Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into upstream-merge-33783
# Conflicts: # _maps/map_files/generic/CentCom.dmm # code/modules/mob/living/living.dm
This commit is contained in:
@@ -110,26 +110,32 @@
|
||||
anchored = TRUE
|
||||
|
||||
/obj/effect/shuttle_build/New()
|
||||
SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
|
||||
SSshuttle.emergency.initiate_docking(SSshuttle.getDock("emergency_home"))
|
||||
qdel(src)
|
||||
|
||||
//Arena
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle
|
||||
name = "portal"
|
||||
var/list/warp_points = list()
|
||||
var/list/warp_points
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle/Initialize()
|
||||
. = ..()
|
||||
warp_points = get_area_turfs(/area/shuttle/escape)
|
||||
for(var/thing in warp_points)
|
||||
CHECK_TICK
|
||||
var/turf/T = thing
|
||||
if(istype(T.loc, /area/shuttle/escape/backup))
|
||||
warp_points -= T
|
||||
continue
|
||||
for(var/atom/movable/TAM in T)
|
||||
if(TAM.density && TAM.anchored)
|
||||
warp_points -= T
|
||||
break
|
||||
|
||||
/obj/effect/forcefield/arena_shuttle/CollidedWith(atom/movable/AM)
|
||||
if(!isliving(AM))
|
||||
return
|
||||
if(!warp_points.len)
|
||||
warp_points = get_area_turfs(/area/shuttle/escape)
|
||||
for(var/turf/T in warp_points)
|
||||
for(var/atom/movable/TAM in T)
|
||||
if(TAM.density && TAM.anchored)
|
||||
warp_points -= T
|
||||
break
|
||||
|
||||
var/mob/living/L = AM
|
||||
if(L.pulling && istype(L.pulling, /obj/item/bodypart/head))
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
triggering = TRUE
|
||||
if (alertadmins)
|
||||
message_admins("Random Event triggering in 10 seconds: [name] ([typepath]) (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
|
||||
message_admins("Random Event triggering in 10 seconds: [name] (<a href='?src=[REF(src)];cancel=1'>CANCEL</a>)")
|
||||
sleep(100)
|
||||
var/gamemode = SSticker.mode.config_tag
|
||||
var/players_amt = get_active_player_count(alive_check = TRUE, afk_check = TRUE, human_check = TRUE)
|
||||
|
||||
@@ -1,27 +1,3 @@
|
||||
//this is an example of a possible round-start event
|
||||
/datum/round_event_control/presents
|
||||
name = "Presents under Trees (Christmas)"
|
||||
holidayID = CHRISTMAS
|
||||
typepath = /datum/round_event/presents
|
||||
weight = -1 //forces it to be called, regardless of weight
|
||||
max_occurrences = 1
|
||||
earliest_start = 0
|
||||
|
||||
/datum/round_event/presents/start()
|
||||
for(var/obj/structure/flora/tree/pine/xmas/xmas in world)
|
||||
if(!(xmas.z in GLOB.station_z_levels))
|
||||
continue
|
||||
xmas.icon_state = "pinepresents"
|
||||
xmas.gifts_under_tree = TRUE
|
||||
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
|
||||
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
|
||||
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
|
||||
Monitor.icon_state = "entertainment_xmas"
|
||||
|
||||
/datum/round_event/presents/announce(fake)
|
||||
priority_announce("Ho Ho Ho, Merry Xmas!", "Unknown Transmission")
|
||||
|
||||
|
||||
/obj/item/toy/xmas_cracker
|
||||
name = "xmas cracker"
|
||||
icon = 'icons/obj/christmas.dmi'
|
||||
@@ -65,17 +41,21 @@
|
||||
|
||||
/obj/effect/landmark/xmastree
|
||||
name = "christmas tree spawner"
|
||||
var/tree = /obj/structure/flora/tree/pine/xmas
|
||||
var/festive_tree = /obj/structure/flora/tree/pine/xmas
|
||||
var/christmas_tree = /obj/structure/flora/tree/pine/xmas/presents
|
||||
|
||||
/obj/effect/landmark/xmastree/Initialize(mapload)
|
||||
..()
|
||||
if(FESTIVE_SEASON in SSevents.holidays)
|
||||
new tree(get_turf(src))
|
||||
if((CHRISTMAS in SSevents.holidays) && christmas_tree)
|
||||
new christmas_tree(get_turf(src))
|
||||
else if((FESTIVE_SEASON in SSevents.holidays) && festive_tree)
|
||||
new festive_tree(get_turf(src))
|
||||
return INITIALIZE_HINT_QDEL
|
||||
|
||||
/obj/effect/landmark/xmastree/rdrod
|
||||
name = "festivus pole spawner"
|
||||
tree = /obj/structure/festivus
|
||||
festive_tree = /obj/structure/festivus
|
||||
christmas_tree = null
|
||||
|
||||
/datum/round_event_control/santa
|
||||
name = "Santa is coming to town! (Christmas)"
|
||||
@@ -92,7 +72,7 @@
|
||||
priority_announce("Santa is coming to town!", "Unknown Transmission")
|
||||
|
||||
/datum/round_event/santa/start()
|
||||
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be santa?", poll_time=150)
|
||||
var/list/candidates = pollGhostCandidates("Santa is coming to town! Do you want to be Santa?", poll_time=150)
|
||||
if(LAZYLEN(candidates))
|
||||
var/mob/dead/observer/Z = pick(candidates)
|
||||
santa = new /mob/living/carbon/human(pick(GLOB.blobstart))
|
||||
|
||||
@@ -206,7 +206,7 @@
|
||||
if(engines_cooling)
|
||||
return "[.] - Engines cooling."
|
||||
|
||||
/obj/docking_port/mobile/pirate/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
/obj/docking_port/mobile/pirate/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
. = ..()
|
||||
if(. == DOCKING_SUCCESS && new_dock.z != ZLEVEL_TRANSIT)
|
||||
engines_cooling = TRUE
|
||||
|
||||
@@ -714,6 +714,8 @@ GLOBAL_LIST_INIT(hallucinations_major, list(
|
||||
for(var/obj/machinery/door/airlock/A in range(7, target))
|
||||
if(count>door_number && door_number>0)
|
||||
break
|
||||
if(!A.density)
|
||||
continue
|
||||
count++
|
||||
I = image(A.overlays_file, get_turf(A), "lights_bolts",layer=A.layer+0.1)
|
||||
doors += I
|
||||
|
||||
@@ -394,6 +394,17 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
/datum/holiday/xmas/greet()
|
||||
return "Have a merry Christmas!"
|
||||
|
||||
/datum/holiday/xmas/celebrate()
|
||||
SSticker.OnRoundstart(CALLBACK(src, .proc/roundstart_celebrate))
|
||||
|
||||
/datum/holiday/xmas/proc/roundstart_celebrate()
|
||||
for(var/obj/machinery/computer/security/telescreen/entertainment/Monitor in GLOB.machines)
|
||||
Monitor.icon_state = "entertainment_xmas"
|
||||
|
||||
for(var/mob/living/simple_animal/pet/dog/corgi/Ian/Ian in GLOB.mob_living_list)
|
||||
Ian.place_on_head(new /obj/item/clothing/head/helmet/space/santahat(Ian))
|
||||
|
||||
|
||||
/datum/holiday/festive_season
|
||||
name = FESTIVE_SEASON
|
||||
begin_day = 1
|
||||
|
||||
@@ -471,7 +471,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set hidden = TRUE
|
||||
var/max_view = client.prefs.unlock_content ? GHOST_MAX_VIEW_RANGE_MEMBER : GHOST_MAX_VIEW_RANGE_DEFAULT
|
||||
if(input)
|
||||
client.rescale_view(input, 7, max_view)
|
||||
client.rescale_view(input, 15, (max_view*2)+1)
|
||||
|
||||
/mob/dead/observer/verb/boo()
|
||||
set category = "Ghost"
|
||||
|
||||
@@ -195,8 +195,10 @@
|
||||
var/trauma_type
|
||||
if(ispath(trauma))
|
||||
trauma_type = trauma
|
||||
SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
|
||||
traumas += new trauma_type(arglist(list(src, permanent) + arguments))
|
||||
else
|
||||
SSblackbox.record_feedback("tally", "traumas", 1, trauma.type)
|
||||
traumas += trauma
|
||||
trauma.permanent = permanent
|
||||
|
||||
@@ -209,6 +211,7 @@
|
||||
possible_traumas += BT
|
||||
|
||||
var/trauma_type = pick(possible_traumas)
|
||||
SSblackbox.record_feedback("tally", "traumas", 1, trauma_type)
|
||||
traumas += new trauma_type(src, permanent)
|
||||
|
||||
//Cure a random trauma of a certain subtype
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
//Generic system for picking up mobs.
|
||||
//Currently works for head and hands.
|
||||
/obj/item/clothing/head/mob_holder
|
||||
name = "bugged mob"
|
||||
desc = "Yell at coderbrush."
|
||||
icon = null
|
||||
icon_state = ""
|
||||
flags_1 = DROPDEL_1
|
||||
var/mob/living/held_mob
|
||||
var/can_head = TRUE
|
||||
var/destroying = FALSE
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Initialize(mapload, mob/living/M, _worn_state, head_icon, lh_icon, rh_icon, _can_head = TRUE)
|
||||
. = ..()
|
||||
can_head = _can_head
|
||||
if(head_icon)
|
||||
alternate_worn_icon = head_icon
|
||||
if(_worn_state)
|
||||
item_state = _worn_state
|
||||
if(lh_icon)
|
||||
lefthand_file = lh_icon
|
||||
if(rh_icon)
|
||||
righthand_file = rh_icon
|
||||
if(!can_head)
|
||||
slot_flags = NONE
|
||||
deposit(M)
|
||||
|
||||
/obj/item/clothing/head/mob_holder/Destroy()
|
||||
destroying = TRUE
|
||||
if(held_mob)
|
||||
release(FALSE)
|
||||
return ..()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/deposit(mob/living/L)
|
||||
if(!istype(L))
|
||||
return FALSE
|
||||
L.setDir(SOUTH)
|
||||
update_visuals(L)
|
||||
held_mob = L
|
||||
L.forceMove(src)
|
||||
name = L.name
|
||||
desc = L.desc
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/update_visuals(mob/living/L)
|
||||
appearance = L.appearance
|
||||
|
||||
/obj/item/clothing/head/mob_holder/proc/release(del_on_release = TRUE)
|
||||
if(!held_mob)
|
||||
if(del_on_release && !destroying)
|
||||
qdel(src)
|
||||
return FALSE
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='warning'>[held_mob] wriggles free!</span>")
|
||||
L.dropItemToGround(src)
|
||||
held_mob.forceMove(get_turf(src))
|
||||
held_mob.reset_perspective()
|
||||
held_mob.setDir(SOUTH)
|
||||
held_mob.visible_message("<span class='warning'>[held_mob] uncurls!</span>")
|
||||
held_mob = null
|
||||
if(del_on_release && !destroying)
|
||||
qdel(src)
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/head/mob_holder/relaymove()
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/container_resist()
|
||||
release()
|
||||
|
||||
/obj/item/clothing/head/mob_holder/drone/deposit(mob/living/L)
|
||||
. = ..()
|
||||
if(!isdrone(L))
|
||||
qdel(src)
|
||||
name = "drone (hiding)"
|
||||
desc = "This drone is scared and has curled up into a ball!"
|
||||
|
||||
/obj/item/clothing/head/mob_holder/drone/update_visuals(mob/living/L)
|
||||
var/mob/living/simple_animal/drone/D = L
|
||||
if(!D)
|
||||
return ..()
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "[D.visualAppearence]_hat"
|
||||
@@ -1064,4 +1064,32 @@
|
||||
|
||||
/mob/living/onTransitZ(old_z,new_z)
|
||||
..()
|
||||
update_z(new_z)
|
||||
update_z(new_z)
|
||||
|
||||
/mob/living/MouseDrop(mob/over)
|
||||
. = ..()
|
||||
var/mob/living/user = usr
|
||||
if(!istype(over) || !istype(user))
|
||||
return
|
||||
if(!over.Adjacent(src) || (user != src) || !canUseTopic(over))
|
||||
return
|
||||
if(can_be_held)
|
||||
mob_try_pickup(over)
|
||||
|
||||
/mob/living/proc/mob_pickup(mob/living/L)
|
||||
return
|
||||
|
||||
/mob/living/proc/mob_try_pickup(mob/living/user)
|
||||
if(!ishuman(user))
|
||||
return
|
||||
if(user.get_active_held_item())
|
||||
to_chat(user, "<span class='warning'>Your hands are full!</span>")
|
||||
return FALSE
|
||||
if(buckled)
|
||||
to_chat(user, "<span class='warning'>[src] is buckled to something!</span>")
|
||||
return FALSE
|
||||
user.visible_message("<span class='notice'>[user] starts trying to scoop up [src]!</span>")
|
||||
if(!do_after(user, 20, target = src))
|
||||
return FALSE
|
||||
mob_pickup(user)
|
||||
return TRUE
|
||||
|
||||
@@ -79,4 +79,5 @@
|
||||
|
||||
var/list/obj/effect/proc_holder/abilities = list()
|
||||
|
||||
var/registered_z
|
||||
var/registered_z
|
||||
var/can_be_held = FALSE //whether this can be picked up and held.
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
health = 500
|
||||
maxHealth = 500
|
||||
layer = BELOW_MOB_LAYER
|
||||
can_be_held = TRUE
|
||||
|
||||
var/network = "SS13"
|
||||
var/obj/machinery/camera/current = null
|
||||
@@ -57,7 +58,10 @@
|
||||
var/canholo = TRUE
|
||||
var/obj/item/card/id/access_card = null
|
||||
var/chassis = "repairbot"
|
||||
var/list/possible_chassis = list("cat", "mouse", "monkey", "corgi", "fox", "repairbot", "rabbit")
|
||||
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE) //assoc value is whether it can be picked up.
|
||||
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
|
||||
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
|
||||
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
|
||||
|
||||
var/emitterhealth = 20
|
||||
var/emittermaxhealth = 20
|
||||
|
||||
@@ -68,9 +68,12 @@
|
||||
lay_down()
|
||||
|
||||
/mob/living/silicon/pai/proc/choose_chassis()
|
||||
if(!isturf(loc) && loc != card)
|
||||
to_chat(src, "<span class='boldwarning'>You can not change your holochassis composite while not on the ground or in your card!</span>")
|
||||
return FALSE
|
||||
var/choice = input(src, "What would you like to use for your holochassis composite?") as null|anything in possible_chassis
|
||||
if(!choice)
|
||||
return 0
|
||||
return FALSE
|
||||
chassis = choice
|
||||
icon_state = "[chassis]"
|
||||
if(resting)
|
||||
@@ -103,3 +106,16 @@
|
||||
/mob/living/silicon/pai/movement_delay()
|
||||
. = ..()
|
||||
. += 1 //A bit slower than humans, so they're easier to smash
|
||||
|
||||
/mob/living/silicon/pai/mob_pickup(mob/living/L)
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, chassis, item_head_icon, item_lh_icon, item_rh_icon)
|
||||
if(!L.put_in_hands(holder))
|
||||
qdel(holder)
|
||||
else
|
||||
L.visible_message("<span class='warning'>[L] scoops up [src]!</span>")
|
||||
|
||||
/mob/living/silicon/pai/mob_try_pickup(mob/living/user)
|
||||
if(!possible_chassis[chassis])
|
||||
to_chat(user, "<span class='wraning'>[src]'s current form isn't able to be carried!</span>")
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -205,15 +205,14 @@
|
||||
"Medical" = /obj/item/robot_module/medical, \
|
||||
"Miner" = /obj/item/robot_module/miner, \
|
||||
"Janitor" = /obj/item/robot_module/janitor, \
|
||||
"Service" = /obj/item/robot_module/butler, \
|
||||
"MediHound" = /obj/item/robot_module/medihound, \
|
||||
"Security K9" = /obj/item/robot_module/k9, \
|
||||
"Scrub Puppy" = /obj/item/robot_module/scrubpup)
|
||||
"Service" = /obj/item/robot_module/butler)
|
||||
if(!CONFIG_GET(flag/disable_peaceborg))
|
||||
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
|
||||
if(!CONFIG_GET(flag/disable_secborg))
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
|
||||
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
|
||||
if(!input_module || module.type != /obj/item/robot_module)
|
||||
return
|
||||
@@ -593,39 +592,25 @@
|
||||
/mob/living/silicon/robot/update_icons()
|
||||
cut_overlays()
|
||||
icon_state = module.cyborg_base_icon
|
||||
if(module.cyborg_base_icon == "medihound")
|
||||
icon = 'icons/mob/widerobot.dmi'
|
||||
pixel_x = -16
|
||||
if(sleeper_g == 1)
|
||||
add_overlay("msleeper_g")
|
||||
if(sleeper_r == 1)
|
||||
add_overlay("msleeper_r")
|
||||
if(stat == DEAD)
|
||||
icon_state = "medihound-wreck"
|
||||
|
||||
if(module.cyborg_base_icon == "k9")
|
||||
icon = 'icons/mob/widerobot.dmi'
|
||||
pixel_x = -16
|
||||
if(laser == 1)
|
||||
add_overlay("laser")
|
||||
if(disabler == 1)
|
||||
add_overlay("disabler")
|
||||
if(sleeper_g == 1)
|
||||
add_overlay("ksleeper_g")
|
||||
if(sleeper_r == 1)
|
||||
add_overlay("ksleeper_r")
|
||||
if(stat == DEAD)
|
||||
icon_state = "k9-wreck"
|
||||
//Citadel changes start here - Allows modules to use different icon files, and allows modules to specify a pixel offset
|
||||
icon = (module.cyborg_icon_override ? module.cyborg_icon_override : initial(icon))
|
||||
|
||||
if(module.cyborg_base_icon == "scrubpup")
|
||||
icon = 'icons/mob/widerobot.dmi'
|
||||
pixel_x = -16
|
||||
if(sleeper_g == 1)
|
||||
add_overlay("jsleeper_g")
|
||||
if(sleeper_r == 1)
|
||||
add_overlay("jsleeper_r")
|
||||
if(stat == DEAD)
|
||||
icon_state = "scrubpup-wreck"
|
||||
if(laser)
|
||||
add_overlay("laser")//Is this even used???
|
||||
if(disabler)
|
||||
add_overlay("disabler")//ditto
|
||||
|
||||
if(sleeper_g && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_g")
|
||||
if(sleeper_r && module.sleeper_overlay)
|
||||
add_overlay("[module.sleeper_overlay]_r")
|
||||
if(stat == DEAD && module.has_snowflake_deadsprite)
|
||||
icon_state = "[module.cyborg_base_icon]-wreck"
|
||||
|
||||
if(module.cyborg_pixel_offset)
|
||||
pixel_x = module.cyborg_pixel_offset
|
||||
//End of citadel changes
|
||||
|
||||
if(module.cyborg_base_icon == "robot")
|
||||
icon = 'icons/mob/robots.dmi'
|
||||
@@ -1023,6 +1008,7 @@
|
||||
designation = module.name
|
||||
if(hands)
|
||||
hands.icon_state = module.moduleselect_icon
|
||||
hands.icon = (module.moduleselect_alternate_icon ? module.moduleselect_alternate_icon : initial(hands.icon)) //CITADEL CHANGE - allows module select icons to use a different icon file
|
||||
if(module.can_be_pushed)
|
||||
status_flags |= CANPUSH
|
||||
else
|
||||
|
||||
@@ -336,31 +336,6 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/robot_module/k9
|
||||
name = "Security K-9 Unit module"
|
||||
basic_modules = list(
|
||||
/obj/item/restraints/handcuffs/cable/zipties/cyborg/dog,
|
||||
/obj/item/dogborg/jaws/big,
|
||||
/obj/item/dogborg/pounce,
|
||||
/obj/item/clothing/mask/gas/sechailer/cyborg,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/device/dogborg/sleeper/K9,
|
||||
/obj/item/gun/energy/disabler/cyborg,
|
||||
/obj/item/pinpointer/crew)
|
||||
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
|
||||
/obj/item/clockwork/weapon/ratvarian_spear)
|
||||
cyborg_base_icon = "k9"
|
||||
moduleselect_icon = "security"
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
|
||||
/obj/item/robot_module/k9/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc,"<span class='userdanger'>While you have picked the security-k9 module, you still have to follow your laws, NOT Space Law. \
|
||||
For Asimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
|
||||
|
||||
/obj/item/robot_module/security/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/gun/energy/e_gun/advtaser/cyborg/T = locate(/obj/item/gun/energy/e_gun/advtaser/cyborg) in basic_modules
|
||||
@@ -372,59 +347,6 @@
|
||||
else
|
||||
T.charge_tick = 0
|
||||
|
||||
/obj/item/robot_module/medihound
|
||||
name = "MediHound module"
|
||||
basic_modules = list(
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/device/healthanalyzer,
|
||||
/obj/item/device/dogborg/sleeper/medihound,
|
||||
/obj/item/twohanded/shockpaddles/hound,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/device/sensor_device)
|
||||
emag_modules = list(/obj/item/dogborg/pounce)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
|
||||
/obj/item/clockwork/weapon/ratvarian_spear)
|
||||
cyborg_base_icon = "medihound"
|
||||
moduleselect_icon = "medical"
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
|
||||
/obj/item/robot_module/medihound/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
|
||||
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
|
||||
|
||||
/obj/item/robot_module/scrubpup
|
||||
name = "Janitor"
|
||||
basic_modules = list(
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/device/analyzer/nose,
|
||||
/obj/item/soap/tongue/scrubpup,
|
||||
/obj/item/device/lightreplacer/cyborg,
|
||||
/obj/item/device/dogborg/sleeper/compactor)
|
||||
emag_modules = list(/obj/item/dogborg/pounce)
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/janitor,
|
||||
/obj/item/clockwork/replica_fabricator/cyborg)
|
||||
cyborg_base_icon = "scrubpup"
|
||||
moduleselect_icon = "janitor"
|
||||
hat_offset = INFINITY
|
||||
clean_on_move = TRUE
|
||||
|
||||
/obj/item/robot_module/scrubpup/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/device/lightreplacer/LR = locate(/obj/item/device/lightreplacer) in basic_modules
|
||||
if(LR)
|
||||
for(var/i in 1 to coeff)
|
||||
LR.Charge(R)
|
||||
|
||||
/obj/item/robot_module/scrubpup/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc,"<span class='userdanger'>As tempting as it might be, do not begin binging on important items. Eat your garbage responsibly. People are not included under Garbage.</span>")
|
||||
|
||||
|
||||
/obj/item/robot_module/security/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/obj/item/inventory_back
|
||||
var/nofur = 0 //Corgis that have risen past the material plane of existence.
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
can_be_held = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/dog/pug
|
||||
name = "\improper pug"
|
||||
@@ -121,7 +122,12 @@
|
||||
..()
|
||||
update_corgi_fluff()
|
||||
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/mob_pickup(mob/living/L)
|
||||
var/obj/item/clothing/head/mob_holder/holder = new(get_turf(src), src, "corgi", null, 'icons/mob/pets_held_lh.dmi', 'icons/mob/pets_held_rh.dmi', FALSE)
|
||||
if(!L.put_in_hands(holder))
|
||||
qdel(holder)
|
||||
else
|
||||
L.visible_message("<span class='warning'>[L] scoops up [src]!</span>")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
|
||||
if(usr.stat)
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
dextrous = TRUE
|
||||
dextrous_hud_type = /datum/hud/dextrous/drone
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
can_be_held = TRUE
|
||||
var/staticChoice = "static"
|
||||
var/list/staticChoices = list("static", "blank", "letter", "animal")
|
||||
var/picked = FALSE //Have we picked our visual appearence (+ colour if applicable)
|
||||
@@ -67,7 +68,6 @@
|
||||
var/seeStatic = 1 //Whether we see static instead of mobs
|
||||
var/visualAppearence = MAINTDRONE //What we appear as
|
||||
var/hacked = FALSE //If we have laws to destroy the station
|
||||
var/can_be_held = TRUE //if assholes can pick us up
|
||||
var/flavortext = \
|
||||
"\n<big><span class='warning'>DO NOT INTERFERE WITH THE ROUND AS A DRONE OR YOU WILL BE DRONE BANNED</span></big>\n"+\
|
||||
"<span class='notify'>Drones are a ghost role that are allowed to fix the station and build things. Interfering with the round as a drone is against the rules.</span>\n"+\
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
//DRONES AS ITEMS//
|
||||
///////////////////
|
||||
//Drone shells
|
||||
//Drones as hats
|
||||
|
||||
|
||||
//DRONE SHELL
|
||||
/obj/item/drone_shell
|
||||
@@ -45,45 +43,3 @@
|
||||
D.admin_spawned = admin_spawned
|
||||
D.key = user.key
|
||||
qdel(src)
|
||||
|
||||
|
||||
//DRONE HOLDER
|
||||
/obj/item/clothing/head/drone_holder//Only exists in someones hand.or on their head
|
||||
name = "drone (hiding)"
|
||||
desc = "This drone is scared and has curled up into a ball."
|
||||
icon = 'icons/mob/drone.dmi'
|
||||
icon_state = "drone_maint_hat"
|
||||
var/mob/living/simple_animal/drone/drone //stored drone
|
||||
|
||||
/obj/item/clothing/head/drone_holder/proc/uncurl()
|
||||
if(!drone)
|
||||
return
|
||||
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='warning'>[drone] is trying to escape!</span>")
|
||||
if(!do_after(drone, 50, target = L))
|
||||
return
|
||||
L.dropItemToGround(src)
|
||||
|
||||
contents -= drone
|
||||
drone.forceMove(drop_location())
|
||||
drone.reset_perspective()
|
||||
drone.setDir(SOUTH )//Looks better
|
||||
drone.visible_message("<span class='warning'>[drone] uncurls!</span>")
|
||||
drone = null
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/clothing/head/drone_holder/relaymove()
|
||||
uncurl()
|
||||
|
||||
/obj/item/clothing/head/drone_holder/container_resist(mob/living/user)
|
||||
uncurl()
|
||||
|
||||
|
||||
/obj/item/clothing/head/drone_holder/proc/updateVisualAppearence(mob/living/simple_animal/drone/D)
|
||||
if(!D)
|
||||
return
|
||||
icon_state = "[D.visualAppearence]_hat"
|
||||
. = icon_state
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
if("Nothing")
|
||||
return
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/attack_hand(mob/user)
|
||||
if(ishuman(user))
|
||||
if(stat == DEAD || status_flags & GODMODE || !can_be_held)
|
||||
@@ -49,11 +48,8 @@
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You pick [src] up.</span>")
|
||||
drop_all_held_items()
|
||||
var/obj/item/clothing/head/drone_holder/DH = new /obj/item/clothing/head/drone_holder(src)
|
||||
DH.updateVisualAppearence(src)
|
||||
DH.drone = src
|
||||
var/obj/item/clothing/head/mob_holder/drone/DH = new(get_turf(src), src)
|
||||
user.put_in_hands(DH)
|
||||
forceMove(DH)
|
||||
|
||||
/mob/living/simple_animal/drone/proc/try_reactivate(mob/living/user)
|
||||
var/mob/dead/observer/G = get_ghost()
|
||||
|
||||
@@ -260,13 +260,13 @@
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
client.eye = A
|
||||
else
|
||||
if(isturf(loc))
|
||||
if(isturf(loc) && (!A || loc == A))
|
||||
client.eye = client.mob
|
||||
client.perspective = MOB_PERSPECTIVE
|
||||
else
|
||||
client.perspective = EYE_PERSPECTIVE
|
||||
client.eye = loc
|
||||
return 1
|
||||
client.eye = A
|
||||
return 1
|
||||
|
||||
/mob/living/reset_perspective(atom/A)
|
||||
if(..())
|
||||
@@ -362,7 +362,7 @@
|
||||
|
||||
add_logs(src, M, "grabbed", addition="passive grab")
|
||||
if(!supress_message)
|
||||
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
|
||||
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!</span>")
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
if(beaker && beaker.reagents)
|
||||
beaker.reagents.remove_all()
|
||||
cell.use(total/powerefficiency)
|
||||
cell.emp_act()
|
||||
cell.emp_act(severity)
|
||||
visible_message("<span class='danger'>[src] malfunctions, spraying chemicals everywhere!</span>")
|
||||
..()
|
||||
|
||||
@@ -400,4 +400,4 @@
|
||||
"cryoxadone",
|
||||
"ammonia",
|
||||
"ash",
|
||||
"diethylamine")
|
||||
"diethylamine")
|
||||
|
||||
@@ -664,9 +664,9 @@
|
||||
|
||||
/obj/item/relic/proc/teleport(mob/user)
|
||||
to_chat(user, "<span class='notice'>[src] begins to vibrate!</span>")
|
||||
addtimer(CALLBACK(src, .proc/do_teleport, user), rand(10, 30))
|
||||
addtimer(CALLBACK(src, .proc/do_the_teleport, user), rand(10, 30))
|
||||
|
||||
/obj/item/relic/proc/do_teleport(mob/user)
|
||||
/obj/item/relic/proc/do_the_teleport(mob/user)
|
||||
var/turf/userturf = get_turf(user)
|
||||
if(loc == user && userturf.z != ZLEVEL_CENTCOM) //Because Nuke Ops bringing this back on their shuttle, then looting the ERT area is 2fun4you!
|
||||
visible_message("<span class='notice'>[src] twists and bends, relocating itself!</span>")
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
hyperspace_sound(HYPERSPACE_LAUNCH, areas) //for the new guy
|
||||
setTimer(dockTime)
|
||||
|
||||
/obj/docking_port/mobile/arrivals/dock(obj/docking_port/stationary/S1, force=FALSE)
|
||||
/obj/docking_port/mobile/arrivals/initiate_docking(obj/docking_port/stationary/S1, force=FALSE)
|
||||
var/docked = S1 == assigned_transit
|
||||
sound_played = FALSE
|
||||
if(docked) //about to launch
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/docking_port/mobile/assault_pod/dock(obj/docking_port/stationary/S1)
|
||||
/obj/docking_port/mobile/assault_pod/initiate_docking(obj/docking_port/stationary/S1)
|
||||
. = ..()
|
||||
if(!istype(S1, /obj/docking_port/stationary/transit))
|
||||
playsound(get_turf(src.loc), 'sound/effects/explosion1.ogg',50,1)
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port new_dock
|
||||
/obj/docking_port/mobile/proc/initiate_docking(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
// Crashing this ship with NO SURVIVORS
|
||||
|
||||
if(new_dock.get_docked() == src)
|
||||
remove_ripples()
|
||||
return DOCKING_SUCCESS
|
||||
|
||||
if(!force)
|
||||
if(!check_dock(new_dock))
|
||||
return DOCKING_BLOCKED
|
||||
if(!canMove())
|
||||
return DOCKING_IMMOBILIZED
|
||||
|
||||
var/obj/docking_port/stationary/old_dock = get_docked()
|
||||
|
||||
// The turf that gets placed under where the shuttle moved from
|
||||
var/underlying_turf_type = SHUTTLE_DEFAULT_TURF_TYPE
|
||||
|
||||
// The baseturf that the gets assigned to the turf_type above
|
||||
var/underlying_baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
|
||||
|
||||
// The area that gets placed under where the shuttle moved from
|
||||
var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
|
||||
|
||||
// The baseturf cache is a typecache of what counts as a baseturf to be left behind
|
||||
var/list/baseturf_cache
|
||||
|
||||
if(old_dock) //Dock overwrites
|
||||
underlying_turf_type = old_dock.turf_type
|
||||
underlying_baseturf_type = old_dock.baseturf_type
|
||||
underlying_area_type = old_dock.area_type
|
||||
baseturf_cache = old_dock.baseturf_cache
|
||||
else
|
||||
baseturf_cache = typecacheof(underlying_baseturf_type)
|
||||
|
||||
/**************************************************************************************************************
|
||||
Both lists are associative with a turf:bitflag structure. (new_turfs bitflag space unused currently)
|
||||
The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
|
||||
The bitflags can be found in __DEFINES/shuttles.dm
|
||||
*/
|
||||
var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
|
||||
var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
|
||||
CHECK_TICK
|
||||
/**************************************************************************************************************/
|
||||
|
||||
// The underlying old area is the area assumed to be under the shuttle's starting location
|
||||
// If it no longer/has never existed it will be created
|
||||
var/area/underlying_old_area = locate(underlying_area_type) in GLOB.sortedAreas
|
||||
if(!underlying_old_area)
|
||||
underlying_old_area = new underlying_area_type(null)
|
||||
|
||||
var/rotation = 0
|
||||
if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
|
||||
rotation = dir2angle(new_dock.dir)-dir2angle(dir)
|
||||
if ((rotation % 90) != 0)
|
||||
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
||||
rotation = SIMPLIFY_DEGREES(rotation)
|
||||
|
||||
if(!movement_direction)
|
||||
movement_direction = turn(preferred_direction, 180)
|
||||
|
||||
var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
|
||||
var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
|
||||
|
||||
remove_ripples()
|
||||
|
||||
. = preflight_check(old_turfs, new_turfs, areas_to_move, rotation, underlying_turf_type, baseturf_cache)
|
||||
if(.)
|
||||
return
|
||||
|
||||
/*******************************************Hiding turfs if necessary*******************************************/
|
||||
// TODO: Move this somewhere sane
|
||||
var/list/new_hidden_turfs
|
||||
if(hidden)
|
||||
new_hidden_turfs = list()
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
var/turf/oldT = old_turfs[i]
|
||||
if(old_turfs[oldT] & MOVE_TURF)
|
||||
new_hidden_turfs += new_turfs[i]
|
||||
SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
|
||||
/***************************************************************************************************************/
|
||||
|
||||
if(!force)
|
||||
if(!check_dock(new_dock))
|
||||
return DOCKING_BLOCKED
|
||||
if(!canMove())
|
||||
return DOCKING_IMMOBILIZED
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
takeoff(old_turfs, new_turfs, moved_atoms, rotation, movement_direction, old_dock, underlying_old_area)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
cleanup_runway(new_dock, old_turfs, new_turfs, areas_to_move, moved_atoms, rotation, movement_direction, underlying_old_area, underlying_turf_type, underlying_baseturf_type)
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
/*******************************************Unhiding turfs if necessary******************************************/
|
||||
if(new_hidden_turfs)
|
||||
SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
|
||||
hidden_turfs = new_hidden_turfs
|
||||
/****************************************************************************************************************/
|
||||
|
||||
check_poddoors()
|
||||
new_dock.last_dock_time = world.time
|
||||
setDir(new_dock.dir)
|
||||
|
||||
return DOCKING_SUCCESS
|
||||
|
||||
/obj/docking_port/mobile/proc/preflight_check(
|
||||
list/old_turfs,
|
||||
list/new_turfs,
|
||||
list/areas_to_move,
|
||||
rotation,
|
||||
underlying_turf_type,
|
||||
baseturf_cache,
|
||||
)
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
if(!newT)
|
||||
return DOCKING_NULL_DESTINATION
|
||||
if(!oldT)
|
||||
return DOCKING_NULL_SOURCE
|
||||
|
||||
var/area/old_area = oldT.loc
|
||||
var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
|
||||
|
||||
var/list/old_contents = oldT.contents
|
||||
for(var/k in 1 to old_contents.len)
|
||||
CHECK_TICK
|
||||
var/atom/movable/moving_atom = old_contents[k]
|
||||
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
||||
continue
|
||||
move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms
|
||||
|
||||
move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs
|
||||
move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs
|
||||
|
||||
if(move_mode & MOVE_AREA)
|
||||
areas_to_move[old_area] = TRUE
|
||||
|
||||
old_turfs[oldT] = move_mode
|
||||
|
||||
/obj/docking_port/mobile/proc/takeoff(
|
||||
list/old_turfs,
|
||||
list/new_turfs,
|
||||
list/moved_atoms,
|
||||
rotation,
|
||||
movement_direction,
|
||||
old_dock,
|
||||
area/underlying_old_area,
|
||||
)
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
var/move_mode = old_turfs[oldT]
|
||||
if(move_mode & MOVE_CONTENTS)
|
||||
for(var/k in oldT)
|
||||
var/atom/movable/moving_atom = k
|
||||
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
||||
continue
|
||||
moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
|
||||
moved_atoms[moving_atom] = oldT
|
||||
|
||||
if(move_mode & MOVE_TURF)
|
||||
oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
|
||||
|
||||
if(move_mode & MOVE_AREA)
|
||||
var/area/shuttle_area = oldT.loc
|
||||
shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
|
||||
|
||||
/obj/docking_port/mobile/proc/cleanup_runway(
|
||||
obj/docking_port/stationary/new_dock,
|
||||
list/old_turfs,
|
||||
list/new_turfs,
|
||||
list/areas_to_move,
|
||||
list/moved_atoms,
|
||||
rotation,
|
||||
movement_direction,
|
||||
area/underlying_old_area,
|
||||
underlying_turf_type,
|
||||
underlying_baseturf_type,
|
||||
)
|
||||
|
||||
underlying_old_area.afterShuttleMove()
|
||||
|
||||
// Parallax handling
|
||||
// This needs to be done before the atom after move
|
||||
var/new_parallax_dir = FALSE
|
||||
if(istype(new_dock, /obj/docking_port/stationary/transit))
|
||||
new_parallax_dir = preferred_direction
|
||||
for(var/i in 1 to areas_to_move.len)
|
||||
CHECK_TICK
|
||||
var/area/internal_area = areas_to_move[i]
|
||||
internal_area.afterShuttleMove(new_parallax_dir) //areas
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
|
||||
continue
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs
|
||||
|
||||
for(var/i in 1 to moved_atoms.len)
|
||||
CHECK_TICK
|
||||
var/atom/movable/moved_object = moved_atoms[i]
|
||||
if(QDELETED(moved_object))
|
||||
continue
|
||||
var/turf/oldT = moved_atoms[moved_object]
|
||||
moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation)//atoms
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
// Objects can block air so either turf or content changes means an air update is needed
|
||||
if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
|
||||
continue
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
oldT.blocks_air = initial(oldT.blocks_air)
|
||||
oldT.air_update_turf(TRUE)
|
||||
newT.blocks_air = initial(newT.blocks_air)
|
||||
newT.air_update_turf(TRUE)
|
||||
@@ -7,4 +7,4 @@
|
||||
movement_force = list("KNOCKDOWN" = 0, "THROW" = 0)
|
||||
|
||||
/obj/docking_port/mobile/elevator/request(obj/docking_port/stationary/S) //No transit, no ignition, just a simple up/down platform
|
||||
dock(S, TRUE)
|
||||
initiate_docking(S, TRUE)
|
||||
@@ -290,7 +290,7 @@
|
||||
if(SHUTTLE_CALL)
|
||||
if(time_left <= 0)
|
||||
//move emergency shuttle to station
|
||||
if(dock(SSshuttle.getDock("emergency_home")) != DOCKING_SUCCESS)
|
||||
if(initiate_docking(SSshuttle.getDock("emergency_home")) != DOCKING_SUCCESS)
|
||||
setTimer(20)
|
||||
return
|
||||
mode = SHUTTLE_DOCKED
|
||||
|
||||
@@ -222,7 +222,7 @@
|
||||
|
||||
existing_shuttle.jumpToNullSpace()
|
||||
|
||||
preview_shuttle.dock(D)
|
||||
preview_shuttle.initiate_docking(D)
|
||||
. = preview_shuttle
|
||||
|
||||
// Shuttle state involves a mode and a timer based on world.time, so
|
||||
|
||||
@@ -172,7 +172,10 @@
|
||||
var/mob/camera/aiEye/remote/shuttle_docker/the_eye = eyeobj
|
||||
var/turf/eyeturf = get_turf(the_eye)
|
||||
if(!eyeturf)
|
||||
return
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
if(z_lock.len && !(eyeturf.z in z_lock))
|
||||
return SHUTTLE_DOCKER_BLOCKED
|
||||
|
||||
. = SHUTTLE_DOCKER_LANDING_CLEAR
|
||||
var/list/bounds = shuttle_port.return_coords(the_eye.x - x_offset, the_eye.y - y_offset, the_eye.dir)
|
||||
var/list/overlappers = SSshuttle.get_dock_overlap(bounds[1], bounds[2], bounds[3], bounds[4], the_eye.z)
|
||||
|
||||
+15
-208
@@ -159,9 +159,9 @@
|
||||
/obj/docking_port/stationary
|
||||
name = "dock"
|
||||
|
||||
turf_type = /turf/open/space
|
||||
baseturf_type = /turf/open/space
|
||||
area_type = /area/space
|
||||
turf_type = SHUTTLE_DEFAULT_TURF_TYPE
|
||||
baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
|
||||
area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
|
||||
|
||||
var/list/baseturf_cache
|
||||
|
||||
@@ -203,7 +203,7 @@
|
||||
for(var/i in 1 to assigned_turfs.len)
|
||||
var/turf/T = assigned_turfs[i]
|
||||
if(T.type == turf_type)
|
||||
T.ChangeTurf(/turf/open/space,/turf/open/space)
|
||||
T.ChangeTurf(SHUTTLE_DEFAULT_TURF_TYPE, SHUTTLE_DEFAULT_BASETURF_TYPE)
|
||||
T.flags_1 |= UNUSED_TRANSIT_TURF_1
|
||||
|
||||
/obj/docking_port/stationary/transit/Destroy(force=FALSE)
|
||||
@@ -224,9 +224,9 @@
|
||||
name = "shuttle"
|
||||
icon_state = "pinonclose"
|
||||
|
||||
area_type = /area/shuttle
|
||||
area_type = SHUTTLE_DEFAULT_SHUTTLE_AREA_TYPE
|
||||
|
||||
var/list/area/shuttle/shuttle_areas
|
||||
var/list/shuttle_areas
|
||||
|
||||
var/timer //used as a timer (if you want time left to complete move, use timeLeft proc)
|
||||
var/last_timer_length
|
||||
@@ -400,7 +400,7 @@
|
||||
var/obj/docking_port/stationary/S0 = get_docked()
|
||||
var/obj/docking_port/stationary/S1 = assigned_transit
|
||||
if(S1)
|
||||
if(dock(S1) != DOCKING_SUCCESS)
|
||||
if(initiate_docking(S1) != DOCKING_SUCCESS)
|
||||
WARNING("shuttle \"[id]\" could not enter transit space. Docked at [S0 ? S0.id : "null"]. Transit dock [S1 ? S1.id : "null"].")
|
||||
else
|
||||
previous = S0
|
||||
@@ -413,9 +413,9 @@
|
||||
// Not in a fancy way, it just ceases.
|
||||
var/obj/docking_port/stationary/current_dock = get_docked()
|
||||
|
||||
var/turf_type = /turf/open/space
|
||||
var/baseturf_type = /turf/open/space
|
||||
var/underlying_area_type = /area/space
|
||||
var/turf_type = SHUTTLE_DEFAULT_TURF_TYPE
|
||||
var/baseturf_type = SHUTTLE_DEFAULT_BASETURF_TYPE
|
||||
var/underlying_area_type = SHUTTLE_DEFAULT_UNDERLYING_AREA
|
||||
// If the shuttle is docked to a stationary port, restore its normal
|
||||
// "empty" area and turf
|
||||
if(current_dock)
|
||||
@@ -474,197 +474,6 @@
|
||||
for(var/obj/machinery/door/poddoor/shuttledock/pod in GLOB.airlocks)
|
||||
pod.check()
|
||||
|
||||
//this is the main proc. It instantly moves our mobile port to stationary port new_dock
|
||||
/obj/docking_port/mobile/proc/dock(obj/docking_port/stationary/new_dock, movement_direction, force=FALSE)
|
||||
// Crashing this ship with NO SURVIVORS
|
||||
|
||||
if(new_dock.get_docked() == src)
|
||||
remove_ripples()
|
||||
return DOCKING_SUCCESS
|
||||
|
||||
if(!force)
|
||||
if(!check_dock(new_dock))
|
||||
return DOCKING_BLOCKED
|
||||
if(!canMove())
|
||||
return DOCKING_IMMOBILIZED
|
||||
|
||||
var/obj/docking_port/stationary/old_dock = get_docked()
|
||||
|
||||
// The turf that gets placed under where the shuttle moved from
|
||||
var/underlying_turf_type = /turf/open/space
|
||||
|
||||
// The baseturf that the gets assigned to the turf_type above
|
||||
var/underlying_baseturf_type = /turf/open/space
|
||||
|
||||
// The area that gets placed under where the shuttle moved from
|
||||
var/underlying_area_type = /area/space
|
||||
|
||||
// The baseturf cache is a typecache of what counts as a baseturf to be left behind
|
||||
var/list/baseturf_cache
|
||||
if(old_dock) //Dock overwrites
|
||||
if(old_dock.turf_type)
|
||||
underlying_turf_type = old_dock.turf_type
|
||||
if(old_dock.baseturf_type)
|
||||
underlying_baseturf_type = old_dock.baseturf_type
|
||||
if(old_dock.area_type)
|
||||
underlying_area_type = old_dock.area_type
|
||||
if(old_dock.baseturf_cache)
|
||||
baseturf_cache = old_dock.baseturf_cache
|
||||
if(!baseturf_cache)
|
||||
baseturf_cache = typecacheof(underlying_baseturf_type)
|
||||
|
||||
/**************************************************************************************************************
|
||||
old_turfs is an associative list with a turf:bitflag structure
|
||||
new_turfs is a standard list composed of turf instances
|
||||
The bitflag contains the data for what inhabitants of that coordinate should be moved to the new location
|
||||
The bitflags can be found in __DEFINES/shuttles.dm
|
||||
*/
|
||||
var/list/old_turfs = return_ordered_turfs(x, y, z, dir)
|
||||
var/list/new_turfs = return_ordered_turfs(new_dock.x, new_dock.y, new_dock.z, new_dock.dir)
|
||||
/**************************************************************************************************************/
|
||||
|
||||
// The underlying old area is the area assumed to be under the shuttle's starting location
|
||||
// If it no longer/has never existed it will be created
|
||||
var/area/underlying_old_area = locate(underlying_area_type) in GLOB.sortedAreas
|
||||
if(!underlying_old_area)
|
||||
underlying_old_area = new underlying_area_type(null)
|
||||
|
||||
var/rotation = 0
|
||||
if(new_dock.dir != dir) //Even when the dirs are the same rotation is coming out as not 0 for some reason
|
||||
rotation = dir2angle(new_dock.dir)-dir2angle(dir)
|
||||
if ((rotation % 90) != 0)
|
||||
rotation += (rotation % 90) //diagonal rotations not allowed, round up
|
||||
rotation = SIMPLIFY_DEGREES(rotation)
|
||||
|
||||
if(!movement_direction)
|
||||
movement_direction = turn(preferred_direction, 180)
|
||||
|
||||
remove_ripples()
|
||||
|
||||
var/list/moved_atoms = list() //Everything not a turf that gets moved in the shuttle
|
||||
var/list/areas_to_move = list() //unique assoc list of areas on turfs being moved
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
/****************************************All beforeShuttleMove procs*****************************************/
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
if(!newT)
|
||||
return DOCKING_NULL_DESTINATION
|
||||
if(!oldT)
|
||||
return DOCKING_NULL_SOURCE
|
||||
|
||||
var/area/old_area = oldT.loc
|
||||
var/move_mode = old_area.beforeShuttleMove(shuttle_areas) //areas
|
||||
|
||||
var/list/old_contents = oldT.contents
|
||||
for(var/k in 1 to old_contents.len)
|
||||
CHECK_TICK
|
||||
var/atom/movable/moving_atom = old_contents[k]
|
||||
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
||||
continue
|
||||
move_mode = moving_atom.beforeShuttleMove(newT, rotation, move_mode) //atoms
|
||||
|
||||
move_mode = oldT.fromShuttleMove(newT, underlying_turf_type, baseturf_cache, move_mode) //turfs
|
||||
move_mode = newT.toShuttleMove(oldT, move_mode , src) //turfs
|
||||
|
||||
if(move_mode & MOVE_AREA)
|
||||
areas_to_move[old_area] = TRUE
|
||||
|
||||
old_turfs[oldT] = move_mode
|
||||
|
||||
/*******************************************Hiding turfs if necessary*******************************************/
|
||||
|
||||
var/list/new_hidden_turfs
|
||||
if(hidden)
|
||||
new_hidden_turfs = list()
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
var/turf/oldT = old_turfs[i]
|
||||
if(old_turfs[oldT] & MOVE_TURF)
|
||||
new_hidden_turfs += new_turfs[i]
|
||||
SSshuttle.update_hidden_docking_ports(null, new_hidden_turfs)
|
||||
|
||||
/*******************************************All onShuttleMove procs******************************************/
|
||||
|
||||
CHECK_TICK
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
var/move_mode = old_turfs[oldT]
|
||||
if(move_mode & MOVE_CONTENTS)
|
||||
for(var/k in oldT)
|
||||
var/atom/movable/moving_atom = k
|
||||
if(moving_atom.loc != oldT) //fix for multi-tile objects
|
||||
continue
|
||||
moving_atom.onShuttleMove(newT, oldT, movement_force, movement_direction, old_dock, src) //atoms
|
||||
moved_atoms[moving_atom] = oldT
|
||||
|
||||
if(move_mode & MOVE_TURF)
|
||||
oldT.onShuttleMove(newT, movement_force, movement_direction) //turfs
|
||||
|
||||
if(move_mode & MOVE_AREA)
|
||||
var/area/shuttle_area = oldT.loc
|
||||
shuttle_area.onShuttleMove(oldT, newT, underlying_old_area) //areas
|
||||
|
||||
/******************************************All afterShuttleMove procs****************************************/
|
||||
|
||||
underlying_old_area.afterShuttleMove()
|
||||
|
||||
// Parallax handling
|
||||
// This needs to be done before the atom after move
|
||||
var/new_parallax_dir = FALSE
|
||||
if(istype(new_dock, /obj/docking_port/stationary/transit))
|
||||
new_parallax_dir = preferred_direction
|
||||
for(var/i in 1 to areas_to_move.len)
|
||||
CHECK_TICK
|
||||
var/area/internal_area = areas_to_move[i]
|
||||
internal_area.afterShuttleMove(new_parallax_dir) //areas
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
if(!(old_turfs[old_turfs[i]] & MOVE_TURF))
|
||||
continue
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
newT.afterShuttleMove(oldT, underlying_turf_type, underlying_baseturf_type, rotation) //turfs
|
||||
|
||||
for(var/i in 1 to moved_atoms.len)
|
||||
CHECK_TICK
|
||||
var/atom/movable/moved_object = moved_atoms[i]
|
||||
if(QDELETED(moved_object))
|
||||
continue
|
||||
var/turf/oldT = moved_atoms[moved_object]
|
||||
moved_object.afterShuttleMove(oldT, movement_force, dir, preferred_direction, movement_direction, rotation)//atoms
|
||||
|
||||
for(var/i in 1 to old_turfs.len)
|
||||
CHECK_TICK
|
||||
// Objects can block air so either turf or content changes means an air update is needed
|
||||
if(!(old_turfs[old_turfs[i]] & MOVE_CONTENTS | MOVE_TURF))
|
||||
continue
|
||||
var/turf/oldT = old_turfs[i]
|
||||
var/turf/newT = new_turfs[i]
|
||||
oldT.blocks_air = initial(oldT.blocks_air)
|
||||
oldT.air_update_turf(TRUE)
|
||||
newT.blocks_air = initial(newT.blocks_air)
|
||||
newT.air_update_turf(TRUE)
|
||||
|
||||
/*******************************************Unhiding turfs if necessary******************************************/
|
||||
|
||||
if(new_hidden_turfs)
|
||||
SSshuttle.update_hidden_docking_ports(hidden_turfs, null)
|
||||
hidden_turfs = new_hidden_turfs
|
||||
|
||||
check_poddoors()
|
||||
new_dock.last_dock_time = world.time
|
||||
setDir(new_dock.dir)
|
||||
|
||||
return DOCKING_SUCCESS
|
||||
|
||||
/obj/docking_port/mobile/proc/findRoundstartDock()
|
||||
return SSshuttle.getDock(roundstart_move)
|
||||
|
||||
@@ -674,7 +483,7 @@
|
||||
/obj/docking_port/mobile/proc/dock_id(id)
|
||||
var/port = SSshuttle.getDock(id)
|
||||
if(port)
|
||||
. = dock(port)
|
||||
. = initiate_docking(port)
|
||||
else
|
||||
. = null
|
||||
|
||||
@@ -694,9 +503,9 @@
|
||||
// then try again
|
||||
switch(mode)
|
||||
if(SHUTTLE_CALL)
|
||||
var/error = dock(destination, preferred_direction)
|
||||
var/error = initiate_docking(destination, preferred_direction)
|
||||
if(error && error & (DOCKING_NULL_DESTINATION | DOCKING_NULL_SOURCE))
|
||||
var/msg = "A mobile dock in transit exited dock() with an error. This is most likely a mapping problem: Error: [error], ([src]) ([previous])"
|
||||
var/msg = "A mobile dock in transit exited initiate_docking() with an error. This is most likely a mapping problem: Error: [error], ([src]) ([previous])"
|
||||
WARNING(msg)
|
||||
message_admins(msg)
|
||||
mode = SHUTTLE_IDLE
|
||||
@@ -705,7 +514,7 @@
|
||||
setTimer(20)
|
||||
return
|
||||
if(SHUTTLE_RECALL)
|
||||
if(dock(previous) != DOCKING_SUCCESS)
|
||||
if(initiate_docking(previous) != DOCKING_SUCCESS)
|
||||
setTimer(20)
|
||||
return
|
||||
if(SHUTTLE_IGNITING)
|
||||
@@ -933,10 +742,8 @@
|
||||
|
||||
/obj/docking_port/mobile/pod/on_emergency_dock()
|
||||
if(launch_status == ENDGAME_LAUNCHED)
|
||||
dock(SSshuttle.getDock("[id]_away")) //Escape pods dock at centcom
|
||||
initiate_docking(SSshuttle.getDock("[id]_away")) //Escape pods dock at centcom
|
||||
mode = SHUTTLE_ENDGAME
|
||||
|
||||
/obj/docking_port/mobile/emergency/on_emergency_dock()
|
||||
return
|
||||
|
||||
#undef DOCKING_PORT_HIGHLIGHT
|
||||
|
||||
@@ -64,7 +64,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
return 2
|
||||
return ..()
|
||||
|
||||
/obj/docking_port/mobile/supply/dock()
|
||||
/obj/docking_port/mobile/supply/initiate_docking()
|
||||
if(getDockedId() == "supply_away") // Buy when we leave home.
|
||||
buy()
|
||||
. = ..() // Fly/enter transit.
|
||||
|
||||
@@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(z_levels_list)
|
||||
neigbours[TEXT_WEST] = P.spl
|
||||
P.spl.neigbours[TEXT_EAST] = src
|
||||
|
||||
/datum/point //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
|
||||
/datum/space_transition //this is explicitly utilitarian datum type made specially for the space map generation and are absolutely unusable for anything else
|
||||
var/list/neigbours = list()
|
||||
var/x
|
||||
var/y
|
||||
|
||||
Reference in New Issue
Block a user