mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2026-08-26 06:22:26 +01:00
Newmap - SMC, Openturf, Arrivals Controller, and Mine Turf Improvements (#1958)
* Replace SSingulo with SScalamity; processing cleanup
- SScalamity now handles blobs as well as singularity-types.
- Processing subtypes have been simplified to not require a stop_processing definition.
* this is probably important
* Remove cascade disabling SSgarbage
* Fixed a bug where dust() did not qdel the target mob
* Misc fixes
* Fix decals surviving break-to-plating
* Subsystem flag tweaks
* Apparently subsystems are new'd before config is.
* Fix paper icons
* Speculative fix for insane lag
* Better machinery stat
* Make organs not use SSoverlay
* Misc bugfixes & tweaks
* Nightmode fixes
* Changelog for SMC
* Port /tg/'s improved MC crash handling
* Add some more SS Recover() procs
* supply_controller -> SScargo
* More New() -> Initialize()
* pAI and robot construction overlays
* Fix cargo unit tests
* Merge the DMM Suite's atom/New() into atoms_init
* Lighting pre-baking
* Lighting initialization logging
* Fix some bad SS init orders
* Fix SSlighting logging; rename Processes to MC
* Speculative fix for insane GC lag
* Prebaked openturf/icon_smooth & fix lighting prebake
* SS init status; SSatoms LATEQDEL
* Fix bug with MC init stat panel
* Fix parallax
* Misc
* Ignore SS_NO_DISPLAY during init
* apparently this is important
* REEEEEE
* Image GC fixes; broadcaster radio-new sanity
* RCON Cleanup
* Move pAI recruiter into subsystem
* Move global solars list into sun subsystem
* Make chickens not use a global
* Demote SSdisposals to SS_BACKGROUND; garbage-debug cleanup
* Speed up space init a little
* Fix bad timer flags on floor drying
* Subsystem panic-restart verb for mins
* Explosion speedup
* Minor subsystem & MC logging tweaks
* SSopenturf improvements
* Make pipenet actually initialize (whoops)
* Minor tweaks
* Implement lighting rounding
* comments are hard okay
* Minor lattice tweaks
* Fix some timer issues & better closet init
* Timer sanity
* Request console tweaks + Storage init sanity
* Minor SSmachiner RCON improvements
* Further reduce world-start timer count
* Standardize subsystem logging
* Garbage hard delete profiling from /tg/
* Timer hang detection & recovery
* Log machines that sleep in process() and fuck up SSmachinery
* Fix an issue with external airlocks sleeping in process()
* Failsafe logging
* Minor tweaks
* Revert "Request console tweaks + Storage init sanity"
This reverts commit 98d3579e35.
* Re-implement RC changes
* Fix SQL FT saving
* Fix SSmachinery sleep in disposals
* Minor SS tweaks
* Paper fixes
* Blood drying fixes
* Merge gameticker and SSticker
* Minor global list init cleanup
* Lagcheck biogenerator & bags
* Tweak SScargo init order; RIG Initialize()
* Caching tweaks
* Remove rogue comma
* Initialize fixes
* Lighting destroy cleanup
* Fix emagging airlocks
* Initial SSicon implementation
* Tweaks & Fixes
* Fire + Air alarm queued icon updates
* Overlays + Queued icon cleanup
* Runtime & background fixes
* Kill some meaningless set statements
* Kill some image qdels
* Bump up lighting rounding val
* Fix adv. scanner destroy runtimes
* Remove unneeded icon update limiting
* Move icon smoothing into helpers
* Show a warning if DM 510 compiles without memory leak hack enabled
* Re-organize subsystems & MC defines a little
* Airlock SFX
* Log of Changes
* Make SSicon_update disable itself when not doing anything
* Fix respawn verb runtime when used early in server-init
* Add more information to MC's stat_entry()
* Replace direct refernces to gcDestroyed with QDEL* macros
* plant_controller -> SSplants
* More plant tweaks
* Add more humor to changelog
* Move parallax globals into SSparallax
* Lighting responsiveness tweaks
* Fix parallax init order & better MC init panel stat
* Make mobs GC
* More overlays + Remove intercom spawn()
* SSfast_process; make pinpointers not use spawn-recursion to process
Also made the SM Cascade beach process with SSprocessing instead of a spawn loop.
* Update changelog
* Mob GC tweaks
* Del() cleanup
* Fix insomniac ZAS connection edges
* Minor pAI cleanup
* Convert more things to SSoverlay; fix duplicated overlay in field gens
* SM Bluespace turf tweaks
* Update SSgarbage debug globals list
* Human-type qdel tweaks
* Subsystem suspension; stat_entry improvements
* SQL Statistics cleanup
* Fix runtimes with ambrosia
* More disable() -> suspend(); fix nightmode again
* Human qdel fix; minor tweaks
* Update turbolift to work with StonedMC
* Make lifts use timers instead of a subsystem
* Make SSassets start earlier
* Convert the radio controller into a subsystem
* Fix some missing CHECK_TICKs in asteroid generation
* MC stat tweaks; make shouldnt_see a typecache
* Kill some redundant debug-controller entries
* radio_controller -> SSradio
* Better SSgarbage hard-del logging from /tg/ upstream
* Logging tweaks + GELF
* Misc client caching improvements
* Slime SSoverlay
* Oven icon fixes
* Implant fixes
- Death implants will no longer spam Common on death of user.
- Death implants should handle a deleted user better.
* Holder tweaks + Welding tool Initialize()
* Fix some bad subsystem logging
* Fix suit cooling units spawning without cells
* Starlight tweaks
* Gibber infinite gib fix
* More SSoverlay stuff
* Make crates use CUT_OVERLAY_IN
* Make SSarrivals suspend instead of disable
* Make openturf use split/phased tick checks
* Speculative fix for unwet timer runtimes
* Blood overlay tweaks/fixes
* Update crusher to play nice with SMC + SSoverlay
* Openturf improvements and fixes
* Minor turbolift tweaks
* Lighting performance improvements + ChangeTurf tweaks
* this is probably important
* Fix wall weld noises on changeturf
* More ChangeTurf tweaks
* Explosion tweaks
* Pre-game lobby tweaks
* Openturf tweaks
* Prevent admins from starting the game before init finishes
* Fix Travis
* Kill an unused var
* Fix ChangeTurf runtimes on openturfs
* Fixes
* Browser datum fixes, asset caching
* Update changelog
* Changelog
* Lobby tweaks
* Ticker tweaks; kill ticker var
* Further lobby tweaks
* Cascade tweaks
* air_master -> SSair
* Reduce overhead from radio autosay
* alarm_manager -> SSalarm
* bomb_processor -> SSexplosives
* corp_regs -> SSlaw
* ZAS overlay fixes
* Small wall icon optimization
* Fix effects master
* Assembly tweaks
* Megavend fixes
* Shuttle fixes
* Camera alert performance improvements
* Fix some world.log spam from lighting overlays
* Fix some Initialize() procs
* Openspace responsiveness tweaks
* Make HE pipes animate through openturfs
* Kill a spawn
This commit is contained in:
@@ -467,7 +467,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
src << "<span class='warning'>Spawning as a mouse is currently disabled.</span>"
|
||||
return
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
if(!ROUND_IS_STARTED)
|
||||
src << "<span class='warning'>You can not spawn as a mouse before round start!</span>"
|
||||
return
|
||||
|
||||
@@ -730,6 +730,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
for(var/image/I in client.images)
|
||||
if(I.icon_state == icon)
|
||||
iconRemoved = 1
|
||||
client.images -= I
|
||||
qdel(I)
|
||||
|
||||
if(!iconRemoved)
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
flick(anim, animation)
|
||||
if(do_gibs) gibs(loc, viruses, dna)
|
||||
|
||||
spawn(15)
|
||||
if(animation) qdel(animation)
|
||||
if(src) qdel(src)
|
||||
QDEL_IN(animation, 15)
|
||||
QDEL_IN(src, 15)
|
||||
|
||||
//This is the proc for turning a mob into ash. Mostly a copy of gib code (above).
|
||||
//Originally created for wizard disintegrate. I've removed the virus code since it's irrelevant here.
|
||||
@@ -45,10 +44,9 @@
|
||||
new remains(loc)
|
||||
|
||||
dead_mob_list -= src
|
||||
spawn(15)
|
||||
if(animation) qdel(animation)
|
||||
if(src) qdel(src)
|
||||
|
||||
QDEL_IN(animation, 15)
|
||||
QDEL_IN(src, 15)
|
||||
|
||||
/mob/proc/death(gibbed,deathmessage="seizes up and falls limp...")
|
||||
|
||||
@@ -95,8 +93,8 @@
|
||||
|
||||
updateicon()
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
ticker.mode.check_win()
|
||||
if(SSticker.mode)
|
||||
SSticker.mode.check_win()
|
||||
|
||||
|
||||
return 1
|
||||
|
||||
@@ -20,3 +20,13 @@ var/mob/dview/dview_mob = new
|
||||
dead_mob_list -= src
|
||||
else
|
||||
living_mob_list -= src
|
||||
|
||||
/mob/dview/Destroy(force = FALSE)
|
||||
crash_with("Some fuck [force ? "force-" : ""]qdeleted the dview mob.")
|
||||
if (!force)
|
||||
return QDEL_HINT_LETMELIVE
|
||||
|
||||
world.log << "Dview was force-qdeleted, this should never happen!"
|
||||
|
||||
dview_mob = new
|
||||
return QDEL_HINT_QUEUE
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
/datum/visualnet/camera/proc/process_sort()
|
||||
if(cameras_unsorted)
|
||||
cameras = dd_sortedObjectList(cameras)
|
||||
sortTim(cameras, /proc/cmp_camera, FALSE)
|
||||
cameras_unsorted = 0
|
||||
|
||||
// Removes a camera from a chunk.
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
/mob/living/silicon/ai/proc/create_eyeobj(var/newloc)
|
||||
if(eyeobj) destroy_eyeobj()
|
||||
if(!newloc) newloc = src.loc
|
||||
eyeobj = getFromPool(/mob/eye/aiEye, newloc)
|
||||
eyeobj = new /mob/eye/aiEye(newloc)
|
||||
eyeobj.owner = src
|
||||
eyeobj.name = "[src.name] (AI Eye)" // Give it a name
|
||||
if(client) client.eye = eyeobj
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
/mob/living/silicon/ai/Destroy()
|
||||
destroy_eyeobj()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/atom/proc/move_camera_by_click()
|
||||
if(istype(usr, /mob/living/silicon/ai))
|
||||
|
||||
@@ -18,19 +18,17 @@
|
||||
cameranet.updatePortableCamera(src.camera)
|
||||
updating = 0
|
||||
|
||||
/mob/living/silicon/AI/Move()
|
||||
/mob/living/silicon/ai/Move()
|
||||
var/oldLoc = src.loc
|
||||
. = ..()
|
||||
if(.)
|
||||
if(provides_camera_vision())
|
||||
if(!updating)
|
||||
updating = 1
|
||||
spawn(BORG_CAMERA_BUFFER)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updateVisibility(oldLoc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
updating = 0
|
||||
addtimer(CALLBACK(src, .proc/camera_post_move, oldLoc), BORG_CAMERA_BUFFER, TIMER_UNIQUE)
|
||||
|
||||
/mob/living/silicon/ai/proc/camera_post_move(oldLoc)
|
||||
if(oldLoc != src.loc)
|
||||
cameranet.updateVisibility(oldLoc, 0)
|
||||
cameranet.updateVisibility(loc, 0)
|
||||
#undef BORG_CAMERA_BUFFER
|
||||
|
||||
// CAMERA
|
||||
@@ -46,10 +44,10 @@
|
||||
src.set_light(0)
|
||||
cameranet.removeCamera(src)
|
||||
|
||||
/obj/machinery/camera/New()
|
||||
..()
|
||||
/obj/machinery/camera/Initialize()
|
||||
. = ..()
|
||||
//Camera must be added to global list of all cameras no matter what...
|
||||
if(cameranet.cameras_unsorted || !ticker)
|
||||
if(cameranet.cameras_unsorted)
|
||||
cameranet.cameras += src
|
||||
cameranet.cameras_unsorted = 1
|
||||
else
|
||||
@@ -59,7 +57,7 @@
|
||||
/obj/machinery/camera/Destroy()
|
||||
clear_all_networks()
|
||||
cameranet.cameras -= src
|
||||
..()
|
||||
return ..()
|
||||
|
||||
// Mobs
|
||||
/mob/living/silicon/ai/rejuvenate()
|
||||
|
||||
@@ -71,8 +71,7 @@
|
||||
// The actual updating.
|
||||
|
||||
/datum/chunk/proc/update()
|
||||
|
||||
set background = 1
|
||||
set waitfor = FALSE
|
||||
|
||||
var/list/newVisibleTurfs = new()
|
||||
acquireVisibleTurfs(newVisibleTurfs)
|
||||
@@ -128,7 +127,9 @@
|
||||
src.y = y
|
||||
src.z = z
|
||||
|
||||
for(var/turf/t in range(10, locate(x + 8, y + 8, z)))
|
||||
var/turf/center = locate(x + 8, y + 8, z)
|
||||
|
||||
for(var/turf/t in RANGE_TURFS(10, center))
|
||||
if(t.x >= x && t.y >= y && t.x < x + 16 && t.y < y + 16)
|
||||
turfs[t] = t
|
||||
|
||||
|
||||
@@ -32,14 +32,14 @@
|
||||
updateallghostimages()
|
||||
..()
|
||||
|
||||
mob/eye/Destroy()
|
||||
/mob/eye/Destroy()
|
||||
if (ghostimage)
|
||||
ghost_darkness_images -= ghostimage
|
||||
ghost_sightless_images -= ghostimage
|
||||
qdel(ghostimage)
|
||||
ghostimage = null
|
||||
updateallghostimages()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/eye/Move(n, direct)
|
||||
if(owner == src)
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/mob/living/Destroy()
|
||||
cultnet.updateVisibility(src, 0)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/rejuvenate()
|
||||
var/was_dead = stat == DEAD
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
// TURFS
|
||||
|
||||
/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
if(ticker)
|
||||
for(var/datum/visualnet/VN in visual_nets)
|
||||
VN.updateVisibility(A, opacity_check)
|
||||
for(var/datum/visualnet/VN in visual_nets)
|
||||
VN.updateVisibility(A, opacity_check)
|
||||
|
||||
/turf
|
||||
var/list/image/obfuscations = new()
|
||||
@@ -17,8 +16,8 @@
|
||||
updateVisibility(src)
|
||||
return ..()
|
||||
|
||||
/turf/simulated/New()
|
||||
..()
|
||||
/turf/simulated/Initialize()
|
||||
. = ..()
|
||||
updateVisibility(src)
|
||||
|
||||
|
||||
@@ -46,4 +45,4 @@
|
||||
// Glass door glass = 1
|
||||
// don't check then?
|
||||
if(!glass)
|
||||
updateVisibility(src, 0)
|
||||
updateVisibility(src, 0)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
/datum/visualnet/Destroy()
|
||||
visual_nets -= src
|
||||
..()
|
||||
return ..()
|
||||
|
||||
// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/visualnet/proc/chunkGenerated(x, y, z)
|
||||
@@ -64,7 +64,7 @@
|
||||
|
||||
/datum/visualnet/proc/updateVisibility(atom/A, var/opacity_check = 1)
|
||||
|
||||
if(!ticker || (opacity_check && !A.opacity))
|
||||
if((opacity_check && !A.opacity))
|
||||
return
|
||||
majorChunkChange(A, 2)
|
||||
|
||||
|
||||
+35
-43
@@ -14,25 +14,38 @@ var/list/holder_mob_icon_cache = list()
|
||||
var/name_dead
|
||||
var/isalive
|
||||
|
||||
var/last_loc_general//This stores a general location of the object. Ie, a container or a mob
|
||||
var/last_loc_specific//This stores specific extra information about the location, pocket, hand, worn on head, etc. Only relevant to mobs
|
||||
var/static/list/unsafe_containers
|
||||
|
||||
var/last_loc_general //This stores a general location of the object. Ie, a container or a mob
|
||||
var/last_loc_specific //This stores specific extra information about the location, pocket, hand, worn on head, etc. Only relevant to mobs
|
||||
|
||||
/obj/item/weapon/holder/proc/setup_unsafe_list()
|
||||
unsafe_containers = typecacheof(list(
|
||||
/obj/item/weapon/storage,
|
||||
/obj/item/weapon/reagent_containers,
|
||||
/obj/structure/closet/crate,
|
||||
/obj/machinery/appliance,
|
||||
/obj/machinery/microwave
|
||||
))
|
||||
|
||||
/obj/item/weapon/holder/Initialize()
|
||||
. = ..()
|
||||
if (!unsafe_containers)
|
||||
setup_unsafe_list()
|
||||
|
||||
/obj/item/weapon/holder/New()
|
||||
tag = rand(0,9999)
|
||||
if (!item_state)
|
||||
item_state = icon_state
|
||||
|
||||
flags_inv |= ALWAYSDRAW
|
||||
|
||||
..()
|
||||
processing_objects.Add(src)
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
/obj/item/weapon/holder/Destroy()
|
||||
reagents = null
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
if (contained)
|
||||
release_mob()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/holder/examine(mob/user)
|
||||
if (contained)
|
||||
@@ -66,7 +79,6 @@ var/list/holder_mob_icon_cache = list()
|
||||
|
||||
release_mob()
|
||||
|
||||
|
||||
return
|
||||
if (isalive && contained.stat == DEAD)
|
||||
held_death(1)//If we get here, it means the mob died sometime after we picked it up. We pass in 1 so that we can play its deathmessage
|
||||
@@ -74,22 +86,8 @@ var/list/holder_mob_icon_cache = list()
|
||||
|
||||
//This function checks if the current location is safe to release inside
|
||||
//it returns 1 if the creature will bug out when released
|
||||
/obj/item/weapon/holder/proc/is_unsafe_container(var/obj/place)
|
||||
if (istype(place, /turf))
|
||||
return 0
|
||||
else if (istype(place, /obj/item/weapon/storage))
|
||||
return 1
|
||||
else if (istype(place, /obj/item/weapon/reagent_containers))
|
||||
return 1
|
||||
else if (istype(place, /obj/structure/closet/crate))
|
||||
return 1
|
||||
else if (istype(place, /obj/machinery/appliance))
|
||||
return 1
|
||||
else if (istype(place, /obj/machinery/microwave))
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/obj/item/weapon/holder/proc/is_unsafe_container(atom/place)
|
||||
return is_type_in_typecache(place, unsafe_containers)
|
||||
|
||||
//Releases all mobs inside the holder, then deletes it.
|
||||
//is_unsafe_container should be checked before calling this
|
||||
@@ -103,7 +101,6 @@ var/list/holder_mob_icon_cache = list()
|
||||
M.reset_view()
|
||||
M.Released()
|
||||
|
||||
|
||||
contained = null
|
||||
var/mob/L = get_holding_mob()
|
||||
if (L)
|
||||
@@ -111,7 +108,6 @@ var/list/holder_mob_icon_cache = list()
|
||||
|
||||
qdel(src)
|
||||
|
||||
|
||||
//Similar to above function, but will not deposit things in any container, only directly on a turf.
|
||||
//Can be called safely anywhere. Notably on holders held or worn on a mob
|
||||
/obj/item/weapon/holder/proc/release_to_floor()
|
||||
@@ -139,18 +135,18 @@ var/list/holder_mob_icon_cache = list()
|
||||
//once with it on the floor, and then once in the container
|
||||
//This conditional allows us to ignore that first one. Handling of mobs dropped on the floor is done in process
|
||||
if (istype(loc, /turf))
|
||||
spawn(3)
|
||||
//Repeat this check
|
||||
//If we're still on the turf a few frames later, then we have actually been dropped or thrown
|
||||
//Release the mob accordingly
|
||||
if (istype(loc, /turf))
|
||||
release_mob()
|
||||
|
||||
//Repeat this check
|
||||
//If we're still on the turf a few frames later, then we have actually been dropped or thrown
|
||||
//Release the mob accordingly
|
||||
addtimer(CALLBACK(src, .proc/post_drop), 3)
|
||||
return
|
||||
|
||||
if (istype(loc, /obj/item/weapon/storage)) //The second drop reads the container its placed into as the location
|
||||
update_location()
|
||||
|
||||
/obj/item/weapon/holder/proc/post_drop()
|
||||
if (isturf(loc))
|
||||
release_mob()
|
||||
|
||||
/obj/item/weapon/holder/equipped(var/mob/user, var/slot)
|
||||
..()
|
||||
@@ -163,10 +159,6 @@ var/list/holder_mob_icon_cache = list()
|
||||
|
||||
report_onmob_location(1, slotnumber, contained)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/holder/attack_self(mob/M as mob)
|
||||
|
||||
if (contained && !(contained.stat & DEAD))
|
||||
@@ -174,11 +166,11 @@ var/list/holder_mob_icon_cache = list()
|
||||
var/mob/living/carbon/human/H = M
|
||||
switch(H.a_intent)
|
||||
if(I_HELP)
|
||||
H.visible_message("\blue [H] pets [contained]")
|
||||
H.visible_message("<span class='notice'>[H] pets [contained].</span>")
|
||||
|
||||
if(I_HURT)
|
||||
contained.adjustBruteLoss(3)
|
||||
H.visible_message("\red [H] crushes [contained]")
|
||||
H.visible_message("<span class='alert'>[H] crushes [contained].</span>")
|
||||
else
|
||||
M << "[contained] is dead."
|
||||
|
||||
@@ -209,7 +201,7 @@ var/list/holder_mob_icon_cache = list()
|
||||
//We have to play it as a visible message on the grabber, because the normal death message played on the dying mob won't show if it's being held
|
||||
var/mob/M = get_holding_mob()
|
||||
if (M)
|
||||
M.visible_message("<b>\The [contained.name]</b> dies")
|
||||
M.visible_message("<b>[contained.name]</b> dies.")
|
||||
//update_icon()
|
||||
|
||||
|
||||
@@ -507,7 +499,7 @@ var/list/holder_mob_icon_cache = list()
|
||||
/obj/item/weapon/holder/lizard
|
||||
name = "lizard"
|
||||
desc = "It's a hissy little lizard. Is it related to Unathi?"
|
||||
desc_dead = "It doesn't hiss anymore"
|
||||
desc_dead = "It doesn't hiss anymore."
|
||||
icon_state_dead = "lizard_dead"
|
||||
icon_state = "lizard"
|
||||
|
||||
@@ -553,7 +545,7 @@ var/list/holder_mob_icon_cache = list()
|
||||
name = "walking mushroom"
|
||||
name_dead = "mushroom"
|
||||
desc = "It's a massive mushroom... with legs?"
|
||||
desc_dead = "Shame, he was a really fun-guy."
|
||||
desc_dead = "Shame, he was a really fun-guy." // HA
|
||||
icon_state = "mushroom"
|
||||
icon_state_dead = "mushroom_dead"
|
||||
slot_flags = SLOT_HEAD
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
access_scanner.req_access = req_access.Copy()
|
||||
access_scanner.req_one_access = req_one_access.Copy()
|
||||
|
||||
/mob/living/bot/Destroy()
|
||||
QDEL_NULL(botcard)
|
||||
QDEL_NULL(access_scanner)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/Life()
|
||||
..()
|
||||
if(health <= 0)
|
||||
|
||||
@@ -54,8 +54,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
|
||||
janitorial_supplies |= src
|
||||
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
if(SSradio)
|
||||
SSradio.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
|
||||
/mob/living/bot/cleanbot/Destroy()
|
||||
. = ..()
|
||||
@@ -63,7 +63,8 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
patrol_path = null
|
||||
target = null
|
||||
ignorelist = null
|
||||
janitorial_supplies -= src
|
||||
QDEL_NULL(listener)
|
||||
global.janitorial_supplies -= src
|
||||
|
||||
/mob/living/bot/cleanbot/proc/handle_target()
|
||||
if(target.clean_marked && target.clean_marked != src)
|
||||
@@ -158,7 +159,7 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
if(!found_spot && !target) // No targets in range
|
||||
if(!patrol_path || !patrol_path.len)
|
||||
if(!signal_sent || signal_sent > world.time + 200) // Waited enough or didn't send yet
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(beacon_freq)
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(beacon_freq)
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
@@ -354,6 +355,10 @@ var/list/cleanbot_types // Going to use this to generate a list of types once th
|
||||
cleanbot.closest_dist = dist
|
||||
cleanbot.next_dest = signal.data["next_patrol"]
|
||||
|
||||
/obj/cleanbot_listener/Destroy()
|
||||
cleanbot = null
|
||||
return ..()
|
||||
|
||||
/* Assembly */
|
||||
|
||||
/obj/item/weapon/bucket_sensor
|
||||
|
||||
@@ -27,12 +27,15 @@
|
||||
var/atom/target
|
||||
var/frustration = 0
|
||||
|
||||
/mob/living/bot/farmbot/New()
|
||||
..()
|
||||
spawn(5)
|
||||
tank = locate() in contents
|
||||
if(!tank)
|
||||
tank = new /obj/structure/reagent_dispensers/watertank(src)
|
||||
/mob/living/bot/farmbot/Initialize()
|
||||
. = ..()
|
||||
tank = locate() in contents
|
||||
if(!tank)
|
||||
tank = new /obj/structure/reagent_dispensers/watertank(src)
|
||||
|
||||
/mob/living/bot/farmbot/Destroy()
|
||||
QDEL_NULL(tank)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/farmbot/attack_hand(var/mob/user as mob)
|
||||
. = ..()
|
||||
|
||||
@@ -229,7 +229,7 @@
|
||||
if(building == 1)
|
||||
I = new /obj/item/stack/tile/floor(src)
|
||||
else
|
||||
I = getFromPool(/obj/item/stack/rods, src)
|
||||
I = new /obj/item/stack/rods(src)
|
||||
A.attackby(I, src)
|
||||
target = null
|
||||
repairing = 0
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
var/treatment_emag = "toxin"
|
||||
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
|
||||
|
||||
|
||||
/mob/living/bot/medbot/Destroy()
|
||||
QDEL_NULL(reagent_glass)
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/medbot/Life()
|
||||
..()
|
||||
|
||||
@@ -111,9 +116,9 @@
|
||||
update_icons()
|
||||
|
||||
/mob/living/bot/medbot/update_icons()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(skin)
|
||||
overlays += image('icons/obj/aibots.dmi', "medskin_[skin]")
|
||||
add_overlay("medskin_[skin]")
|
||||
if(currently_healing)
|
||||
icon_state = "medibots"
|
||||
else
|
||||
@@ -337,11 +342,10 @@
|
||||
var/skin = null //Same as medbot, set to tox or ointment for the respective kits.
|
||||
w_class = 3.0
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/New()
|
||||
..()
|
||||
spawn(5) // Terrible. TODO: fix
|
||||
if(skin)
|
||||
overlays += image('icons/obj/aibots.dmi', "kit_skin_[src.skin]")
|
||||
/obj/item/weapon/firstaid_arm_assembly/Initialize()
|
||||
. = ..()
|
||||
if(skin)
|
||||
add_overlay("kit_skin_[skin]")
|
||||
|
||||
/obj/item/weapon/firstaid_arm_assembly/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
..()
|
||||
@@ -361,7 +365,7 @@
|
||||
build_step++
|
||||
user << "<span class='notice'>You add the health sensor to [src].</span>"
|
||||
name = "First aid/robot arm/health analyzer assembly"
|
||||
overlays += image('icons/obj/aibots.dmi', "na_scanner")
|
||||
add_overlay("na_scanner")
|
||||
return 1
|
||||
|
||||
if(1)
|
||||
|
||||
@@ -48,15 +48,19 @@
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
auto_patrol = 1
|
||||
|
||||
/mob/living/bot/secbot/New()
|
||||
..()
|
||||
/mob/living/bot/secbot/Initialize()
|
||||
. = ..()
|
||||
listener = new /obj/secbot_listener(src)
|
||||
listener.secbot = src
|
||||
|
||||
spawn(5) // Since beepsky is made on the start... this delay is necessary
|
||||
if(radio_controller)
|
||||
radio_controller.add_object(listener, control_freq, filter = RADIO_SECBOT)
|
||||
radio_controller.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
if(SSradio)
|
||||
SSradio.add_object(listener, control_freq, filter = RADIO_SECBOT)
|
||||
SSradio.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
|
||||
|
||||
/mob/living/bot/secbot/Destroy()
|
||||
QDEL_NULL(listener)
|
||||
target = null
|
||||
return ..()
|
||||
|
||||
/mob/living/bot/secbot/turn_off()
|
||||
..()
|
||||
@@ -315,7 +319,7 @@
|
||||
|
||||
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/secbot_assembly(Tsec)
|
||||
Sa.build_step = 1
|
||||
Sa.overlays += image('icons/obj/aibots.dmi', "hs_hole")
|
||||
Sa.add_overlay("hs_hole")
|
||||
Sa.created_name = name
|
||||
new /obj/item/device/assembly/prox_sensor(Tsec)
|
||||
new /obj/item/weapon/melee/baton(Tsec)
|
||||
@@ -405,11 +409,15 @@
|
||||
/obj/secbot_listener
|
||||
var/mob/living/bot/secbot/secbot = null
|
||||
|
||||
/obj/secbot_listener/Destroy()
|
||||
secbot = null
|
||||
return ..()
|
||||
|
||||
/obj/secbot_listener/proc/post_signal(var/freq, var/key, var/value) // send a radio signal with a single data key/value pair
|
||||
post_signal_multiple(freq, list("[key]" = value))
|
||||
|
||||
/obj/secbot_listener/proc/post_signal_multiple(var/freq, var/list/keyval) // send a radio signal with multiple data key/values
|
||||
var/datum/radio_frequency/frequency = radio_controller.return_frequency(freq)
|
||||
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
|
||||
if(!frequency)
|
||||
return
|
||||
|
||||
@@ -520,7 +528,7 @@
|
||||
var/obj/item/weapon/weldingtool/WT = O
|
||||
if(WT.remove_fuel(0, user))
|
||||
build_step = 1
|
||||
overlays += image('icons/obj/aibots.dmi', "hs_hole")
|
||||
add_overlay("hs_hole")
|
||||
user << "You weld a hole in \the [src]."
|
||||
return 1
|
||||
|
||||
@@ -528,7 +536,7 @@
|
||||
user.drop_item()
|
||||
build_step = 2
|
||||
user << "You add \the [O] to [src]."
|
||||
overlays += image('icons/obj/aibots.dmi', "hs_eye")
|
||||
add_overlay("hs_eye")
|
||||
name = "helmet/signaler/prox sensor assembly"
|
||||
qdel(O)
|
||||
return 1
|
||||
@@ -538,7 +546,7 @@
|
||||
build_step = 3
|
||||
user << "You add \the [O] to [src]."
|
||||
name = "helmet/signaler/prox sensor/robot arm assembly"
|
||||
overlays += image('icons/obj/aibots.dmi', "hs_arm")
|
||||
add_overlay("hs_arm")
|
||||
qdel(O)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// Alien larva are quite simple.
|
||||
/mob/living/carbon/alien/Life()
|
||||
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (transforming) return
|
||||
if(!loc) return
|
||||
|
||||
@@ -134,7 +134,7 @@
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/device/mmi/radio_enabled
|
||||
name = "radio-enabled man-machine interface"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
..()
|
||||
return ..()
|
||||
|
||||
say_understands(var/other)//Goddamn is this hackish, but this say code is so odd
|
||||
if (istype(other, /mob/living/silicon/ai))
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/brain/proc/transfer_identity(var/mob/living/carbon/H)
|
||||
name = "\the [H]'s [initial(src.name)]"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
//Start of a breath chain, calls breathe()
|
||||
/mob/living/carbon/handle_breathing()
|
||||
if(air_master.current_cycle%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath
|
||||
if(SSair.times_fired%4==2 || failed_last_breath || (health < config.health_threshold_crit)) //First, resolve location and get a breath
|
||||
breathe()
|
||||
|
||||
/mob/living/carbon/proc/breathe()
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
|
||||
/mob/living/carbon/Destroy()
|
||||
QDEL_NULL(touching)
|
||||
// We don't qdel(bloodstr) because it's the same as qdel(reagents)
|
||||
bloodstr = null
|
||||
QDEL_NULL(dna)
|
||||
for(var/guts in internal_organs)
|
||||
qdel(guts)
|
||||
return ..()
|
||||
@@ -66,13 +67,13 @@
|
||||
if(prob(src.getBruteLoss() - 50))
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
A.loc = loc
|
||||
stomach_contents.Remove(A)
|
||||
LAZYREMOVE(stomach_contents, A)
|
||||
src.gib()
|
||||
|
||||
/mob/living/carbon/gib()
|
||||
for(var/mob/M in src)
|
||||
if(M in src.stomach_contents)
|
||||
src.stomach_contents.Remove(M)
|
||||
LAZYREMOVE(src.stomach_contents, M)
|
||||
M.loc = src.loc
|
||||
for(var/mob/N in viewers(src, null))
|
||||
if(N.client)
|
||||
|
||||
@@ -513,7 +513,7 @@ var/list/diona_banned_languages = list(
|
||||
/datum/dionastats/Destroy()
|
||||
light_organ = null//Nulling out these references to prevent GC errors
|
||||
nutrient_organ = null
|
||||
..()
|
||||
return ..()
|
||||
|
||||
|
||||
#undef FLASHLIGHT_STRENGTH
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
if(!gibbed && species.death_sound)
|
||||
playsound(loc, species.death_sound, 80, 1, 1)
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
if(SSticker.mode)
|
||||
sql_report_death(src)
|
||||
ticker.mode.check_win()
|
||||
SSticker.mode.check_win()
|
||||
|
||||
if(wearing_rig)
|
||||
wearing_rig.notify_ai("<span class='danger'>Warning: user death event. Mobility control passed to integrated intelligence system.</span>")
|
||||
|
||||
@@ -88,6 +88,8 @@
|
||||
bad_internal_organs = null
|
||||
bad_external_organs = null
|
||||
|
||||
QDEL_NULL(vessel)
|
||||
|
||||
QDEL_NULL(DS)
|
||||
// qdel and null out our equipment.
|
||||
QDEL_NULL(shoes)
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
return
|
||||
|
||||
for(var/obj/item/organ/external/E in bad_external_organs)
|
||||
if(!E)
|
||||
if(QDELETED(E))
|
||||
continue
|
||||
if(!E.need_process())
|
||||
bad_external_organs -= E
|
||||
|
||||
@@ -200,12 +200,12 @@
|
||||
set desc = "Empties the contents of your stomach"
|
||||
set category = "Abilities"
|
||||
|
||||
if(stomach_contents.len)
|
||||
if(LAZYLEN(stomach_contents))
|
||||
for(var/mob/M in src)
|
||||
if(M in stomach_contents)
|
||||
stomach_contents.Remove(M)
|
||||
M.loc = loc
|
||||
src.visible_message("\red <B>[src] hurls out the contents of their stomach!</B>")
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
M.forceMove(loc)
|
||||
src.visible_message(span("danger", "\The [src] hurls out the contents of their stomach!"))
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/psychic_whisper(mob/M as mob in oview())
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
var/global/list/overlays_cache = null
|
||||
|
||||
/mob/living/carbon/human/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (transforming)
|
||||
@@ -1265,23 +1264,6 @@
|
||||
if(T.dynamic_lighting && T.get_lumcount() < 0.01) // give a little bit of tolerance for near-dark areas.
|
||||
playsound_local(src,pick(scarySounds),50, 1, -1)
|
||||
|
||||
/mob/living/carbon/human/handle_stomach()
|
||||
spawn(0)
|
||||
for(var/mob/living/M in stomach_contents)
|
||||
if(M.loc != src)
|
||||
stomach_contents.Remove(M)
|
||||
continue
|
||||
if(iscarbon(M)|| isanimal(M))
|
||||
if(M.stat == 2)
|
||||
M.death(1)
|
||||
stomach_contents.Remove(M)
|
||||
qdel(M)
|
||||
continue
|
||||
if(air_master.current_cycle%3==1)
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
|
||||
/mob/living/carbon/human/proc/handle_changeling()
|
||||
if(mind && mind.changeling)
|
||||
mind.changeling.regenerate()
|
||||
|
||||
@@ -146,6 +146,9 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
//UPDATES OVERLAYS FROM OVERLAYS_LYING/OVERLAYS_STANDING
|
||||
//Fixed by Nanako
|
||||
/mob/living/carbon/human/update_icons()
|
||||
if (QDELING(src))
|
||||
return // No point.
|
||||
|
||||
//so we don't update overlays for lying/standing unless our stance changes again
|
||||
update_hud() //TODO: remove the need for this
|
||||
overlays.Cut()
|
||||
@@ -234,6 +237,9 @@ var/global/list/damage_icon_parts = list()
|
||||
//Passing in a value of 2 for update_icons will ignore any cached icon, and force a new one to be generated
|
||||
|
||||
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
var/husk_color_mod = rgb(96,88,80)
|
||||
var/hulk_color_mod = rgb(48,224,40)
|
||||
|
||||
@@ -355,6 +361,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
//HAIR OVERLAY
|
||||
/mob/living/carbon/human/proc/update_hair(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
//Reset our hair
|
||||
overlays_standing[HAIR_LAYER] = null
|
||||
|
||||
@@ -404,6 +413,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_mutations(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
var/fat
|
||||
if(FAT in mutations)
|
||||
fat = "fat"
|
||||
@@ -449,6 +461,9 @@ var/global/list/damage_icon_parts = list()
|
||||
/* --------------------------------------- */
|
||||
//For legacy support.
|
||||
/mob/living/carbon/human/regenerate_icons()
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
..()
|
||||
if(transforming) return
|
||||
|
||||
@@ -483,6 +498,9 @@ var/global/list/damage_icon_parts = list()
|
||||
//vvvvvv UPDATE_INV PROCS vvvvvv
|
||||
|
||||
/mob/living/carbon/human/update_inv_w_uniform(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[UNIFORM_LAYER] = null
|
||||
if(check_draw_underclothing())
|
||||
w_uniform.screen_loc = ui_iclothing
|
||||
@@ -543,6 +561,9 @@ var/global/list/damage_icon_parts = list()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_id(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[ID_LAYER] = null
|
||||
if(wear_id)
|
||||
|
||||
@@ -566,6 +587,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_gloves(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[GLOVES_LAYER] = null
|
||||
if(check_draw_gloves())
|
||||
|
||||
@@ -607,6 +631,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_glasses(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[GLASSES_LAYER] = null
|
||||
if(check_draw_glasses())
|
||||
if(glasses.contained_sprite)
|
||||
@@ -632,6 +659,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_ears(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[L_EAR_LAYER] = null
|
||||
overlays_standing[R_EAR_LAYER] = null
|
||||
|
||||
@@ -688,6 +718,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_shoes(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[SHOES_LAYER] = null
|
||||
if(check_draw_shoes())
|
||||
var/image/standing
|
||||
@@ -725,6 +758,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_s_store(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
if(s_store)
|
||||
//s_store.auto_adapt_species(src)
|
||||
var/t_state = s_store.item_state
|
||||
@@ -737,6 +773,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_head(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[HEAD_LAYER] = null
|
||||
if(head)
|
||||
head.screen_loc = ui_head //TODO
|
||||
@@ -789,6 +828,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_belt(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[BELT_LAYER] = null
|
||||
if(belt)
|
||||
|
||||
@@ -852,6 +894,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_suit(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
|
||||
if( wear_suit && istype(wear_suit, /obj/item/) )
|
||||
|
||||
@@ -904,12 +949,18 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_pockets(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
if(l_store) l_store.screen_loc = ui_storage1 //TODO
|
||||
if(r_store) r_store.screen_loc = ui_storage2 //TODO
|
||||
if(update_icons) update_icons()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_mask(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[FACEMASK_LAYER] = null
|
||||
if(check_draw_mask())
|
||||
wear_mask.screen_loc = ui_mask //TODO
|
||||
@@ -943,6 +994,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_back(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
|
||||
overlays_standing[BACK_LAYER] = null
|
||||
if(back)
|
||||
@@ -1007,6 +1061,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_handcuffed(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
@@ -1026,6 +1083,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/update_inv_legcuffed(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
if(legcuffed)
|
||||
|
||||
var/image/standing
|
||||
@@ -1048,6 +1108,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_r_hand(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[R_HAND_LAYER] = null
|
||||
if(r_hand)
|
||||
r_hand.screen_loc = ui_rhand //TODO
|
||||
@@ -1090,6 +1153,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_l_hand(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[L_HAND_LAYER] = null
|
||||
if(l_hand)
|
||||
l_hand.screen_loc = ui_lhand //TODO
|
||||
@@ -1131,6 +1197,9 @@ var/global/list/damage_icon_parts = list()
|
||||
if(update_icons) update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/update_tail_showing(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[TAIL_LAYER] = null
|
||||
|
||||
if(species.tail && !(wear_suit && wear_suit.flags_inv & HIDETAIL))
|
||||
@@ -1142,6 +1211,9 @@ var/global/list/damage_icon_parts = list()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/human/proc/get_tail_icon()
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
var/icon_key = "[species.race_key][r_skin][g_skin][b_skin][r_hair][g_hair][b_hair]"
|
||||
var/icon/tail_icon = tail_icon_cache[icon_key]
|
||||
if(!tail_icon)
|
||||
@@ -1182,12 +1254,12 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
tail_overlay = set_tail_state(t_state)
|
||||
if(tail_overlay)
|
||||
spawn(20)
|
||||
//check that the animation hasn't changed in the meantime
|
||||
if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == t_state)
|
||||
animate_tail_stop()
|
||||
|
||||
addtimer(CALLBACK(src, .proc/end_animate_tail_once, tail_overlay), 20)
|
||||
|
||||
/mob/living/carbon/human/proc/end_animate_tail_once(image/tail_overlay)
|
||||
//check that the animation hasn't changed in the meantime
|
||||
if(overlays_standing[TAIL_LAYER] == tail_overlay && tail_overlay.icon_state == "[species.tail]_once")
|
||||
animate_tail_stop()
|
||||
|
||||
/mob/living/carbon/human/proc/animate_tail_start()
|
||||
set_tail_state("[species.tail]_slow[rand(0,9)]")
|
||||
@@ -1214,6 +1286,9 @@ var/global/list/damage_icon_parts = list()
|
||||
//Adds a collar overlay above the helmet layer if the suit has one
|
||||
// Suit needs an identically named sprite in icons/mob/collar.dmi
|
||||
/mob/living/carbon/human/proc/update_collar(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
var/icon/C = new('icons/mob/collar.dmi')
|
||||
var/image/standing = null
|
||||
|
||||
@@ -1227,6 +1302,9 @@ var/global/list/damage_icon_parts = list()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_fire(var/update_icons=1)
|
||||
if (QDELING(src))
|
||||
return
|
||||
|
||||
overlays_standing[FIRE_LAYER] = null
|
||||
if(on_fire)
|
||||
overlays_standing[FIRE_LAYER] = image("icon"='icons/mob/OnFire.dmi', "icon_state"="Standing", "layer"=FIRE_LAYER)
|
||||
|
||||
@@ -142,19 +142,24 @@
|
||||
watching -= eavesdropping
|
||||
|
||||
//now mobs
|
||||
var/speech_bubble_test = say_test(message)
|
||||
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
|
||||
spawn(30) qdel(speech_bubble)
|
||||
|
||||
var/list/listening_clients = list() // The clients we're going to show the speech bubble to.
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M << speech_bubble
|
||||
M.hear_say(message, verb, speaking, alt_name, italics, src)
|
||||
if (M.client)
|
||||
listening_clients += M.client
|
||||
|
||||
if (eavesdropping.len)
|
||||
var/new_message = stars(message) //hopefully passing the message twice through stars() won't hurt... I guess if you already don't understand the language, when they speak it too quietly to hear normally you would be able to catch even less.
|
||||
for(var/mob/M in eavesdropping)
|
||||
M << speech_bubble
|
||||
M.hear_say(new_message, verb, speaking, alt_name, italics, src)
|
||||
if (M.client)
|
||||
listening_clients += M.client
|
||||
|
||||
var/speech_bubble_test = say_test(message)
|
||||
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, speech_bubble, listening_clients, 30)
|
||||
|
||||
if (watching.len)
|
||||
var/rendered = "<span class='game say'><span class='name'>[src.name]</span> [not_heard].</span>"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/living/carbon/slime/Life()
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (src.transforming)
|
||||
return
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
icon_state = "[colour] baby slime dead"
|
||||
else
|
||||
icon_state = "[colour] [is_adult ? "adult" : "baby"] slime[Victim ? "" : " eat"]"
|
||||
overlays.len = 0
|
||||
cut_overlays()
|
||||
if (mood)
|
||||
overlays += image('icons/mob/slimes.dmi', icon_state = "aslime-[mood]")
|
||||
..()
|
||||
add_overlay("aslime-[mood]")
|
||||
..()
|
||||
|
||||
@@ -18,11 +18,6 @@
|
||||
#define PPM 9//Protein per meat, used for calculating the quantity of protein in an animal
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/var/swallowed_mob = 0
|
||||
//This is set true if there are any mobs in this mob's contents. they will be slowly digested.
|
||||
//just used as a boolean to minimise extra processing
|
||||
@@ -85,26 +80,16 @@
|
||||
else
|
||||
devour_gradual(victim,mouth_size)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/swallow(var/mob/living/victim, var/mouth_size)
|
||||
//This function will move the victim inside the eater's contents.. There they will be digested over time
|
||||
|
||||
var/swallow_time = max(3 + (victim.mob_size * victim.mob_size) - mouth_size, 3)
|
||||
src.visible_message("[src] starts swallowing [victim]","You start swallowing [victim], this will take approximately [swallow_time] seconds")
|
||||
src.visible_message("[src] starts swallowing \the [victim]!","You start swallowing \the [victim], this will take approximately [swallow_time] seconds.")
|
||||
var/turf/ourloc = src.loc
|
||||
var/turf/victimloc = victim.loc
|
||||
if (do_mob(src, victim, swallow_time*10))
|
||||
victim.loc = src
|
||||
stomach_contents.Add(victim)
|
||||
victim.forceMove(src)
|
||||
LAZYADD(stomach_contents, victim)
|
||||
else if (victimloc != victim.loc)
|
||||
src << "[victim] moved away, you need to keep it still. Try grabbing, stunning or killing it first."
|
||||
else if (ourloc != src.loc)
|
||||
@@ -112,9 +97,6 @@
|
||||
else
|
||||
src << "Swallowing failed!"//reason unknown, maybe the eater got stunned?
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/devour_gradual(var/mob/living/victim, var/mouth_size)
|
||||
//This function will start consuming the victim by taking bites out of them.
|
||||
//Victim or attacker moving will interrupt it
|
||||
@@ -180,48 +162,43 @@
|
||||
//This can also happen if you start devouring something else
|
||||
break
|
||||
|
||||
|
||||
|
||||
//this function gradually digests things inside the mob's contents.
|
||||
//It is called from life.dm. Any creatures that don't want to digest their contents simply don't call it
|
||||
/mob/living/proc/handle_stomach()
|
||||
for(var/mob/living/M in stomach_contents)
|
||||
if(M.loc != src)//if something somehow escaped the stomach, then we remove it
|
||||
stomach_contents.Remove(M)
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
continue
|
||||
|
||||
if(!M.composition_reagent_quantity)
|
||||
M.calculate_composition()
|
||||
|
||||
var/digestion_power = (((mob_size * mob_size)/10) / (M.mob_size * M.mob_size))
|
||||
var/digestion_time = digestion_power * 60//Number of seconds it will take to digest in total
|
||||
var/DPPP = 1 / (digestion_time / 2.1)//Digestion percentage per proc
|
||||
var/digestion_time = digestion_power * 60 //Number of seconds it will take to digest in total
|
||||
var/DPPP = 1 / (digestion_time / 2.1) //Digestion percentage per proc
|
||||
M.adjustCloneLoss(M.maxHealth*DPPP)
|
||||
//Digestion power is how much of the creature we can digest per minute. Calculated as a tenth of our mob size squared, divided by the victim's mob size squared
|
||||
//If the resulting value is >1, digestion will take under a minute.
|
||||
src.ingested.add_reagent(M.composition_reagent, M.composition_reagent_quantity*DPPP)
|
||||
if ((M.stat != DEAD) && (M.cloneloss > (M.maxHealth*0.5)))//If we've consumed half of the victim, then it dies
|
||||
if ((M.stat != DEAD) && (M.cloneloss > (M.maxHealth*0.5))) //If we've consumed half of the victim, then it dies
|
||||
M.death()
|
||||
M.stat = DEAD //Just in case the death function doesn't set it
|
||||
src << "Your stomach feels a little more relaxed as [M] finally stops fighting"
|
||||
src << "Your stomach feels a little more relaxed as \the [M] finally stops fighting."
|
||||
|
||||
if (M.cloneloss >= M.maxHealth)//If we've consumed all of it, then digestion is finished.
|
||||
stomach_contents.Remove(M)
|
||||
src << "Your stomach feels a little more empty as you finish digesting [M]"
|
||||
if (M.cloneloss >= M.maxHealth) //If we've consumed all of it, then digestion is finished.
|
||||
LAZYREMOVE(stomach_contents, M)
|
||||
src << "Your stomach feels a little more empty as you finish digesting \the [M]."
|
||||
qdel(M)
|
||||
|
||||
|
||||
|
||||
//Helpers
|
||||
/proc/bitemessage(var/mob/living/victim)
|
||||
return pick("You take a bite out of [victim]",
|
||||
"You rip a chunk off of [victim]",
|
||||
"You consume a piece of [victim]",
|
||||
"You feast upon your prey",
|
||||
"You chow down on [victim]",
|
||||
"You gobble [victim]'s flesh")
|
||||
|
||||
|
||||
return pick(
|
||||
"You take a bite out of \the [victim].",
|
||||
"You rip a chunk off of \the [victim].",
|
||||
"You consume a piece of \the [victim].",
|
||||
"You feast upon your prey.",
|
||||
"You chow down on \the [victim].",
|
||||
"You gobble \the [victim]'s flesh.")
|
||||
|
||||
/proc/handle_devour_mess(var/mob/user, var/mob/living/victim, var/datum/reagents/vessel, var/finish = 0)
|
||||
//The maximum number of blood placements is equal to the mob size of the victim
|
||||
@@ -286,10 +263,6 @@
|
||||
B.fluorescent = 0
|
||||
B.invisibility = 0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/proc/turf_hasblood(var/turf/test)
|
||||
for (var/obj/effect/decal/cleanable/blood/b in test)
|
||||
return 1
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
/mob/living/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (QDELETED(src)) // If they're being deleted, why bother?
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
if (transforming)
|
||||
@@ -127,7 +129,7 @@
|
||||
|
||||
//this handles hud updates. Calls update_vision() and handle_hud_icons()
|
||||
/mob/living/proc/handle_regular_hud_updates()
|
||||
if(!client) return 0
|
||||
if(!client || QDELETED(src)) return 0
|
||||
|
||||
handle_hud_icons()
|
||||
handle_vision()
|
||||
|
||||
@@ -712,8 +712,8 @@ default behaviour is:
|
||||
|
||||
//check for nuke disks
|
||||
if(client && stat != DEAD) //if they are clientless and dead don't bother, the parent will treat them as any other container
|
||||
if(ticker && istype(ticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear
|
||||
var/datum/game_mode/nuclear/G = ticker.mode
|
||||
if(istype(SSticker.mode, /datum/game_mode/nuclear)) //only really care if the game mode is nuclear
|
||||
var/datum/game_mode/nuclear/G = SSticker.mode
|
||||
if(G.check_mob(src))
|
||||
if(x <= TRANSITIONEDGE)
|
||||
inertia_dir = 4
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
var/possession_candidate // Can be possessed by ghosts if unplayed.
|
||||
|
||||
var/list/stomach_contents = list()//This is moved here from carbon defines
|
||||
var/list/stomach_contents //This is moved here from carbon defines
|
||||
var/composition_reagent
|
||||
var/composition_reagent_quantity
|
||||
var/mouth_size = 2//how large of a creature it can swallow at once, and how big of a bite it can take out of larger things
|
||||
@@ -69,4 +69,6 @@
|
||||
var/move_delay_mod = 0//Added to move delay, used for calculating movement speeds. Provides a centralised value for modifiers to alter
|
||||
|
||||
var/total_radiation // DON'T MODIFY THIS DIRECTLY. USE apply_radiation()!
|
||||
var/cloaked = 0//Set to 1 by cloaking devices, optimises update_icons
|
||||
var/cloaked = 0//Set to 1 by cloaking devices, optimises update_icons
|
||||
|
||||
var/tesla_ignore = 0 // If true, mob is not affected by tesla bolts.
|
||||
|
||||
@@ -103,7 +103,7 @@ var/controlling
|
||||
if(host) src.loc = host.loc
|
||||
src.stat = 2
|
||||
..()
|
||||
del src
|
||||
qdel(src)
|
||||
|
||||
// When a meme speaks, it speaks through its host
|
||||
/mob/living/parasite/meme/say(message as text)
|
||||
|
||||
@@ -243,13 +243,15 @@ proc/get_radio_key_from_channel(var/channel)
|
||||
get_mobs_and_objs_in_view_fast(T, message_range, listening, listening_obj)
|
||||
|
||||
|
||||
var/list/hear_clients = list()
|
||||
for(var/mob/M in listening)
|
||||
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
|
||||
if (M.client)
|
||||
hear_clients += M.client
|
||||
|
||||
var/speech_bubble_test = say_test(message)
|
||||
var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
|
||||
spawn(30) qdel(speech_bubble)
|
||||
|
||||
for(var/mob/M in listening)
|
||||
M << speech_bubble
|
||||
M.hear_say(message, verb, speaking, alt_name, italics, src, speech_sound, sound_vol)
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, speech_bubble, hear_clients, 30)
|
||||
|
||||
for(var/obj/O in listening_obj)
|
||||
spawn(0)
|
||||
|
||||
@@ -48,7 +48,7 @@ var/list/ai_verbs_default = list(
|
||||
anchored = 1 // -- TLE
|
||||
density = 1
|
||||
status_flags = CANSTUN|CANPARALYSE|CANPUSH
|
||||
shouldnt_see = list(/obj/effect/rune)
|
||||
//shouldnt_see - set in New()
|
||||
var/list/network = list("Exodus")
|
||||
var/obj/machinery/camera/camera = null
|
||||
var/list/connected_robots = list()
|
||||
@@ -99,6 +99,7 @@ var/list/ai_verbs_default = list(
|
||||
src.verbs -= silicon_subsystems
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
shouldnt_see = typecacheof(/obj/effect/rune)
|
||||
announcement = new()
|
||||
announcement.title = "A.I. Announcement"
|
||||
announcement.announcement_type = "A.I. Announcement"
|
||||
@@ -123,7 +124,7 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
holo_icon = getHologramIcon(icon('icons/mob/AI.dmi',"holo1"))
|
||||
|
||||
proc_holder_list = new()
|
||||
//proc_holder_list = new() // This ain't even used, why are we initializing it?
|
||||
|
||||
if(L)
|
||||
if (istype(L, /datum/ai_laws))
|
||||
@@ -168,8 +169,7 @@ var/list/ai_verbs_default = list(
|
||||
|
||||
on_mob_init()
|
||||
|
||||
spawn(5)
|
||||
new /obj/machinery/ai_powersupply(src)
|
||||
addtimer(CALLBACK(src, .proc/create_powersupply), 5)
|
||||
|
||||
hud_list[HEALTH_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
hud_list[STATUS_HUD] = image('icons/mob/hud.dmi', src, "hudblank")
|
||||
@@ -184,6 +184,9 @@ var/list/ai_verbs_default = list(
|
||||
ai_list += src
|
||||
..()
|
||||
|
||||
/mob/living/silicon/ai/proc/init_powersupply()
|
||||
new /obj/machinery/ai_powersupply(src)
|
||||
|
||||
/mob/living/silicon/ai/proc/on_mob_init()
|
||||
src << "<B>You are playing the station's AI. The AI cannot move, but can interact with many objects while viewing them (through cameras).</B>"
|
||||
src << "<B>To look at other parts of the station, click on yourself to get a camera menu.</B>"
|
||||
@@ -541,7 +544,7 @@ var/list/ai_verbs_default = list(
|
||||
for(var/i in tempnetwork)
|
||||
cameralist[i] = i
|
||||
|
||||
cameralist = sortAssoc(cameralist)
|
||||
sortTim(cameralist, /proc/cmp_text_asc)
|
||||
return cameralist
|
||||
|
||||
/mob/living/silicon/ai/proc/ai_network_change(var/network in get_camera_network_list())
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
var/global/list/empty_playable_ai_cores = list()
|
||||
|
||||
/hook/roundstart/proc/spawn_empty_ai()
|
||||
if("AI" in ticker.mode.disabled_jobs)
|
||||
if("AI" in SSticker.mode.disabled_jobs)
|
||||
return 1 // Don't make empty AI's if you can't have them (also applies to Malf)
|
||||
for(var/obj/effect/landmark/start/S in landmarks_list)
|
||||
if(S.name != "AI")
|
||||
@@ -35,7 +35,7 @@ var/global/list/empty_playable_ai_cores = list()
|
||||
set category = "OOC"
|
||||
set desc = "Wipe your core. This is functionally equivalent to cryo or robotic storage, freeing up your job slot."
|
||||
|
||||
if(ticker && ticker.mode && ticker.mode.name == "AI malfunction")
|
||||
if(SSticker.mode && SSticker.mode.name == "AI malfunction")
|
||||
usr << "<span class='danger'>You cannot use this verb in malfunction. If you need to leave, please adminhelp.</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -11,5 +11,5 @@
|
||||
src.anchored = 1
|
||||
src.canmove = 0
|
||||
|
||||
/mob/living/silicon/decoy/initialize()
|
||||
return
|
||||
/mob/living/silicon/decoy/Initialize()
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
@@ -1,380 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
|
||||
|
||||
// Recruiting observers to play as pAIs
|
||||
|
||||
var/datum/paiController/paiController // Global handler for pAI candidates
|
||||
|
||||
/datum/paiCandidate
|
||||
var/name
|
||||
var/key
|
||||
var/description
|
||||
var/role
|
||||
var/comments
|
||||
var/ready = 0
|
||||
|
||||
|
||||
/hook/startup/proc/paiControllerSetup()
|
||||
paiController = new /datum/paiController()
|
||||
return 1
|
||||
|
||||
|
||||
/datum/paiController
|
||||
var/inquirer = null
|
||||
var/list/pai_candidates = list()
|
||||
var/list/asked = list()
|
||||
|
||||
var/askDelay = 10 * 60 * 1 // One minute [ms * sec * min]
|
||||
|
||||
/datum/paiController/Topic(href, href_list[])
|
||||
if(href_list["download"])
|
||||
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
|
||||
var/obj/item/device/paicard/card = locate(href_list["device"])
|
||||
if (!candidate in pai_candidates)
|
||||
return
|
||||
|
||||
if(card.pai)
|
||||
return
|
||||
if(istype(card,/obj/item/device/paicard) && istype(candidate,/datum/paiCandidate))
|
||||
var/mob/living/silicon/pai/pai = new(card)
|
||||
if(!candidate.name)
|
||||
pai.name = pick(ninja_names)
|
||||
else
|
||||
pai.name = candidate.name
|
||||
pai.real_name = pai.name
|
||||
pai.key = candidate.key
|
||||
|
||||
card.setPersonality(pai)
|
||||
card.looking_for_personality = 0
|
||||
|
||||
if(pai.mind) update_antag_icons(pai.mind)
|
||||
|
||||
pai_candidates -= candidate
|
||||
usr << browse(null, "window=findPai")
|
||||
|
||||
if(href_list["new"])
|
||||
var/datum/paiCandidate/candidate = locate(href_list["candidate"])
|
||||
var/option = href_list["option"]
|
||||
var/t = ""
|
||||
|
||||
switch(option)
|
||||
if("name")
|
||||
t = sanitizeSafe(input("Enter a name for your pAI", "pAI Name", candidate.name) as text, MAX_NAME_LEN)
|
||||
if(t)
|
||||
candidate.name = t
|
||||
if("desc")
|
||||
t = input("Enter a description for your pAI", "pAI Description", candidate.description) as message
|
||||
if(t)
|
||||
candidate.description = sanitize(t)
|
||||
if("role")
|
||||
t = input("Enter a role for your pAI", "pAI Role", candidate.role) as text
|
||||
if(t)
|
||||
candidate.role = sanitize(t)
|
||||
if("ooc")
|
||||
t = input("Enter any OOC comments", "pAI OOC Comments", candidate.comments) as message
|
||||
if(t)
|
||||
candidate.comments = sanitize(t)
|
||||
|
||||
if("save")
|
||||
if (config.sql_saves)
|
||||
usr.client.prefs.save_preferences()
|
||||
else
|
||||
candidate.savefile_save(usr)
|
||||
if("load")
|
||||
if (config.sql_saves)
|
||||
usr.client.prefs.load_preferences()
|
||||
else
|
||||
candidate.savefile_load(usr)
|
||||
//In case people have saved unsanitized stuff.
|
||||
if(candidate.name)
|
||||
candidate.name = sanitizeSafe(candidate.name, MAX_NAME_LEN)
|
||||
if(candidate.description)
|
||||
candidate.description = sanitize(candidate.description)
|
||||
if(candidate.role)
|
||||
candidate.role = sanitize(candidate.role)
|
||||
if(candidate.comments)
|
||||
candidate.comments = sanitize(candidate.comments)
|
||||
|
||||
if("submit")
|
||||
if(candidate)
|
||||
candidate.ready = 1
|
||||
for(var/obj/item/device/paicard/p in world)
|
||||
if(p.looking_for_personality == 1)
|
||||
p.alertUpdate()
|
||||
usr << browse(null, "window=paiRecruit")
|
||||
return
|
||||
if (config.sql_saves)
|
||||
usr.client.prefs.save_preferences()
|
||||
else
|
||||
candidate.savefile_save(usr)
|
||||
recruitWindow(usr, href_list["allow_submit"] != "0")
|
||||
|
||||
/datum/paiController/proc/recruitWindow(var/mob/M as mob, allowSubmit = 1)
|
||||
var/datum/paiCandidate/candidate
|
||||
for(var/datum/paiCandidate/c in pai_candidates)
|
||||
if(!istype(c) || !istype(M))
|
||||
break
|
||||
if(c.key == M.key)
|
||||
candidate = c
|
||||
if(!candidate)
|
||||
candidate = new /datum/paiCandidate()
|
||||
candidate.key = M.key
|
||||
pai_candidates.Add(candidate)
|
||||
|
||||
// Load the data before displaying.
|
||||
if (!config.sql_saves)
|
||||
candidate.savefile_load(M)
|
||||
else
|
||||
M.client.prefs.load_preferences()
|
||||
|
||||
var/dat = ""
|
||||
dat += {"
|
||||
<style type="text/css">
|
||||
body {
|
||||
margin-top:5px;
|
||||
font-family:Verdana;
|
||||
color:white;
|
||||
font-size:13px;
|
||||
background-image:url('uiBackground.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color:#272727;
|
||||
background-position:center top;
|
||||
}
|
||||
table {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #333333;
|
||||
}
|
||||
p.top {
|
||||
background-color: none;
|
||||
color: white;
|
||||
}
|
||||
tr.d0 td {
|
||||
background-color: #c0c0c0;
|
||||
color: black;
|
||||
border:0px;
|
||||
border: 1px solid #333333;
|
||||
}
|
||||
tr.d0 th {
|
||||
background-color: none;
|
||||
color: #4477E0;
|
||||
text-align:right;
|
||||
vertical-align:top;
|
||||
width:120px;
|
||||
border:0px;
|
||||
}
|
||||
tr.d1 td {
|
||||
background-color: #555555;
|
||||
color: white;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
}
|
||||
td.desc {
|
||||
font-weight:bold;
|
||||
}
|
||||
a {
|
||||
color:#4477E0;
|
||||
}
|
||||
a.button {
|
||||
color:white;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
"}
|
||||
|
||||
dat += {"
|
||||
<body>
|
||||
<b><font size="3px">pAI Personality Configuration</font></b>
|
||||
<p class="top">Please configure your pAI personality's options. Remember, what you enter here could determine whether or not the user requesting a personality chooses you!</p>
|
||||
|
||||
<table>
|
||||
<tr class="d0">
|
||||
<th rowspan="2"><a href='byond://?src=\ref[src];option=name;new=1;allow_submit=[allowSubmit];candidate=\ref[candidate]'>Name</a>:</th>
|
||||
<td class="desc">[candidate.name] </td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>What you plan to call yourself. Suggestions: Any character name you would choose for a station character OR an AI.</td>
|
||||
</tr>
|
||||
<tr class="d0">
|
||||
<th rowspan="2"><a href='byond://?src=\ref[src];option=desc;new=1;allow_submit=[allowSubmit];candidate=\ref[candidate]'>Description</a>:</th>
|
||||
<td class="desc">[candidate.description] </td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>What sort of pAI you typically play; your mannerisms, your quirks, etc. This can be as sparse or as detailed as you like.</td>
|
||||
</tr>
|
||||
<tr class="d0">
|
||||
<th rowspan="2"><a href='byond://?src=\ref[src];option=role;new=1;allow_submit=[allowSubmit];candidate=\ref[candidate]'>Preferred Role</a>:</th>
|
||||
<td class="desc">[candidate.role] </td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>Do you like to partner with sneaky social ninjas? Like to help security hunt down thugs? Enjoy watching an engineer's back while he saves the station yet again? This doesn't have to be limited to just station jobs. Pretty much any general descriptor for what you'd like to be doing works here.</td>
|
||||
</tr>
|
||||
<tr class="d0">
|
||||
<th rowspan="2"><a href='byond://?src=\ref[src];option=ooc;new=1;allow_submit=[allowSubmit];candidate=\ref[candidate]'>OOC Comments</a>:</th>
|
||||
<td class="desc">[candidate.comments] </td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<td>Anything you'd like to address specifically to the player reading this in an OOC manner. \"I prefer more serious RP.\", \"I'm still learning the interface!\", etc. Feel free to leave this blank if you want.</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
if(allowSubmit)
|
||||
dat += {"
|
||||
<table>
|
||||
<td class="button"><a href='byond://?src=\ref[src];option=submit;new=1;candidate=\ref[candidate]' class="button"><b><font size="4px">Submit Personality</font></b></a></td>
|
||||
</table><br>
|
||||
"}
|
||||
dat += {"
|
||||
<body>
|
||||
"}
|
||||
|
||||
M << browse(dat, "window=paiRecruit;size=580x580;")
|
||||
|
||||
/datum/paiController/proc/findPAI(var/obj/item/device/paicard/p, var/mob/user)
|
||||
requestRecruits(user)
|
||||
var/list/available = list()
|
||||
for(var/datum/paiCandidate/c in paiController.pai_candidates)
|
||||
if(c.ready)
|
||||
var/found = 0
|
||||
for(var/mob/dead/observer/o in player_list)
|
||||
if(o.key == c.key && o.MayRespawn())
|
||||
found = 1
|
||||
if(found)
|
||||
available.Add(c)
|
||||
var/dat = ""
|
||||
|
||||
dat += {"
|
||||
<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
margin-top:5px;
|
||||
font-family:Verdana;
|
||||
color:white;
|
||||
font-size:13px;
|
||||
background-image:url('uiBackground.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color:#272727;
|
||||
background-position:center top;
|
||||
}
|
||||
table {
|
||||
font-size:13px;
|
||||
}
|
||||
table.desc {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
table.download {
|
||||
border-collapse:collapse;
|
||||
font-size:13px;
|
||||
border: 1px solid #161616;
|
||||
width:100%;
|
||||
}
|
||||
tr.d0 td, tr.d0 th {
|
||||
background-color: #506070;
|
||||
color: white;
|
||||
}
|
||||
tr.d1 td, tr.d1 th {
|
||||
background-color: #708090;
|
||||
color: white;
|
||||
}
|
||||
tr.d2 td {
|
||||
background-color: #00FF00;
|
||||
color: white;
|
||||
text-align:center;
|
||||
}
|
||||
td.button {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
td.download {
|
||||
border: 1px solid #161616;
|
||||
background-color: #40628a;
|
||||
text-align: center;
|
||||
}
|
||||
th {
|
||||
text-align:left;
|
||||
width:125px;
|
||||
vertical-align:top;
|
||||
}
|
||||
a.button {
|
||||
color:white;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<b><font size='3px'>pAI Availability List</font></b><br><br>
|
||||
"}
|
||||
dat += "<p>Displaying available AI personalities from central database... If there are no entries, or if a suitable entry is not listed, check again later as more personalities may be added.</p>"
|
||||
|
||||
for(var/datum/paiCandidate/c in available)
|
||||
dat += {"
|
||||
<table class="desc">
|
||||
<tr class="d0">
|
||||
<th>Name:</th>
|
||||
<td>[c.name]</td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<th>Description:</th>
|
||||
<td>[c.description]</td>
|
||||
</tr>
|
||||
<tr class="d0">
|
||||
<th>Preferred Role:</th>
|
||||
<td>[c.role]</td>
|
||||
</tr>
|
||||
<tr class="d1">
|
||||
<th>OOC Comments:</th>
|
||||
<td>[c.comments]</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="download">
|
||||
<td class="download"><a href='byond://?src=\ref[src];download=1;candidate=\ref[c];device=\ref[p]' class="button"><b>Download [c.name]</b></a>
|
||||
</td>
|
||||
</table>
|
||||
<br>
|
||||
"}
|
||||
|
||||
dat += {"
|
||||
</body>
|
||||
</html>
|
||||
"}
|
||||
|
||||
user << browse(dat, "window=findPai")
|
||||
|
||||
|
||||
/datum/paiController/proc/requestRecruits(var/mob/user)
|
||||
inquirer = user
|
||||
for(var/mob/dead/observer/O in player_list)
|
||||
if(!O.MayRespawn())
|
||||
continue
|
||||
if(jobban_isbanned(O, "pAI"))
|
||||
continue
|
||||
if(asked.Find(O.key))
|
||||
if(world.time < asked[O.key] + askDelay)
|
||||
continue
|
||||
else
|
||||
asked.Remove(O.key)
|
||||
if(O.client)
|
||||
if(BE_PAI in O.client.prefs.be_special_role)
|
||||
question(O.client)
|
||||
|
||||
/datum/paiController/proc/question(var/client/C)
|
||||
spawn(0)
|
||||
if(!C) return
|
||||
asked.Add(C.key)
|
||||
asked[C.key] = world.time
|
||||
var/response = alert(C, "[inquirer] is requesting a pAI personality. Would you like to play as a personal AI?", "pAI Request", "Yes", "No", "Never for this round")
|
||||
if(!C) return //handle logouts that happen whilst the alert is waiting for a response.
|
||||
if(response == "Yes")
|
||||
recruitWindow(C.mob)
|
||||
else if (response == "Never for this round")
|
||||
C.prefs.be_special_role -= BE_PAI
|
||||
@@ -16,26 +16,9 @@ var/list/pai_emotions = list(
|
||||
"Question Mark" = 15
|
||||
)
|
||||
|
||||
|
||||
var/global/list/pai_software_by_key = list()
|
||||
var/global/list/default_pai_software = list()
|
||||
/hook/startup/proc/populate_pai_software_list()
|
||||
var/r = 1 // I would use ., but it'd sacrifice runtime detection
|
||||
for(var/type in typesof(/datum/pai_software) - /datum/pai_software)
|
||||
var/datum/pai_software/P = new type()
|
||||
if(pai_software_by_key[P.id])
|
||||
var/datum/pai_software/O = pai_software_by_key[P.id]
|
||||
world << "<span class='warning'>pAI software module [P.name] has the same key as [O.name]!</span>"
|
||||
r = 0
|
||||
continue
|
||||
pai_software_by_key[P.id] = P
|
||||
if(P.default)
|
||||
default_pai_software[P.id] = P
|
||||
return r
|
||||
|
||||
/mob/living/silicon/pai/New()
|
||||
/mob/living/silicon/pai/Initialize()
|
||||
..()
|
||||
software = default_pai_software.Copy()
|
||||
software = SSpai.default_pai_software.Copy()
|
||||
|
||||
/mob/living/silicon/pai/verb/paiInterface()
|
||||
set category = "pAI Commands"
|
||||
@@ -62,6 +45,8 @@ var/global/list/default_pai_software = list()
|
||||
var/bought_software[0]
|
||||
// Software we have not bought
|
||||
var/not_bought_software[0]
|
||||
|
||||
var/list/pai_software_by_key = SSpai.pai_software_by_key
|
||||
|
||||
for(var/key in pai_software_by_key)
|
||||
var/datum/pai_software/S = pai_software_by_key[key]
|
||||
@@ -118,7 +103,7 @@ var/global/list/default_pai_software = list()
|
||||
|
||||
else if(href_list["purchase"])
|
||||
var/soft = href_list["purchase"]
|
||||
var/datum/pai_software/S = pai_software_by_key[soft]
|
||||
var/datum/pai_software/S = SSpai.pai_software_by_key[soft]
|
||||
if(S && (ram >= S.ram_cost))
|
||||
ram -= S.ram_cost
|
||||
software[S.id] = S
|
||||
|
||||
@@ -90,7 +90,7 @@ var/list/mob_hat_cache = list()
|
||||
/mob/living/silicon/robot/drone/Destroy()
|
||||
if(hat)
|
||||
hat.loc = get_turf(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/drone/construction
|
||||
icon_state = "constructiondrone"
|
||||
@@ -149,13 +149,11 @@ var/list/mob_hat_cache = list()
|
||||
|
||||
/mob/living/silicon/robot/drone/updateicon()
|
||||
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(stat == 0)
|
||||
overlays += "eyes-[icon_state]"
|
||||
else
|
||||
overlays -= "eyes"
|
||||
add_overlay("eyes-[icon_state]")
|
||||
if(hat) // Let the drones wear hats.
|
||||
overlays |= get_hat_icon(hat, hat_x_offset, hat_y_offset)
|
||||
add_overlay(get_hat_icon(hat, hat_x_offset, hat_y_offset))
|
||||
|
||||
/mob/living/silicon/robot/drone/choose_icon()
|
||||
return
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
set desc = "Tag yourself for delivery through the disposals system."
|
||||
set category = "Robot Commands"
|
||||
|
||||
var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in tagger_locations
|
||||
var/new_tag = input("Select the desired destination.", "Set Mail Tag", null) as null|anything in SSdisposals.tagger_locations
|
||||
|
||||
if(!new_tag)
|
||||
mail_destination = ""
|
||||
@@ -19,8 +19,6 @@
|
||||
src << "<span class='notice'>\The [D] acknowledges your signal.</span>"
|
||||
D.flush_count = D.flush_every_ticks
|
||||
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/drone/MouseDrop(atom/over_object)
|
||||
var/mob/living/carbon/H = over_object
|
||||
if(!istype(H) || !Adjacent(H)) return ..()
|
||||
@@ -34,4 +32,4 @@
|
||||
hat = null
|
||||
updateicon()
|
||||
else
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
if (href_list["setarea"])
|
||||
|
||||
//Probably should consider using another list, but this one will do.
|
||||
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in tagger_locations
|
||||
var/t_area = input("Select the area to ping.", "Set Target Area", null) as null|anything in SSdisposals.tagger_locations
|
||||
|
||||
if(!t_area)
|
||||
return
|
||||
@@ -120,4 +120,4 @@
|
||||
dronefab.produce_drones = !dronefab.produce_drones
|
||||
usr << "<span class='notice'>You [dronefab.produce_drones ? "enable" : "disable"] drone production in the nearby fabricator.</span>"
|
||||
|
||||
src.updateUsrDialog()
|
||||
src.updateUsrDialog()
|
||||
|
||||
@@ -29,9 +29,6 @@
|
||||
fabricator_tag = "Derelict"
|
||||
drone_type = /mob/living/silicon/robot/drone/construction
|
||||
|
||||
/obj/machinery/drone_fabricator/New()
|
||||
..()
|
||||
|
||||
/obj/machinery/drone_fabricator/power_change()
|
||||
..()
|
||||
if (stat & NOPOWER)
|
||||
@@ -39,7 +36,7 @@
|
||||
|
||||
/obj/machinery/drone_fabricator/process()
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
if(!ROUND_IS_STARTED)
|
||||
return
|
||||
|
||||
if(stat & NOPOWER || !produce_drones)
|
||||
@@ -78,8 +75,10 @@
|
||||
flick("h_lathe_leave",src)
|
||||
|
||||
time_last_drone = world.time
|
||||
if(player.mob && player.mob.mind) player.mob.mind.reset()
|
||||
var/mob/living/silicon/robot/drone/new_drone = getFromPool(drone_type, get_turf(src))
|
||||
if(player.mob && player.mob.mind)
|
||||
player.mob.mind.reset()
|
||||
|
||||
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
|
||||
new_drone.transfer_personality(player)
|
||||
new_drone.master_fabricator = src
|
||||
|
||||
@@ -93,7 +92,7 @@
|
||||
|
||||
/proc/try_drone_spawn(var/mob/user, var/obj/machinery/drone_fabricator/fabricator)
|
||||
|
||||
if(ticker.current_state < GAME_STATE_PLAYING)
|
||||
if(!ROUND_IS_STARTED)
|
||||
user << "<span class='danger'>The game hasn't started yet!</span>"
|
||||
return
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/mob/living/silicon/robot/Life()
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
if (src.transforming)
|
||||
return
|
||||
|
||||
@@ -765,30 +765,28 @@
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/updateicon()
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
|
||||
if(stat == CONSCIOUS)
|
||||
overlays += "eyes-[module_sprites[icontype]]"
|
||||
|
||||
add_overlay("eyes-[module_sprites[icontype]]")
|
||||
|
||||
if(opened)
|
||||
var/panelprefix = custom_sprite ? src.ckey : "ov"
|
||||
if(wiresexposed)
|
||||
overlays += "[panelprefix]-openpanel +w"
|
||||
add_overlay("[panelprefix]-openpanel +w")
|
||||
else if(cell)
|
||||
overlays += "[panelprefix]-openpanel +c"
|
||||
add_overlay("[panelprefix]-openpanel +c")
|
||||
else
|
||||
overlays += "[panelprefix]-openpanel -c"
|
||||
add_overlay("[panelprefix]-openpanel -c")
|
||||
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
|
||||
overlays += "[module_sprites[icontype]]-shield"
|
||||
add_overlay("[module_sprites[icontype]]-shield")
|
||||
|
||||
if(modtype == "Combat")
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
|
||||
icon_state = "[module_sprites[icontype]]-roll"
|
||||
else
|
||||
icon_state = module_sprites[icontype]
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/proc/installed_modules()
|
||||
if(weapon_lock)
|
||||
|
||||
@@ -28,28 +28,27 @@
|
||||
verbs += /mob/living/silicon/robot/proc/choose_icon
|
||||
|
||||
/mob/living/silicon/robot/syndicate/updateicon() //because this was the only way I found out how to make their eyes and etc works
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(stat == 0)
|
||||
overlays += "eyes-[icon_state]"
|
||||
add_overlay("eyes-[icon_state]")
|
||||
|
||||
if(opened)
|
||||
var/panelprefix = custom_sprite ? src.ckey : "ov"
|
||||
if(wiresexposed)
|
||||
overlays += "[panelprefix]-openpanel +w"
|
||||
add_overlay("[panelprefix]-openpanel +w")
|
||||
else if(cell)
|
||||
overlays += "[panelprefix]-openpanel +c"
|
||||
add_overlay("[panelprefix]-openpanel +c")
|
||||
else
|
||||
overlays += "[panelprefix]-openpanel -c"
|
||||
add_overlay("[panelprefix]-openpanel -c")
|
||||
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/shield))
|
||||
overlays += "[icon_state]-shield"
|
||||
add_overlay("[icon_state]-shield")
|
||||
|
||||
if(modtype == "Combat")
|
||||
if(module_active && istype(module_active,/obj/item/borg/combat/mobility))
|
||||
icon_state = "[icon_state]-roll"
|
||||
else
|
||||
icon_state = module_sprites[icontype]
|
||||
return
|
||||
|
||||
/mob/living/silicon/robot/syndicate/death()
|
||||
..()
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
|
||||
/mob/living/silicon/Destroy()
|
||||
silicon_mob_list -= src
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
for(var/datum/alarm_handler/AH in SSalarm.all_handlers)
|
||||
AH.unregister_alarm(src)
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/proc/init_id()
|
||||
if(idcard)
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
if(!register_alarms)
|
||||
return
|
||||
|
||||
for(var/datum/alarm_handler/AH in alarm_manager.all_handlers)
|
||||
for(var/datum/alarm_handler/AH in SSalarm.all_handlers)
|
||||
AH.register_alarm(src, /mob/living/silicon/proc/receive_alarm)
|
||||
queued_alarms[AH] = list() // Makes sure alarms remain listed in consistent order
|
||||
|
||||
|
||||
@@ -28,7 +28,11 @@
|
||||
/mob/living/simple_animal/bee/Destroy()
|
||||
if(parent)
|
||||
parent.owned_bee_swarms.Remove(src)
|
||||
..()
|
||||
my_hydrotray = null
|
||||
parent = null
|
||||
target_turf = null
|
||||
target_mob = null
|
||||
return ..()
|
||||
|
||||
|
||||
//Special death behaviour. When bees accumulate enough damage to 'die', they don't outright die. Thus no call to parent
|
||||
@@ -36,7 +40,7 @@
|
||||
//Repeat until strength hits zero. only THEN do they die, and they qdel and leave no corpse in doing so
|
||||
//Because we don't have sprites for a carpet made of bee corpses.
|
||||
/mob/living/simple_animal/bee/death()
|
||||
if (!gcDestroyed)
|
||||
if (!QDELING(src))
|
||||
strength -= 1
|
||||
if (strength <= 0)
|
||||
if (prob(35))//probability to reduce spam
|
||||
@@ -261,4 +265,4 @@
|
||||
/mob/living/simple_animal/bee/beegun
|
||||
maxHealth = 30
|
||||
strength = 5
|
||||
feral = 30
|
||||
feral = 30
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
var/corpseidaccess = null //This is for access. See access.dm for which jobs give what access. Again, put in quotes. Use "Captain" if you want it to be all access.
|
||||
var/corpseidicon = null //For setting it to be a gold, silver, centcomm etc ID
|
||||
|
||||
/obj/effect/landmark/mobcorpse/New()
|
||||
/obj/effect/landmark/mobcorpse/Initialize()
|
||||
createCorpse()
|
||||
|
||||
/obj/effect/landmark/mobcorpse/proc/createCorpse() //Creates a mob and checks for gear in each slot before attempting to equip it.
|
||||
@@ -154,4 +154,4 @@
|
||||
corpsehelmet = /obj/item/clothing/head/bearpelt
|
||||
|
||||
/obj/effect/landmark/mobcorpse/russian/ranged
|
||||
corpsehelmet = /obj/item/clothing/head/ushanka
|
||||
corpsehelmet = /obj/item/clothing/head/ushanka
|
||||
|
||||
@@ -63,8 +63,7 @@
|
||||
if (!movement_target)
|
||||
walk_to(src,0)
|
||||
|
||||
spawn(2)
|
||||
attack_mice()
|
||||
addtimer(CALLBACK(src, .proc/attack_mice), 2)
|
||||
|
||||
if(prob(2)) //spooky
|
||||
var/mob/dead/observer/spook = locate() in range(src,5)
|
||||
@@ -110,8 +109,7 @@
|
||||
/mob/living/simple_animal/cat/Released()
|
||||
//A thrown cat will immediately attack mice near where it lands
|
||||
handle_movement_target()
|
||||
spawn(3)
|
||||
attack_mice()
|
||||
addtimer(CALLBACK(src, .proc/attack_mice), 3)
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/cat/death()
|
||||
@@ -164,7 +162,7 @@
|
||||
var/befriend_job = null
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/handle_movement_target()
|
||||
if (friend)
|
||||
if (!QDELETED(friend))
|
||||
var/follow_dist = 5
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit) //danger
|
||||
follow_dist = 1
|
||||
@@ -197,7 +195,7 @@
|
||||
|
||||
/mob/living/simple_animal/cat/fluff/Life()
|
||||
..()
|
||||
if (stat || !friend)
|
||||
if (stat || QDELETED(friend))
|
||||
return
|
||||
if (get_dist(src, friend) <= 1)
|
||||
if (friend.stat >= DEAD || friend.health <= config.health_threshold_softcrit)
|
||||
|
||||
@@ -200,9 +200,6 @@
|
||||
..()
|
||||
desc = "How could you do this? You monster!"
|
||||
|
||||
var/const/MAX_CHICKENS = 50
|
||||
var/global/chicken_count = 0
|
||||
|
||||
/mob/living/simple_animal/chicken
|
||||
name = "\improper chicken"
|
||||
desc = "Hopefully the eggs are good this season."
|
||||
@@ -230,6 +227,8 @@ var/global/chicken_count = 0
|
||||
mob_size = 2
|
||||
hunger_enabled = FALSE
|
||||
|
||||
var/static/chicken_count = 0
|
||||
|
||||
/mob/living/simple_animal/chicken/New()
|
||||
..()
|
||||
if(!body_color)
|
||||
@@ -283,16 +282,19 @@ var/global/chicken_count = 0
|
||||
E.pixel_x = rand(-6,6)
|
||||
E.pixel_y = rand(-6,6)
|
||||
if(chicken_count < MAX_CHICKENS && prob(10))
|
||||
processing_objects.Add(E)
|
||||
START_PROCESSING(SSprocessing, E)
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg
|
||||
var/amount_grown = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/var/amount_grown = 0
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/process()
|
||||
if(isturf(loc))
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
visible_message("[src] hatches with a quiet cracking sound.")
|
||||
new /mob/living/simple_animal/chick(get_turf(src))
|
||||
processing_objects.Remove(src)
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
qdel(src)
|
||||
else
|
||||
STOP_PROCESSING(SSprocessing, src)
|
||||
processing_objects.Remove(src)
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
/mob/living/simple_animal/adultslime/New()
|
||||
..()
|
||||
overlays += "aslime-:33"
|
||||
add_overlay("aslime-:33")
|
||||
|
||||
|
||||
/mob/living/simple_animal/slime/adult/death()
|
||||
@@ -54,4 +54,4 @@
|
||||
S2.icon_living = "[src.colour] baby slime"
|
||||
S2.icon_dead = "[src.colour] baby slime dead"
|
||||
S2.colour = "[src.colour]"
|
||||
qdel(src)
|
||||
qdel(src)
|
||||
|
||||
@@ -156,7 +156,7 @@
|
||||
eject_brain()
|
||||
death()
|
||||
|
||||
/mob/living/simple_animal/spiderbot/proc/update_icon()
|
||||
/mob/living/simple_animal/spiderbot/update_icon()
|
||||
if(mmi)
|
||||
if(positronic)
|
||||
icon_state = "spiderbot-chassis-posi"
|
||||
@@ -183,7 +183,7 @@
|
||||
|
||||
/mob/living/simple_animal/spiderbot/Destroy()
|
||||
eject_brain()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/spiderbot/New()
|
||||
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
/mob/living/simple_animal/hostile/scarybat/Allow_Spacemove(var/check_drift = 0)
|
||||
return ..() //No drifting in space for space carp! //original comments do not steal
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/Destroy()
|
||||
owner = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/scarybat/FindTarget()
|
||||
. = ..()
|
||||
if(.)
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
if(busy == LAYING_EGGS)
|
||||
E = locate() in get_turf(src)
|
||||
if(!E)
|
||||
getFromPool(/obj/effect/spider/eggcluster, loc, src)
|
||||
new /obj/effect/spider/eggcluster(loc, src)
|
||||
fed--
|
||||
busy = 0
|
||||
stop_automated_movement = 0
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
var/shuttletarget = null
|
||||
var/enroute = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/Destroy()
|
||||
friends = null
|
||||
target_mob = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/FindTarget()
|
||||
|
||||
var/atom/T = null
|
||||
@@ -74,7 +79,7 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
if(QDELETED(target_mob) || SA_attackable(target_mob))
|
||||
LoseTarget()
|
||||
if(target_mob in ListTargets(10))
|
||||
if(ranged)
|
||||
@@ -89,7 +94,7 @@
|
||||
/mob/living/simple_animal/hostile/proc/AttackTarget()
|
||||
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
if(QDELETED(target_mob) || SA_attackable(target_mob))
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(!(target_mob in ListTargets(10)))
|
||||
@@ -129,7 +134,7 @@
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/ListTargets(var/dist = 7)
|
||||
var/list/L = hearers(src, dist)
|
||||
var/list/L = view(src, dist)
|
||||
|
||||
for (var/obj/mecha/M in mechas_list)
|
||||
if (M.z == src.z && get_dist(src, M) <= dist)
|
||||
@@ -170,18 +175,11 @@
|
||||
visible_message("\red <b>[src]</b> fires at [target]!", 1)
|
||||
|
||||
if(rapid)
|
||||
spawn(1)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
spawn(4)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
spawn(6)
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
new casingtype(get_turf(src))
|
||||
var/datum/callback/shoot_cb = CALLBACK(src, .proc/shoot_wrapper, target, loc, src)
|
||||
addtimer(shoot_cb, 1)
|
||||
addtimer(shoot_cb, 4)
|
||||
addtimer(shoot_cb, 6)
|
||||
|
||||
else
|
||||
Shoot(target, src.loc, src)
|
||||
if(casingtype)
|
||||
@@ -191,6 +189,10 @@
|
||||
target_mob = null
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/shoot_wrapper(target, location, user)
|
||||
Shoot(target, location, user)
|
||||
if (casingtype)
|
||||
new casingtype(loc)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Shoot(var/target, var/start, var/user, var/bullet = 0)
|
||||
if(target == start)
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
var/attempt_open = 0
|
||||
|
||||
// Pickup loot
|
||||
/mob/living/simple_animal/hostile/mimic/crate/initialize()
|
||||
..()
|
||||
/mob/living/simple_animal/hostile/mimic/crate/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/I in loc)
|
||||
I.loc = src
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@
|
||||
qdel(src)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/malf_drone/Destroy()
|
||||
QDEL_NULL(ion_trail)
|
||||
//some random debris left behind
|
||||
if(has_loot)
|
||||
spark(src, 3, alldirs)
|
||||
@@ -176,16 +177,16 @@
|
||||
step_to(O, get_turf(pick(view(7, src))))
|
||||
|
||||
//rods
|
||||
O = getFromPool(/obj/item/stack/rods, src.loc)
|
||||
O = new /obj/item/stack/rods(src.loc)
|
||||
step_to(O, get_turf(pick(view(7, src))))
|
||||
if(prob(75))
|
||||
O = getFromPool(/obj/item/stack/rods, src.loc)
|
||||
O = new /obj/item/stack/rods(src.loc)
|
||||
step_to(O, get_turf(pick(view(7, src))))
|
||||
if(prob(50))
|
||||
O = getFromPool(/obj/item/stack/rods, src.loc)
|
||||
O = new /obj/item/stack/rods(src.loc)
|
||||
step_to(O, get_turf(pick(view(7, src))))
|
||||
if(prob(25))
|
||||
O = getFromPool(/obj/item/stack/rods, src.loc)
|
||||
O = new /obj/item/stack/rods(src.loc)
|
||||
step_to(O, get_turf(pick(view(7, src))))
|
||||
|
||||
//plasteel
|
||||
@@ -263,7 +264,7 @@
|
||||
C.name = "Corrupted drone morality core"
|
||||
C.origin_tech = list(TECH_ILLEGAL = rand(3,6))
|
||||
|
||||
..()
|
||||
return ..()
|
||||
|
||||
/obj/item/projectile/beam/drone
|
||||
damage = 15
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/mob/living/simple_animal/hostile/retaliate
|
||||
var/list/enemies = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/Destroy()
|
||||
enemies = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/Found(var/atom/A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
|
||||
@@ -100,6 +100,11 @@
|
||||
/mob/living/simple_animal/parrot/verb/drop_held_item_player, \
|
||||
/mob/living/simple_animal/parrot/proc/perch_player)
|
||||
|
||||
/mob/living/simple_animal/parrot/Destroy()
|
||||
QDEL_NULL(ears)
|
||||
parrot_interest = null
|
||||
parrot_perch = null
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/parrot/death()
|
||||
if(held_item)
|
||||
@@ -751,4 +756,4 @@
|
||||
parrot_interest = user
|
||||
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
|
||||
icon_state = "parrot_fly"
|
||||
return success
|
||||
return success
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
Destroy() //if a chunk a destroyed, make a new worm out of the split halves
|
||||
if(previous)
|
||||
previous.Detach()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
Move()
|
||||
var/attachementNextPosition = loc
|
||||
@@ -123,7 +123,7 @@
|
||||
|
||||
return
|
||||
|
||||
proc/update_icon() //only for the sake of consistency with the other update icon procs
|
||||
update_icon() //only for the sake of consistency with the other update icon procs
|
||||
if(stat == CONSCIOUS || stat == UNCONSCIOUS)
|
||||
if(previous) //midsection
|
||||
icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
player_list -= src
|
||||
log_access("Logout: [key_name(src)]",ckey=key_name(src))
|
||||
if(admin_datums[src.ckey])
|
||||
if (ticker && ticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing.
|
||||
if (SSticker.current_state == GAME_STATE_PLAYING) //Only report this stuff if we are currently playing.
|
||||
var/admins_number = 0
|
||||
var/admins_number_afk = 0
|
||||
for (var/client/C)
|
||||
|
||||
+45
-40
@@ -3,7 +3,7 @@
|
||||
dead_mob_list -= src
|
||||
living_mob_list -= src
|
||||
unset_machine()
|
||||
qdel(hud_used)
|
||||
QDEL_NULL(hud_used)
|
||||
if(client)
|
||||
for(var/obj/screen/movable/spell_master/spell_master in spell_masters)
|
||||
qdel(spell_master)
|
||||
@@ -15,8 +15,7 @@
|
||||
spellremove(src)
|
||||
for(var/infection in viruses)
|
||||
qdel(infection)
|
||||
|
||||
|
||||
viruses.Cut()
|
||||
|
||||
//Added this to prevent nonliving mobs from ghostising
|
||||
//The only non 'living' mobs are:
|
||||
@@ -28,7 +27,9 @@
|
||||
//Ghosts are the only ones that even technically 'exist' and aren't just an abstraction using mob code for convenience
|
||||
if (istype(src, /mob/living))
|
||||
ghostize()
|
||||
..()
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/proc/remove_screen_obj_references()
|
||||
flash = null
|
||||
@@ -103,6 +104,10 @@
|
||||
|
||||
for(var/A in player_list)
|
||||
var/mob/M = A
|
||||
if (QDELETED(M))
|
||||
warning("Null or QDELETED object [DEBUG_REF(M)] found in player list! Removing.")
|
||||
player_list -= M
|
||||
continue
|
||||
if (!M.client || istype(M, /mob/new_player))
|
||||
continue
|
||||
if(get_turf(M) in messageturfs)
|
||||
@@ -174,7 +179,6 @@
|
||||
|
||||
M.show_message(message,2,deaf_message,1)
|
||||
|
||||
|
||||
for(var/o in objs)
|
||||
var/obj/O = o
|
||||
O.show_message(message,2,deaf_message,1)
|
||||
@@ -302,15 +306,13 @@
|
||||
|
||||
pointing_effect = new /obj/effect/decal/point(tile)
|
||||
pointing_effect.invisibility = invisibility
|
||||
spawn (20)
|
||||
if(pointing_effect)
|
||||
qdel(pointing_effect) // qdel
|
||||
pointing_effect = null
|
||||
addtimer(CALLBACK(src, .proc/clear_point), 20)
|
||||
|
||||
face_atom(A)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/proc/clear_point()
|
||||
QDEL_NULL(pointing_effect)
|
||||
|
||||
/mob/proc/ret_grab(obj/effect/list_container/mobl/L as obj, flag)
|
||||
if ((!( istype(l_hand, /obj/item/weapon/grab) ) && !( istype(r_hand, /obj/item/weapon/grab) )))
|
||||
@@ -448,10 +450,10 @@
|
||||
if (!( config.abandon_allowed ))
|
||||
usr << "<span class='notice'>Respawn is disabled.</span>"
|
||||
return
|
||||
if ((stat != DEAD || !( ticker )))
|
||||
if (stat != DEAD)
|
||||
usr << "<span class='notice'><B>You must be dead to use this!</B></span>"
|
||||
return
|
||||
if (ticker.mode.deny_respawn) //BS12 EDIT
|
||||
if (SSticker.mode && SSticker.mode.deny_respawn) //BS12 EDIT
|
||||
usr << "<span class='notice'>Respawn is disabled for this roundtype.</span>"
|
||||
return
|
||||
else if(!MayRespawn(1, CREW))
|
||||
@@ -487,26 +489,8 @@
|
||||
/client/verb/changes()
|
||||
set name = "Changelog"
|
||||
set category = "OOC"
|
||||
getFiles(
|
||||
'html/88x31.png',
|
||||
'html/bug-minus.png',
|
||||
'html/cross-circle.png',
|
||||
'html/hard-hat-exclamation.png',
|
||||
'html/image-minus.png',
|
||||
'html/image-plus.png',
|
||||
'html/map-pencil.png',
|
||||
'html/music-minus.png',
|
||||
'html/music-plus.png',
|
||||
'html/tick-circle.png',
|
||||
'html/wrench-screwdriver.png',
|
||||
'html/spell-check.png',
|
||||
'html/burn-exclamation.png',
|
||||
'html/chevron.png',
|
||||
'html/chevron-expand.png',
|
||||
'html/changelog.css',
|
||||
'html/changelog.js',
|
||||
'html/changelog.html'
|
||||
)
|
||||
var/datum/asset/changelog = get_asset_datum(/datum/asset/simple/changelog)
|
||||
changelog.send(src)
|
||||
src << browse('html/changelog.html', "window=changes;size=675x650")
|
||||
if(prefs.lastchangelog != changelog_hash)
|
||||
prefs.lastchangelog = changelog_hash
|
||||
@@ -746,7 +730,7 @@
|
||||
. = (is_client_active(10 MINUTES))
|
||||
|
||||
if(.)
|
||||
if(statpanel("Status") && ticker && ticker.current_state != GAME_STATE_PREGAME)
|
||||
if(statpanel("Status") && SSticker.current_state != GAME_STATE_PREGAME)
|
||||
stat("Game ID", game_id)
|
||||
stat("Station Time", worldtime2text())
|
||||
stat("Round Duration", round_duration())
|
||||
@@ -755,24 +739,45 @@
|
||||
if(client.holder)
|
||||
if(statpanel("Status"))
|
||||
stat("Location:", "([x], [y], [z]) [loc]")
|
||||
stat("CPU:","[world.cpu]")
|
||||
stat("Instances:","[world.contents.len]")
|
||||
if(statpanel("Processes"))
|
||||
if(processScheduler)
|
||||
processScheduler.statProcesses()
|
||||
if (LAZYLEN(client.holder.watched_processes))
|
||||
for (var/datum/controller/ctrl in client.holder.watched_processes)
|
||||
if (!ctrl)
|
||||
LAZYREMOVE(client.holder.watched_processes, ctrl)
|
||||
else
|
||||
ctrl.stat_entry()
|
||||
|
||||
if(statpanel("MC"))
|
||||
stat("CPU:", world.cpu)
|
||||
stat("Tick Usage:", world.tick_usage)
|
||||
stat("Instances:", world.contents.len)
|
||||
if(Master)
|
||||
Master.stat_entry()
|
||||
else
|
||||
stat("Master Controller:", "ERROR")
|
||||
if(Failsafe)
|
||||
Failsafe.stat_entry()
|
||||
else
|
||||
stat("Failsafe Controller:", "ERROR")
|
||||
if (Master)
|
||||
stat(null, "- Subsystems -")
|
||||
for(var/datum/controller/subsystem/SS in Master.subsystems)
|
||||
if (!Master.initializing && SS.flags & SS_NO_DISPLAY)
|
||||
continue
|
||||
|
||||
SS.stat_entry()
|
||||
|
||||
if(listed_turf && client)
|
||||
if(!TurfAdjacent(listed_turf))
|
||||
listed_turf = null
|
||||
else
|
||||
if(statpanel("Turf"))
|
||||
stat("\icon[listed_turf]", listed_turf.name)
|
||||
stat("Turf:", listed_turf)
|
||||
for(var/atom/A in listed_turf)
|
||||
if(!A.mouse_opacity)
|
||||
continue
|
||||
if(A.invisibility > see_invisible)
|
||||
continue
|
||||
if(is_type_in_list(A, shouldnt_see))
|
||||
if(is_type_in_typecache(A, shouldnt_see))
|
||||
continue
|
||||
stat(A)
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
var/captured = 0 //Functionally, should give the same effect as being buckled into a chair when true.
|
||||
|
||||
//Generic list for proc holders. Only way I can see to enable certain verbs/procs. Should be modified if needed.
|
||||
var/proc_holder_list[] = list()//Right now unused.
|
||||
//var/proc_holder_list[] = list()//Right now unused.
|
||||
//Also unlike the spell list, this would only store the object in contents, not an object in itself.
|
||||
|
||||
/* Add this line to whatever stat module you need in order to use the proc holder list.
|
||||
@@ -186,7 +186,7 @@
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
|
||||
//Wizard mode, but can be used in other modes thanks to the brand new "Give Spell" badmin button
|
||||
var/spell/list/spell_list = list()
|
||||
var/spell/list/spell_list
|
||||
|
||||
//Changlings, but can be used in other modes
|
||||
// var/obj/effect/proc_holder/changpower/list/power_list = list()
|
||||
@@ -226,7 +226,7 @@
|
||||
var/mob/teleop = null
|
||||
|
||||
var/turf/listed_turf = null //the current turf being examined in the stat panel
|
||||
var/list/shouldnt_see = list() //list of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
var/list/shouldnt_see = list() //typecache of objects that this mob shouldn't see in the stat panel. this silliness is needed because of AI alt+click and cult blood runes
|
||||
|
||||
var/list/active_genes=list()
|
||||
var/mob_size = MOB_MEDIUM
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
hud.screen_loc = ui_lhand
|
||||
|
||||
/obj/item/weapon/grab/process()
|
||||
if(gcDestroyed) // GC is trying to delete us, we'll kill our processing so we can cleanly GC
|
||||
if(QDELING(src)) // GC is trying to delete us, we'll kill our processing so we can cleanly GC
|
||||
return PROCESS_KILL
|
||||
|
||||
confirm()
|
||||
@@ -361,4 +361,4 @@
|
||||
qdel(hud)
|
||||
hud = null
|
||||
destroying = 1 // stops us calling qdel(src) on dropped()
|
||||
..()
|
||||
return ..()
|
||||
|
||||
@@ -184,34 +184,26 @@
|
||||
if(!mob)
|
||||
return // Moved here to avoid nullrefs below
|
||||
|
||||
if(mob.control_object) Move_object(direct)
|
||||
if(mob.control_object)
|
||||
Move_object(direct)
|
||||
|
||||
if(mob.incorporeal_move && isobserver(mob))
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
|
||||
if(moving) return 0
|
||||
if(moving || world.time < move_delay)
|
||||
return 0
|
||||
|
||||
if(world.time < move_delay)
|
||||
return
|
||||
|
||||
|
||||
//This compensates for the inaccuracy of move ticks
|
||||
//Whenever world.time overshoots the movedelay, due to it only ticking once per decisecond
|
||||
//The overshoot value is subtracted from our next delay, farther down where move delay is set.
|
||||
//This doesn't entirely remove the problem, but it keeps travel times accurate to within 0.1 seconds
|
||||
//Over an infinite distance, and prevents the inaccuracy from compounding. Thus making it basically a non-issue
|
||||
//This compensates for the inaccuracy of move ticks
|
||||
//Whenever world.time overshoots the movedelay, due to it only ticking once per decisecond
|
||||
//The overshoot value is subtracted from our next delay, farther down where move delay is set.
|
||||
//This doesn't entirely remove the problem, but it keeps travel times accurate to within 0.1 seconds
|
||||
//Over an infinite distance, and prevents the inaccuracy from compounding. Thus making it basically a non-issue
|
||||
var/leftover = world.time - move_delay
|
||||
if (leftover > 1)
|
||||
leftover = 0
|
||||
|
||||
|
||||
if(locate(/obj/effect/stop/, mob.loc))
|
||||
for(var/obj/effect/stop/S in mob.loc)
|
||||
if(S.victim == mob)
|
||||
return
|
||||
|
||||
if(mob.stat==DEAD && isliving(mob))
|
||||
if(mob.stat == DEAD && isliving(mob))
|
||||
mob.ghostize()
|
||||
return
|
||||
|
||||
@@ -219,21 +211,24 @@
|
||||
if(mob.eyeobj)
|
||||
return mob.EyeMove(n,direct)
|
||||
|
||||
if(mob.transforming) return//This is sota the goto stop mobs from moving var
|
||||
if(mob.transforming)
|
||||
return //This is sota the goto stop mobs from moving var
|
||||
|
||||
if(isliving(mob))
|
||||
var/mob/living/L = mob
|
||||
if(L.incorporeal_move)//Move though walls
|
||||
Process_Incorpmove(direct)
|
||||
return
|
||||
if(mob.client)
|
||||
if(mob.client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
||||
for(var/obj/item/item in mob.contents)
|
||||
if(item.zoom)
|
||||
item.zoom(mob)
|
||||
break
|
||||
|
||||
if(Process_Grab()) return
|
||||
if(mob.client && mob.client.view != world.view) // If mob moves while zoomed in with device, unzoom them.
|
||||
for(var/obj/item/item in mob)
|
||||
if(item.zoom)
|
||||
item.zoom(mob)
|
||||
break
|
||||
|
||||
// Only meaningful for living mobs.
|
||||
if(Process_Grab())
|
||||
return
|
||||
|
||||
if(!mob.canmove)
|
||||
return
|
||||
@@ -244,22 +239,18 @@
|
||||
if(!mob.lastarea)
|
||||
mob.lastarea = get_area(mob.loc)
|
||||
|
||||
if(!mob.check_solid_ground())
|
||||
var/allowmove = mob.Allow_Spacemove(0)
|
||||
if(!allowmove)
|
||||
return 0
|
||||
else if(allowmove == -1 && mob.handle_spaceslipping()) //Check to see if we slipped
|
||||
return 0
|
||||
else
|
||||
mob.inertia_dir = 0 //If not then we can reset inertia and move
|
||||
|
||||
if(isobj(mob.loc) || ismob(mob.loc))//Inside an object, tell it we moved
|
||||
var/atom/O = mob.loc
|
||||
return O.relaymove(mob, direct)
|
||||
|
||||
if(isturf(mob.loc))
|
||||
if(!mob.check_solid_ground())
|
||||
var/allowmove = mob.Allow_Spacemove(0)
|
||||
if(!allowmove)
|
||||
return 0
|
||||
else if(allowmove == -1 && mob.handle_spaceslipping()) //Check to see if we slipped
|
||||
return 0
|
||||
else
|
||||
mob.inertia_dir = 0 //If not then we can reset inertia and move
|
||||
|
||||
if(mob.restrained())//Why being pulled while cuffed prevents you from moving
|
||||
|
||||
if(mob.restrained()) //Why being pulled while cuffed prevents you from moving
|
||||
for(var/mob/M in range(mob, 1))
|
||||
if(M.pulling == mob)
|
||||
if(!M.restrained() && M.stat == 0 && M.canmove && mob.Adjacent(M))
|
||||
@@ -284,9 +275,6 @@
|
||||
direct = pick(cardinal)
|
||||
return mob.buckled.relaymove(mob,direct)
|
||||
|
||||
if(istype(mob.loc, /turf/space)) // Wheelchair driving!
|
||||
return // No wheelchair driving in space
|
||||
|
||||
//TODO: Fuck wheelchairs.
|
||||
//Toss away all this snowflake code here, and rewrite wheelchairs as a vehicle.
|
||||
else if(istype(mob.buckled, /obj/structure/bed/chair/wheelchair))
|
||||
@@ -306,8 +294,9 @@
|
||||
|
||||
var/tally = mob.movement_delay() + config.walk_speed
|
||||
|
||||
// Apply huuman specific modifiers.
|
||||
if (ishuman(mob))
|
||||
// Apply human specific modifiers.
|
||||
var/mob_is_human = ishuman(mob) // Only check this once and just reuse the value.
|
||||
if (mob_is_human)
|
||||
var/mob/living/carbon/human/H = mob
|
||||
//If we're sprinting and able to continue sprinting, then apply the sprint bonus ontop of this
|
||||
if (H.m_intent == "run" && H.species.handle_sprint_cost(H, tally)) //This will return false if we collapse from exhaustion
|
||||
@@ -319,7 +308,6 @@
|
||||
|
||||
move_delay += tally
|
||||
|
||||
|
||||
var/tickcomp = 0 //moved this out here so we can use it for vehicles
|
||||
if(config.Tickcomp)
|
||||
// move_delay -= 1.3 //~added to the tickcomp calculation below
|
||||
@@ -336,12 +324,10 @@
|
||||
move_delay += 1
|
||||
return mob.pulledby.relaymove(mob, direct)
|
||||
|
||||
|
||||
|
||||
//We are now going to move
|
||||
moving = 1
|
||||
//Something with pulling things
|
||||
if(locate(/obj/item/weapon/grab, mob))
|
||||
if (mob_is_human && (istype(mob:l_hand, /obj/item/weapon/grab) || istype(mob:r_hand, /obj/item/weapon/grab)))
|
||||
move_delay = max(move_delay, world.time + 7)
|
||||
var/list/L = mob.ret_grab()
|
||||
if(istype(L, /list))
|
||||
@@ -378,28 +364,28 @@
|
||||
else
|
||||
. = mob.SelfMove(n, direct)
|
||||
|
||||
for (var/obj/item/weapon/grab/G in mob)
|
||||
for (var/obj/item/weapon/grab/G in list(mob:l_hand, mob:r_hand))
|
||||
if (G.state == GRAB_NECK)
|
||||
mob.set_dir(reverse_dir[direct])
|
||||
G.adjust_position()
|
||||
|
||||
for (var/obj/item/weapon/grab/G in mob.grabbed_by)
|
||||
G.adjust_position()
|
||||
|
||||
moving = 0
|
||||
return .
|
||||
|
||||
return
|
||||
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved
|
||||
var/atom/O = mob.loc
|
||||
return O.relaymove(mob, direct)
|
||||
|
||||
/mob/proc/SelfMove(turf/n, direct)
|
||||
return Move(n, direct)
|
||||
|
||||
|
||||
///Process_Incorpmove
|
||||
///Called by client/Move()
|
||||
///Allows mobs to run though walls
|
||||
/client/proc/Process_Incorpmove(direct)
|
||||
var/turf/mobloc = get_turf(mob)
|
||||
|
||||
switch(mob.incorporeal_move)
|
||||
if(1)
|
||||
var/turf/T = get_step(mob, direct)
|
||||
@@ -410,44 +396,8 @@
|
||||
mob.forceMove(get_step(mob, direct))
|
||||
mob.dir = direct
|
||||
if(2)
|
||||
if(prob(50))
|
||||
var/locx
|
||||
var/locy
|
||||
switch(direct)
|
||||
if(NORTH)
|
||||
locx = mobloc.x
|
||||
locy = (mobloc.y+2)
|
||||
if(locy>world.maxy)
|
||||
return
|
||||
if(SOUTH)
|
||||
locx = mobloc.x
|
||||
locy = (mobloc.y-2)
|
||||
if(locy<1)
|
||||
return
|
||||
if(EAST)
|
||||
locy = mobloc.y
|
||||
locx = (mobloc.x+2)
|
||||
if(locx>world.maxx)
|
||||
return
|
||||
if(WEST)
|
||||
locy = mobloc.y
|
||||
locx = (mobloc.x-2)
|
||||
if(locx<1)
|
||||
return
|
||||
else
|
||||
return
|
||||
mob.forceMove(locate(locx,locy,mobloc.z))
|
||||
spawn(0)
|
||||
var/limit = 2//For only two trailing shadows.
|
||||
for(var/turf/T in getline(mobloc, mob.loc))
|
||||
spawn(0)
|
||||
anim(T,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
limit--
|
||||
if(limit<=0) break
|
||||
else
|
||||
spawn(0)
|
||||
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
mob.forceMove(get_step(mob, direct))
|
||||
anim(mobloc,mob,'icons/mob/mob.dmi',,"shadow",,mob.dir)
|
||||
mob.forceMove(get_step(mob, direct))
|
||||
mob.dir = direct
|
||||
// Crossed is always a bit iffy
|
||||
for(var/obj/S in mob.loc)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/var/obj/effect/lobby_image = new/obj/effect/lobby_image()
|
||||
/var/obj/effect/lobby_image
|
||||
|
||||
/obj/effect/lobby_image
|
||||
name = "Aurorastation"
|
||||
@@ -6,7 +6,8 @@
|
||||
icon = 'icons/misc/title.dmi'
|
||||
screen_loc = "WEST,SOUTH"
|
||||
|
||||
/obj/effect/lobby_image/initialize()
|
||||
/obj/effect/lobby_image/New()
|
||||
..()
|
||||
var/list/known_icon_states = icon_states(icon)
|
||||
for(var/lobby_screen in config.lobby_screens)
|
||||
if(!(lobby_screen in known_icon_states))
|
||||
@@ -32,7 +33,8 @@
|
||||
mind.current = src
|
||||
|
||||
loc = null
|
||||
client.screen += lobby_image
|
||||
show_title()
|
||||
|
||||
my_client = client
|
||||
sight |= SEE_TURFS
|
||||
player_list |= src
|
||||
@@ -42,3 +44,12 @@
|
||||
if(client)
|
||||
handle_privacy_poll()
|
||||
client.playtitlemusic()
|
||||
|
||||
/mob/new_player/proc/show_title()
|
||||
set waitfor = FALSE
|
||||
if (lobby_image)
|
||||
client.screen += lobby_image
|
||||
return
|
||||
|
||||
sleep(5)
|
||||
.()
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
New()
|
||||
mob_list += src
|
||||
|
||||
Destroy()
|
||||
mob_list -= src
|
||||
return ..()
|
||||
|
||||
verb/new_player_panel()
|
||||
set src = usr
|
||||
new_player_panel_proc()
|
||||
@@ -28,7 +32,7 @@
|
||||
output +="<hr>"
|
||||
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
|
||||
|
||||
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
|
||||
if(!ROUND_IS_STARTED)
|
||||
if(ready)
|
||||
output += "<p>\[ <b>Ready</b> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
|
||||
else
|
||||
@@ -67,24 +71,28 @@
|
||||
Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Lobby") && ticker)
|
||||
if(statpanel("Lobby"))
|
||||
stat("Game ID:", game_id)
|
||||
|
||||
if(ticker.hide_mode)
|
||||
if(SSticker.hide_mode)
|
||||
stat("Game Mode:", "Secret")
|
||||
else
|
||||
if(ticker.hide_mode == 0)
|
||||
if(SSticker.hide_mode == 0)
|
||||
stat("Game Mode:", "[master_mode]") // Old setting for showing the game mode
|
||||
|
||||
if(ticker.current_state == GAME_STATE_PREGAME)
|
||||
stat("Time To Start:", "[ticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
|
||||
if(SSticker.current_state == GAME_STATE_PREGAME)
|
||||
if (SSticker.lobby_ready)
|
||||
stat("Time To Start:", "[SSticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
|
||||
else
|
||||
stat("Time To Start:", "Waiting for Server")
|
||||
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
|
||||
totalPlayers = 0
|
||||
totalPlayersReady = 0
|
||||
for(var/mob/new_player/player in player_list)
|
||||
stat("[player.key]", (player.ready)?("(Playing)"):(null))
|
||||
totalPlayers++
|
||||
if(player.ready)totalPlayersReady++
|
||||
if(player.ready)
|
||||
totalPlayersReady++
|
||||
|
||||
Topic(href, href_list[])
|
||||
if(!client) return 0
|
||||
@@ -94,7 +102,7 @@
|
||||
return 1
|
||||
|
||||
if(href_list["ready"])
|
||||
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
|
||||
if(SSticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
|
||||
// Cannot join without a saved character, if we're on SQL saves.
|
||||
if (config.sql_saves && !client.prefs.current_character)
|
||||
alert(src, "You have not saved your character yet. Please do so before readying up.")
|
||||
@@ -109,6 +117,11 @@
|
||||
new_player_panel_proc()
|
||||
|
||||
if(href_list["observe"])
|
||||
if (SSatoms.initialized < INITIALIZATION_INNEW_REGULAR)
|
||||
// Don't allow players to observe until initialization is more or less complete.
|
||||
// Letting them join too early breaks things, they can wait.
|
||||
src << span("alert", "The server is still initializing, try observing again in a minute or so.")
|
||||
return
|
||||
|
||||
if(alert(src,"Are you sure you wish to observe? You will have to wait 30 minutes before being able to respawn!","Player Setup","Yes","No") == "Yes")
|
||||
if(!client) return 1
|
||||
@@ -144,7 +157,7 @@
|
||||
|
||||
if(href_list["late_join"])
|
||||
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
if(SSticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "\red The round is either not ready, or has already finished..."
|
||||
return
|
||||
|
||||
@@ -173,7 +186,7 @@
|
||||
if(!config.enter_allowed)
|
||||
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
|
||||
return
|
||||
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
|
||||
else if(SSticker.mode && SSticker.mode.explosion_in_progress)
|
||||
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
|
||||
return
|
||||
|
||||
@@ -300,7 +313,7 @@
|
||||
proc/AttemptLateSpawn(rank,var/spawning_at)
|
||||
if(src != usr)
|
||||
return 0
|
||||
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
|
||||
if(SSticker.current_state != GAME_STATE_PLAYING)
|
||||
usr << "\red The round is either not ready, or has already finished..."
|
||||
return 0
|
||||
if(!config.enter_allowed)
|
||||
@@ -338,7 +351,7 @@
|
||||
character.loc = C.loc
|
||||
|
||||
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
|
||||
ticker.mode.handle_latejoin(character)
|
||||
SSticker.mode.handle_latejoin(character)
|
||||
|
||||
qdel(C)
|
||||
qdel(src)
|
||||
@@ -353,11 +366,11 @@
|
||||
character.buckled.loc = character.loc
|
||||
character.buckled.set_dir(character.dir)
|
||||
|
||||
ticker.mode.handle_latejoin(character)
|
||||
SSticker.mode.handle_latejoin(character)
|
||||
|
||||
if(character.mind.assigned_role != "Cyborg")
|
||||
data_core.manifest_inject(character)
|
||||
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
|
||||
SSticker.minds += character.mind //Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
|
||||
|
||||
//Grab some data from the character prefs for use in random news procs.
|
||||
|
||||
@@ -368,7 +381,7 @@
|
||||
qdel(src)
|
||||
|
||||
proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
|
||||
if (ticker.current_state == GAME_STATE_PLAYING)
|
||||
if (SSticker.current_state == GAME_STATE_PLAYING)
|
||||
if(character.mind.role_alt_title)
|
||||
rank = character.mind.role_alt_title
|
||||
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
|
||||
@@ -433,7 +446,7 @@
|
||||
|| (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
|
||||
new_character.add_language(lang)
|
||||
|
||||
if(ticker.random_players)
|
||||
if(SSticker.random_players)
|
||||
new_character.gender = pick(MALE, FEMALE)
|
||||
client.prefs.real_name = random_name(new_character.gender)
|
||||
client.prefs.randomize_appearance_for(new_character)
|
||||
|
||||
Reference in New Issue
Block a user