Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions code/__DEFINES/misc.dm
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
//Gets the turf this atom inhabits
#define get_turf(A) (get_step(A, 0))

//Same as above except gets the area instead
#define get_area(A) (isarea(A) ? A : get_step(A, 0)?.loc)

//Ghost orbit types:
#define GHOST_ORBIT_CIRCLE "circle"
#define GHOST_ORBIT_TRIANGLE "triangle"
Expand Down
6 changes: 0 additions & 6 deletions code/__HELPERS/game.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,6 @@
#define Z_TURFS(ZLEVEL) block(locate(1,1,ZLEVEL), locate(world.maxx, world.maxy, ZLEVEL))
#define CULT_POLL_WAIT 2400

/proc/get_area(atom/A)
if(isarea(A))
return A
var/turf/T = get_turf(A)
return T ? T.loc : null

/proc/get_area_name(atom/X, format_text = FALSE)
var/area/A = isarea(X) ? X : get_area(X)
if(!A)
Expand Down
13 changes: 5 additions & 8 deletions code/game/objects/items/blueprints.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
/obj/item/areaeditor/blueprints/attack_self(mob/user)
. = ..()
if(!legend)
var/area/A = get_area()
var/area/A = get_area(user)
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p><a href='?src=[REF(src)];edit_area=1'>Change area name</a></p>"
Expand Down Expand Up @@ -140,12 +140,9 @@
legend = FALSE


/obj/item/areaeditor/proc/get_area()
var/turf/T = get_turf(usr)
var/area/A = T.loc
return A

/obj/item/areaeditor/proc/get_area_type(area/A = get_area())
/obj/item/areaeditor/proc/get_area_type(area/A)
if (!A)
A = get_area(usr)
if(A.outdoors)
return AREA_SPACE
var/list/SPECIALS = list(
Expand Down Expand Up @@ -183,7 +180,7 @@
return ""

/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
var/area/A = get_area(usr)
var/prevname = "[A.name]"
var/str = stripped_input(usr,"New area name:", "Area Creation", "", MAX_NAME_LEN)
if(!str || !length(str) || str==prevname) //cancel
Expand Down
229 changes: 229 additions & 0 deletions code/game/objects/items/crab17.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/obj/item/suspiciousphone
name = "suspicious phone"
desc = "This device raises pink levels to unknown highs."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "suspiciousphone"
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("dumped")
var/dumped = FALSE

/obj/item/suspiciousphone/attack_self(mob/user)
if(!ishuman(user))
to_chat(user, "<span class='warning'>This device is too advanced for you!</span>")
return
if(dumped)
to_chat(user, "<span class='warning'>You already activated Protocol CRAB-17.</span>")
return FALSE
if(alert(user, "Are you sure you want to crash this market with no survivors?", "Protocol CRAB-17", "Yes", "No") == "Yes")
if(dumped || QDELETED(src)) //Prevents fuckers from cheesing alert
return FALSE
var/turf/targetturf = get_safe_random_station_turf()
if (!targetturf)
return FALSE
new /obj/effect/dumpeetTarget(targetturf, user)
dumped = TRUE

/obj/structure/checkoutmachine
name = "Nanotrasen Space-Coin Market"
desc = "This is good for spacecoin because"
icon = 'icons/obj/money_machine.dmi'
icon_state = "bogdanoff"
layer = TABLE_LAYER //So that the crate inside doesn't appear underneath
armor = list("melee" = 30, "bullet" = 50, "laser" = 50, "energy" = 100, "bomb" = 100, "bio" = 0, "rad" = 0, "fire" = 100, "acid" = 80)
density = TRUE
pixel_z = -8
layer = LARGE_MOB_LAYER
max_integrity = 600
var/list/accounts_to_rob
var/mob/living/carbon/human/bogdanoff
var/canwalk = FALSE

/obj/structure/checkoutmachine/examine(mob/living/user)
..()
to_chat(user, "<span class='info'>It's integrated integrity meter reads: <b>HEALTH: [obj_integrity]</b>.</span>")

/obj/structure/checkoutmachine/proc/check_if_finished()
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
if (B.being_dumped)
return FALSE
return TRUE

/obj/structure/checkoutmachine/attackby(obj/item/W, mob/user, params)
if(check_if_finished())
qdel(src)
return
if(istype(W, /obj/item/card/id))
var/obj/item/card/id/card = W
if(!card.registered_account)
to_chat(user, "<span class='warning'>This card does not have a registered account!</span>")
return
if(!card.registered_account.being_dumped)
to_chat(user, "<span class='warning'>It appears that your funds are safe from draining!</span>")
return
if(do_after(user, 40, target = src))
if(!card.registered_account.being_dumped)
return
to_chat(user, "<span class='warning'>You quickly cash out your funds to a more secure banking location. Funds are safu.</span>")
card.registered_account.being_dumped = FALSE
card.registered_account.withdrawDelay = 0
if(check_if_finished())
qdel(src)
return
else
return ..()

/obj/structure/checkoutmachine/Initialize(mapload, mob/living/user)
. = ..()
bogdanoff = user
add_overlay("flaps")
add_overlay("hatch")
add_overlay("legs_retracted")
addtimer(CALLBACK(src, .proc/startUp), 50)


/obj/structure/checkoutmachine/proc/startUp() //very VERY snowflake code that adds a neat animation when the pod lands.
start_dumping() //The machine doesnt move during this time, giving people close by a small window to grab their funds before it starts running around
sleep(10)
if(QDELETED(src))
return
playsound(src, 'sound/machines/click.ogg', 15, 1, -3)
cut_overlay("flaps")
sleep(10)
if(QDELETED(src))
return
playsound(src, 'sound/machines/click.ogg', 15, 1, -3)
cut_overlay("hatch")
sleep(30)
if(QDELETED(src))
return
playsound(src,'sound/machines/twobeep.ogg',50,0)
var/mutable_appearance/hologram = mutable_appearance(icon, "hologram")
hologram.pixel_y = 16
add_overlay(hologram)
var/mutable_appearance/holosign = mutable_appearance(icon, "holosign")
holosign.pixel_y = 16
add_overlay(holosign)
add_overlay("legs_extending")
cut_overlay("legs_retracted")
pixel_z += 4
sleep(5)
if(QDELETED(src))
return
add_overlay("legs_extended")
cut_overlay("legs_extending")
pixel_z += 4
sleep(20)
if(QDELETED(src))
return
add_overlay("screen_lines")
sleep(5)
if(QDELETED(src))
return
cut_overlay("screen_lines")
sleep(5)
if(QDELETED(src))
return
add_overlay("screen_lines")
add_overlay("screen")
sleep(5)
if(QDELETED(src))
return
playsound(src,'sound/machines/triple_beep.ogg',50,0)
add_overlay("text")
sleep(10)
if(QDELETED(src))
return
add_overlay("legs")
cut_overlay("legs_extended")
cut_overlay("screen")
add_overlay("screen")
cut_overlay("screen_lines")
add_overlay("screen_lines")
cut_overlay("text")
add_overlay("text")
canwalk = TRUE
START_PROCESSING(SSfastprocess, src)

/obj/structure/checkoutmachine/Destroy()
stop_dumping()
STOP_PROCESSING(SSfastprocess, src)
priority_announce("The credit deposit machine at [get_area(src)] has been destroyed. Station funds have stopped draining!", sender_override = "CRAB-17 Protocol")
explosion(src, 0,0,1, flame_range = 2)
return ..()

/obj/structure/checkoutmachine/proc/start_dumping()
accounts_to_rob = SSeconomy.bank_accounts.Copy()
accounts_to_rob -= bogdanoff.get_bank_account()
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
B.dumpeet()
dump()

/obj/structure/checkoutmachine/proc/dump()
var/percentage_lost = (rand(1, 10) / 100)
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
if(!B.being_dumped)
continue
var/amount = B.account_balance * percentage_lost
var/datum/bank_account/account = bogdanoff.get_bank_account()
if (account) // get_bank_account() may return FALSE
account.transfer_money(B, amount)
B.bank_card_talk("You have lost [percentage_lost * 100]% of your funds! A spacecoin credit deposit machine is located at: [get_area(src)].")
addtimer(CALLBACK(src, .proc/dump), 150) //Drain every 15 seconds

/obj/structure/checkoutmachine/process()
var/anydir = pick(GLOB.cardinals)
if(Process_Spacemove(anydir))
Move(get_step(src, anydir), anydir)

/obj/structure/checkoutmachine/proc/stop_dumping()
for(var/i in accounts_to_rob)
var/datum/bank_account/B = i
B.being_dumped = FALSE

/obj/effect/dumpeetFall //Falling pod
name = ""
icon = 'icons/obj/money_machine_64.dmi'
pixel_z = 300
desc = "Get out of the way!"
layer = FLY_LAYER//that wasnt flying, that was falling with style!
icon_state = "missile_blur"

/obj/effect/dumpeetTarget
name = "Landing Zone Indicator"
desc = "A holographic projection designating the landing zone of something. It's probably best to stand back."
icon = 'icons/mob/actions/actions_items.dmi'
icon_state = "sniper_zoom"
layer = PROJECTILE_HIT_THRESHHOLD_LAYER
light_range = 2
var/obj/effect/dumpeetFall/DF
var/obj/structure/checkoutmachine/dump
var/mob/living/carbon/human/bogdanoff

/obj/effect/ex_act()
return

/obj/effect/dumpeetTarget/Initialize(mapload, user)
. = ..()
bogdanoff = user
addtimer(CALLBACK(src, .proc/startLaunch), 100)
sound_to_playing_players('sound/items/dump_it.ogg', 20)
deadchat_broadcast("<span class='deadsay'>Protocol CRAB-17 has been activated. A space-coin market has been launched at the station!</span>", turf_target = get_turf(src))

/obj/effect/dumpeetTarget/proc/startLaunch()
DF = new /obj/effect/dumpeetFall(drop_location())
dump = new /obj/structure/checkoutmachine(null, bogdanoff)
priority_announce("The spacecoin bubble has popped! Get to the credit deposit machine at [get_area(src)] and cash out before you lose all of your funds!", sender_override = "CRAB-17 Protocol")
animate(DF, pixel_z = -8, time = 5, , easing = LINEAR_EASING)
playsound(src, 'sound/weapons/mortar_whistle.ogg', 70, 1, 6)
addtimer(CALLBACK(src, .proc/endLaunch), 5, TIMER_CLIENT_TIME) //Go onto the last step after a very short falling animation



/obj/effect/dumpeetTarget/proc/endLaunch()
QDEL_NULL(DF) //Delete the falling machine effect, because at this point its animation is over. We dont use temp_visual because we want to manually delete it as soon as the pod appears
playsound(src, "explosion", 80, 1)
dump.forceMove(get_turf(src))
qdel(src) //The target's purpose is complete. It can rest easy now
3 changes: 2 additions & 1 deletion code/modules/jobs/job_types/ai.dm
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@

/datum/job/ai/announce(mob/living/silicon/ai/AI)
. = ..()
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "[AI] has been downloaded to an empty bluespace-networked AI core in [get_area(AI).name].")) //YOGS - removed the co-ordinates
var/area/A = get_area(AI)//yogs
SSticker.OnRoundstart(CALLBACK(GLOBAL_PROC, .proc/minor_announce, "[AI] has been downloaded to an empty bluespace-networked AI core in [A.name].")) //YOGS - removed the co-ordinates

/datum/job/ai/config_check()
return CONFIG_GET(flag/allow_ai)
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
/mob/living/simple_animal/hostile/floor_cluwne/Life()
do_jitter_animation(1000)
pixel_y = 8

if(is_type_in_typecache(get_area(src.loc), invalid_area_typecache) || !is_station_level(z))
var/area/A = get_area(loc) // Has to be separated from the below since is_type_in_typecache is also a funky macro
if(is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(z))
var/area = pick(GLOB.teleportlocs)
var/area/tp = GLOB.teleportlocs[area]
forceMove(pick(get_area_turfs(tp.type)))
Expand All @@ -99,12 +99,13 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
return

var/turf/T = get_turf(current_victim)
A = get_area(T) // Has to be separated from the below since is_type_in_typecache is also a funky macro
if(prob(5))//checks roughly every 20 ticks
if(current_victim.stat == DEAD || current_victim.dna.check_mutation(CLUWNEMUT) || is_type_in_typecache(get_area(T), invalid_area_typecache) || !is_station_level(current_victim.z))
if(current_victim.stat == DEAD || current_victim.dna.check_mutation(CLUWNEMUT) || is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(current_victim.z))
if(!Found_You())
Acquire_Victim()

if(get_dist(src, current_victim) > 9 && !manifested && !is_type_in_typecache(get_area(T), invalid_area_typecache))//if cluwne gets stuck he just teleports
if(get_dist(src, current_victim) > 9 && !manifested && !is_type_in_typecache(A, invalid_area_typecache))//if cluwne gets stuck he just teleports
do_teleport(src, T)

interest++
Expand All @@ -123,7 +124,8 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
..()

/mob/living/simple_animal/hostile/floor_cluwne/Goto(target, delay, minimum_distance)
if(!manifested && !is_type_in_typecache(get_area(current_victim.loc), invalid_area_typecache) && is_station_level(current_victim.z))
var/area/A = get_area(current_victim.loc)
if(!manifested && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(current_victim.z))
walk_to(src, target, minimum_distance, delay)
else
walk_to(src,0)
Expand Down Expand Up @@ -160,13 +162,15 @@ GLOBAL_VAR_INIT(floor_cluwnes, 0)
/mob/living/simple_animal/hostile/floor_cluwne/proc/Acquire_Victim(specific)
for(var/I in GLOB.player_list)//better than a potential recursive loop
var/mob/living/carbon/human/H = pick(GLOB.player_list)//so the check is fair

var/area/A
if(specific)
H = specific
if(H.stat != DEAD && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(get_area(H.loc), invalid_area_typecache) && is_station_level(H.z))
A = get_area(H.loc)
if(H.stat != DEAD && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
return target = current_victim

if(H && ishuman(H) && H.stat != DEAD && H != current_victim && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(get_area(H.loc), invalid_area_typecache) && is_station_level(H.z))

A = get_area(H.loc)
if(H && ishuman(H) && H.stat != DEAD && H != current_victim && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
current_victim = H
interest = 0
stage = STAGE_HAUNT
Expand Down