mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-07-21 03:56:47 +01:00
Merge branch 'dev' into ofMechfabAndPanic
Conflicts: maps/exodus-1.dmm
This commit is contained in:
@@ -105,7 +105,7 @@ var/list/admin_verbs_fun = list(
|
||||
/client/proc/cmd_admin_dress,
|
||||
/client/proc/cmd_admin_gib_self,
|
||||
/client/proc/drop_bomb,
|
||||
/client/proc/everyone_random,
|
||||
/client/proc/everyone_random,
|
||||
/client/proc/cinematic,
|
||||
/datum/admins/proc/toggle_aliens,
|
||||
/datum/admins/proc/toggle_space_ninja,
|
||||
@@ -114,8 +114,11 @@ var/list/admin_verbs_fun = list(
|
||||
/client/proc/make_sound,
|
||||
/client/proc/toggle_random_events,
|
||||
/client/proc/editappear,
|
||||
/client/proc/roll_dices
|
||||
/client/proc/roll_dices,
|
||||
/datum/admins/proc/call_supply_drop,
|
||||
/datum/admins/proc/call_drop_pod
|
||||
)
|
||||
|
||||
var/list/admin_verbs_spawn = list(
|
||||
/datum/admins/proc/spawn_fruit,
|
||||
/datum/admins/proc/spawn_custom_item,
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
msg = sanitize(msg)
|
||||
if(!msg) return
|
||||
|
||||
log_admin("[key_name(src)] : [msg]")
|
||||
log_admin("ADMIN: [key_name(src)] : [msg]")
|
||||
|
||||
if(check_rights(R_ADMIN,0))
|
||||
for(var/client/C in admins)
|
||||
@@ -29,7 +29,7 @@
|
||||
if (!msg)
|
||||
return
|
||||
|
||||
var/sender_name = src.key
|
||||
var/sender_name = key_name(usr, 1)
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
sender_name = "<span class='admin'>[sender_name]</span>"
|
||||
for(var/client/C in admins)
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
shoes = null
|
||||
return 0
|
||||
H.drop_from_inventory(shoes) //Remove the old shoes so you can put on the magboots.
|
||||
shoes.loc = src
|
||||
shoes.forceMove(src)
|
||||
|
||||
if(!..())
|
||||
if(shoes) //Put the old shoes back on if the check fails.
|
||||
@@ -63,7 +63,7 @@
|
||||
var/mob/living/carbon/human/H = wearer
|
||||
if(shoes)
|
||||
if(!H.equip_to_slot_if_possible(shoes, slot_shoes))
|
||||
shoes.loc = get_turf(src)
|
||||
shoes.forceMove(get_turf(src))
|
||||
src.shoes = null
|
||||
wearer = null
|
||||
|
||||
|
||||
@@ -304,7 +304,7 @@
|
||||
if(istype(piece.loc, /mob/living))
|
||||
M = piece.loc
|
||||
M.drop_from_inventory(piece)
|
||||
piece.loc = src
|
||||
piece.forceMove(src)
|
||||
|
||||
if(!istype(wearer) || loc != wearer || wearer.back != src || canremove || !cell || cell.charge <= 0)
|
||||
if(!cell || cell.charge <= 0)
|
||||
@@ -558,7 +558,7 @@
|
||||
if(M && M.back == src)
|
||||
M.back = null
|
||||
M.drop_from_inventory(src)
|
||||
src.loc = get_turf(src)
|
||||
src.forceMove(get_turf(src))
|
||||
return
|
||||
|
||||
if(istype(M) && M.back == src)
|
||||
@@ -615,22 +615,21 @@
|
||||
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "retract" : "retracts"] swiftly.</b></font>"
|
||||
use_obj.canremove = 1
|
||||
holder.drop_from_inventory(use_obj)
|
||||
use_obj.loc = get_turf(src)
|
||||
use_obj.forceMove(get_turf(src))
|
||||
use_obj.dropped()
|
||||
use_obj.canremove = 0
|
||||
use_obj.loc = src
|
||||
use_obj.forceMove(src)
|
||||
|
||||
else if (deploy_mode != ONLY_RETRACT)
|
||||
if(check_slot)
|
||||
if(check_slot != use_obj)
|
||||
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
|
||||
if(check_slot && check_slot == use_obj)
|
||||
return
|
||||
use_obj.forceMove(H)
|
||||
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0, 1))
|
||||
use_obj.forceMove(src)
|
||||
if(check_slot)
|
||||
H << "<span class='danger'>You are unable to deploy \the [piece] as \the [check_slot] [check_slot.gender == PLURAL ? "are" : "is"] in the way.</span>"
|
||||
else
|
||||
use_obj.loc = H
|
||||
if(!H.equip_to_slot_if_possible(use_obj, equip_to, 0))
|
||||
use_obj.loc = src
|
||||
else
|
||||
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</b></span>"
|
||||
H << "<font color='blue'><b>Your [use_obj.name] [use_obj.gender == PLURAL ? "deploy" : "deploys"] swiftly.</b></span>"
|
||||
|
||||
if(piece == "helmet" && helmet)
|
||||
helmet.update_light(H)
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
if(istype(H))
|
||||
if(helmet && H.head == helmet)
|
||||
H.drop_from_inventory(helmet)
|
||||
helmet.loc = src
|
||||
helmet.forceMove(src)
|
||||
|
||||
if(boots)
|
||||
boots.canremove = 1
|
||||
@@ -120,11 +120,11 @@
|
||||
if(istype(H))
|
||||
if(boots && H.shoes == boots)
|
||||
H.drop_from_inventory(boots)
|
||||
boots.loc = src
|
||||
boots.forceMove(src)
|
||||
|
||||
if(tank)
|
||||
tank.canremove = 1
|
||||
tank.loc = src
|
||||
tank.forceMove(src)
|
||||
|
||||
/obj/item/clothing/suit/space/void/verb/toggle_helmet()
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
H << "<span class='notice'>You retract your suit helmet.</span>"
|
||||
helmet.canremove = 1
|
||||
H.drop_from_inventory(helmet)
|
||||
helmet.loc = src
|
||||
helmet.forceMove(src)
|
||||
else
|
||||
if(H.head)
|
||||
H << "<span class='danger'>You cannot deploy your helmet while wearing \the [H.head].</span>"
|
||||
@@ -197,15 +197,15 @@
|
||||
|
||||
if(choice == tank) //No, a switch doesn't work here. Sorry. ~Techhead
|
||||
user << "You pop \the [tank] out of \the [src]'s storage compartment."
|
||||
tank.loc = get_turf(src)
|
||||
tank.forceMove(get_turf(src))
|
||||
src.tank = null
|
||||
else if(choice == helmet)
|
||||
user << "You detatch \the [helmet] from \the [src]'s helmet mount."
|
||||
helmet.loc = get_turf(src)
|
||||
helmet.forceMove(get_turf(src))
|
||||
src.helmet = null
|
||||
else if(choice == boots)
|
||||
user << "You detatch \the [boots] from \the [src]'s boot mounts."
|
||||
boots.loc = get_turf(src)
|
||||
boots.forceMove(get_turf(src))
|
||||
src.boots = null
|
||||
else
|
||||
user << "\The [src] does not have anything installed."
|
||||
@@ -216,7 +216,7 @@
|
||||
else
|
||||
user << "You attach \the [W] to \the [src]'s helmet mount."
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
W.forceMove(src)
|
||||
src.helmet = W
|
||||
return
|
||||
else if(istype(W,/obj/item/clothing/shoes/magboots))
|
||||
@@ -225,7 +225,7 @@
|
||||
else
|
||||
user << "You attach \the [W] to \the [src]'s boot mounts."
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
W.forceMove(src)
|
||||
boots = W
|
||||
return
|
||||
else if(istype(W,/obj/item/weapon/tank))
|
||||
@@ -236,7 +236,7 @@
|
||||
else
|
||||
user << "You insert \the [W] into \the [src]'s storage compartment."
|
||||
user.drop_item()
|
||||
W.loc = src
|
||||
W.forceMove(src)
|
||||
tank = W
|
||||
return
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Rogue Drones", /datum/event/rogue_drone, 20, list(ASSIGNMENT_SECURITY = 20)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Space Dust", /datum/event/dust, 30, list(ASSIGNMENT_ENGINEER = 5)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 150), 1),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Virology Breach", /datum/event/prison_break/virology, 0, list(ASSIGNMENT_MEDICAL = 100)),
|
||||
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Xenobiology Breach", /datum/event/prison_break/xenobiology, 0, list(ASSIGNMENT_SCIENCE = 100)),
|
||||
)
|
||||
|
||||
@@ -326,6 +326,20 @@ var/list/name_to_material
|
||||
icon_reinf = "reinf_over"
|
||||
icon_colour = "#666666"
|
||||
|
||||
/material/diona
|
||||
name = "biomass"
|
||||
icon_colour = null
|
||||
stack_type = null
|
||||
integrity = 600
|
||||
icon_base = "diona"
|
||||
icon_reinf = "noreinf"
|
||||
|
||||
/material/diona/place_dismantled_product()
|
||||
return
|
||||
|
||||
/material/diona/place_dismantled_girder(var/turf/target)
|
||||
spawn_diona_nymph(target)
|
||||
|
||||
/material/steel/holographic
|
||||
name = "holo" + DEFAULT_WALL_MATERIAL
|
||||
display_name = DEFAULT_WALL_MATERIAL
|
||||
@@ -346,6 +360,14 @@ var/list/name_to_material
|
||||
stack_origin_tech = list(TECH_MATERIAL = 2)
|
||||
composite_material = list(DEFAULT_WALL_MATERIAL = 3750, "platinum" = 3750) //todo
|
||||
|
||||
/material/plasteel/titanium
|
||||
name = "titanium"
|
||||
stack_type = null
|
||||
icon_base = "metal"
|
||||
door_icon_base = "metal"
|
||||
icon_colour = "#D1E6E3"
|
||||
icon_reinf = "reinf_metal"
|
||||
|
||||
/material/glass
|
||||
name = "glass"
|
||||
stack_type = /obj/item/stack/material/glass
|
||||
|
||||
@@ -208,7 +208,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user as mob)
|
||||
if(user.incapacitated())
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
return
|
||||
|
||||
var/obj/item/clothing/under/suit = null
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
if(!slot_to_strip || !istype(user))
|
||||
return
|
||||
|
||||
if(user.incapacitated())
|
||||
if(user.incapacitated() || !user.Adjacent(src))
|
||||
user << browse(null, text("window=mob[src.name]"))
|
||||
return
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ var/global/list/damage_icon_parts = list()
|
||||
O.update_icon()
|
||||
if(O.damage_state == "00") continue
|
||||
var/icon/DI
|
||||
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.name]"
|
||||
var/cache_index = "[O.damage_state]/[O.icon_name]/[species.blood_color]/[species.get_bodytype()]"
|
||||
if(damage_icon_parts[cache_index] == null)
|
||||
DI = new /icon(species.damage_overlays, O.damage_state) // the damage icon for whole human
|
||||
DI.Blend(new /icon(species.damage_mask, O.icon_name), ICON_MULTIPLY) // mask with this organ's pixels
|
||||
|
||||
@@ -659,6 +659,26 @@ default behaviour is:
|
||||
resting = !resting
|
||||
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"].</span>"
|
||||
|
||||
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
|
||||
if(istype(carried_item, /obj/item/weapon/implant))
|
||||
return 1
|
||||
if(istype(carried_item, /obj/item/clothing/mask/facehugger))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
|
||||
if(carried_item in internal_organs)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item)
|
||||
if(carried_item in organs)
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item)
|
||||
return carried_item != held_item
|
||||
|
||||
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
|
||||
if(stat)
|
||||
src << "You must be conscious to do this!"
|
||||
@@ -721,9 +741,10 @@ default behaviour is:
|
||||
|
||||
if(!ignore_items)
|
||||
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
|
||||
if( !istype(carried_item, /obj/item/weapon/implant) && !istype(carried_item, /obj/item/clothing/mask/facehugger) )//If it's not an implant or a facehugger
|
||||
src << "\red You can't be carrying items or have items equipped when vent crawling!"
|
||||
return
|
||||
if(is_allowed_vent_crawl_item(carried_item))
|
||||
continue
|
||||
src << "<span class='warning'>You can't be carrying items or have items equipped when vent crawling!</span>"
|
||||
return
|
||||
|
||||
if(isslime(src))
|
||||
var/mob/living/carbon/slime/S = src
|
||||
|
||||
@@ -347,7 +347,7 @@ nanoui is used to open and update nano browser uis
|
||||
template_data_json = list2json(templates)
|
||||
|
||||
var/list/send_data = get_send_data(initial_data)
|
||||
var/initial_data_json = replacetext(list2json_usecache(send_data), "'", "'")
|
||||
var/initial_data_json = replacetext(replacetext(list2json_usecache(send_data), """, "&#34;"), "'", "'")
|
||||
|
||||
var/url_parameters_json = list2json(list("src" = "\ref[src]"))
|
||||
|
||||
|
||||
@@ -345,6 +345,7 @@ var/list/organ_cache = list()
|
||||
user.drop_from_inventory(src)
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/organ/O = new(get_turf(src))
|
||||
O.name = name
|
||||
O.icon = icon
|
||||
O.icon_state = icon_state
|
||||
|
||||
// Pass over the blood.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/proc/spawn_diona_nymph_from_organ(var/obj/item/organ/organ)
|
||||
if(!istype(organ))
|
||||
/proc/spawn_diona_nymph(var/turf/target)
|
||||
if(!istype(target))
|
||||
return 0
|
||||
|
||||
//This is a terrible hack and I should be ashamed.
|
||||
@@ -8,7 +8,7 @@
|
||||
return 0
|
||||
|
||||
spawn(1) // So it has time to be thrown about by the gib() proc.
|
||||
var/mob/living/carbon/alien/diona/D = new(get_turf(organ))
|
||||
var/mob/living/carbon/alien/diona/D = new(target)
|
||||
var/datum/ghosttrap/plant/P = get_ghost_trap("living plant")
|
||||
P.request_player(D, "A diona nymph has split off from its gestalt. ")
|
||||
spawn(60)
|
||||
@@ -144,7 +144,7 @@
|
||||
..()
|
||||
if(!istype(H) || !H.organs || !H.organs.len)
|
||||
H.death()
|
||||
if(prob(50) && spawn_diona_nymph_from_organ(src))
|
||||
if(prob(50) && spawn_diona_nymph(get_turf(src)))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/organ/diona/process()
|
||||
@@ -185,7 +185,7 @@
|
||||
..()
|
||||
if(!istype(H) || !H.organs || !H.organs.len)
|
||||
H.death()
|
||||
if(prob(50) && spawn_diona_nymph_from_organ(src))
|
||||
if(prob(50) && spawn_diona_nymph(get_turf(src)))
|
||||
qdel(src)
|
||||
|
||||
// These are different to the standard diona organs as they have a purpose in other
|
||||
|
||||
@@ -166,6 +166,10 @@
|
||||
desc = "A small lighting fixture."
|
||||
light_type = /obj/item/weapon/light/bulb
|
||||
|
||||
/obj/machinery/light/small/emergency
|
||||
brightness_range = 6
|
||||
brightness_power = 2
|
||||
brightness_color = "#da0205"
|
||||
|
||||
/obj/machinery/light/spot
|
||||
name = "spotlight"
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/turf/simulated/wall/diona/New(var/newloc)
|
||||
..(newloc,"biomass")
|
||||
|
||||
/turf/simulated/wall/diona/attack_generic(var/mob/user, var/damage, var/attack_message)
|
||||
if(istype(user, /mob/living/carbon/alien/diona))
|
||||
if(can_open == WALL_OPENING)
|
||||
return
|
||||
can_open = WALL_CAN_OPEN
|
||||
user.visible_message("<span class='alium'>\The [user] strokes its feelers against \the [src] and the biomass [density ? "moves aside" : "closes up"].</span>")
|
||||
toggle_open(user)
|
||||
sleep(15)
|
||||
if(can_open == WALL_CAN_OPEN) can_open = 0
|
||||
else
|
||||
return ..(user, damage, attack_message)
|
||||
|
||||
/obj/structure/diona
|
||||
icon = 'icons/obj/diona.dmi'
|
||||
anchored = 1
|
||||
density = 1
|
||||
opacity = 0
|
||||
layer = TURF_LAYER + 0.01
|
||||
|
||||
/obj/structure/diona/vines
|
||||
name = "alien vines"
|
||||
desc = "Thick, heavy vines of some sort."
|
||||
icon_state = "vines3"
|
||||
var/growth = 0
|
||||
|
||||
/obj/structure/diona/vines/proc/spread()
|
||||
var/turf/origin = get_turf(src)
|
||||
for(var/turf/T in range(src,2))
|
||||
if(T.density || T == origin || istype(T, /turf/space))
|
||||
continue
|
||||
var/new_growth = 1
|
||||
switch(get_dist(origin,T))
|
||||
if(0)
|
||||
new_growth = 3
|
||||
if(1)
|
||||
new_growth = 2
|
||||
var/obj/structure/diona/vines/existing = locate() in T
|
||||
if(!istype(existing)) existing = PoolOrNew(/obj/structure/diona/vines, T)
|
||||
if(existing.growth < new_growth)
|
||||
existing.growth = new_growth
|
||||
existing.update_icon()
|
||||
|
||||
/obj/structure/diona/vines/update_icon()
|
||||
icon_state = "vines[growth]"
|
||||
|
||||
/obj/structure/diona/bulb
|
||||
name = "glow bulb"
|
||||
desc = "A glowing bulb of some sort."
|
||||
icon_state = "glowbulb"
|
||||
|
||||
/obj/structure/diona/bulb/New(var/newloc)
|
||||
..()
|
||||
set_light(3,3,"#557733")
|
||||
|
||||
/datum/random_map/automata/diona
|
||||
iterations = 3
|
||||
descriptor = "diona gestalt"
|
||||
limit_x = 32
|
||||
limit_y = 32
|
||||
|
||||
wall_type = /turf/simulated/wall/diona
|
||||
floor_type = /turf/simulated/floor/diona
|
||||
|
||||
// This is disgusting.
|
||||
/datum/random_map/automata/diona/proc/search_neighbors_for(var/search_val, var/x, var/y)
|
||||
var/current_cell = get_map_cell(x-1,y-1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x-1,y)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x-1,y+1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x,y-1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x,y+1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x+1,y-1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x+1,y)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
current_cell = get_map_cell(x+1,y+1)
|
||||
if(current_cell && map[current_cell] == search_val) return 1
|
||||
return 0
|
||||
|
||||
/datum/random_map/automata/diona/cleanup()
|
||||
|
||||
// Hollow out the interior spaces.
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!current_cell) continue
|
||||
if(map[current_cell] == WALL_CHAR)
|
||||
if(!search_neighbors_for(FLOOR_CHAR,x,y) && !search_neighbors_for(DOOR_CHAR,x,y) && !(x == 1 || y == 1 || x == limit_x || y == limit_y))
|
||||
map[current_cell] = EMPTY_CHAR
|
||||
|
||||
// Prune exposed floor turfs away from the edges.
|
||||
var/changed = 1
|
||||
while(changed)
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
changed = 0
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!current_cell) continue
|
||||
if(map[current_cell] == EMPTY_CHAR)
|
||||
if((search_neighbors_for(FLOOR_CHAR,x,y)) || (x == 1 || y == 1 || x == limit_x || y == limit_y))
|
||||
map[current_cell] = FLOOR_CHAR
|
||||
changed = 1
|
||||
|
||||
// Count and track the floors.
|
||||
var/list/floor_turfs = list()
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!current_cell) continue
|
||||
if(map[current_cell] == EMPTY_CHAR)
|
||||
floor_turfs |= current_cell
|
||||
|
||||
// Add vine decals.
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!current_cell || map[current_cell] != EMPTY_CHAR) continue
|
||||
if(search_neighbors_for(WALL_CHAR,x,y))
|
||||
map[current_cell] = DOOR_CHAR
|
||||
|
||||
// Add bulbs and doona nymphs.
|
||||
if(floor_turfs.len)
|
||||
var/bulb_count = rand(round(floor_turfs.len/10),round(floor_turfs.len/8))
|
||||
while(floor_turfs.len && bulb_count)
|
||||
var/cell = pick(floor_turfs)
|
||||
floor_turfs -= cell
|
||||
map[cell] = ARTIFACT_CHAR
|
||||
bulb_count--
|
||||
if(floor_turfs.len)
|
||||
var/nymph_count = rand(round(floor_turfs.len/10),round(floor_turfs.len/8))
|
||||
while(floor_turfs.len && nymph_count)
|
||||
var/cell = pick(floor_turfs)
|
||||
floor_turfs -= cell
|
||||
map[cell] = MONSTER_CHAR
|
||||
nymph_count--
|
||||
return
|
||||
|
||||
/datum/random_map/automata/diona/get_appropriate_path(var/value)
|
||||
switch(value)
|
||||
if(EMPTY_CHAR, DOOR_CHAR, MONSTER_CHAR, ARTIFACT_CHAR)
|
||||
return floor_type
|
||||
if(WALL_CHAR)
|
||||
return wall_type
|
||||
|
||||
/datum/random_map/automata/diona/get_additional_spawns(var/value, var/turf/T)
|
||||
|
||||
if(value != FLOOR_CHAR)
|
||||
for(var/thing in T)
|
||||
if(istype(thing, /atom))
|
||||
var/atom/A = thing
|
||||
if(A.simulated)
|
||||
continue
|
||||
qdel(thing)
|
||||
|
||||
switch(value)
|
||||
if(ARTIFACT_CHAR)
|
||||
PoolOrNew(/obj/structure/diona/bulb,T)
|
||||
if(MONSTER_CHAR)
|
||||
spawn_diona_nymph(T)
|
||||
if(DOOR_CHAR)
|
||||
var/obj/structure/diona/vines/V = PoolOrNew(/obj/structure/diona/vines,T)
|
||||
V.growth = 3
|
||||
V.update_icon()
|
||||
spawn(1)
|
||||
V.spread()
|
||||
@@ -7,7 +7,7 @@
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!within_bounds(current_cell))
|
||||
if(!current_cell)
|
||||
continue
|
||||
if(x == 1 || y == 1 || x == limit_x || y == limit_y)
|
||||
map[current_cell] = WALL_CHAR
|
||||
@@ -19,7 +19,7 @@
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!within_bounds(current_cell))
|
||||
if(!current_cell)
|
||||
continue
|
||||
if(!(x == 1 || y == 1 || x == limit_x || y == limit_y))
|
||||
continue
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
var/global/list/datum/supply_drop_loot/supply_drop
|
||||
|
||||
/proc/supply_drop_random_loot_types()
|
||||
if(!supply_drop)
|
||||
supply_drop = init_subtypes(/datum/supply_drop_loot)
|
||||
supply_drop = dd_sortedObjectList(supply_drop)
|
||||
return supply_drop
|
||||
|
||||
/datum/supply_drop_loot
|
||||
var/name = ""
|
||||
var/container = null
|
||||
var/list/contents = null
|
||||
|
||||
/datum/supply_drop_loot/proc/contents()
|
||||
return contents
|
||||
|
||||
/datum/supply_drop_loot/proc/drop(turf/T)
|
||||
var/C = container ? new container(T) : T
|
||||
for(var/content in contents())
|
||||
new content(C)
|
||||
|
||||
/datum/supply_drop_loot/dd_SortValue()
|
||||
return name
|
||||
|
||||
/datum/supply_drop_loot/supermatter
|
||||
name = "Supermatter"
|
||||
/datum/supply_drop_loot/supermatter/New()
|
||||
..()
|
||||
contents = list(/obj/machinery/power/supermatter)
|
||||
|
||||
/datum/supply_drop_loot/lasers
|
||||
name = "Lasers"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/lasers/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/weapon/gun/energy/laser,
|
||||
/obj/item/weapon/gun/energy/laser,
|
||||
/obj/item/weapon/gun/energy/sniperrifle,
|
||||
/obj/item/weapon/gun/energy/ionrifle)
|
||||
|
||||
/datum/supply_drop_loot/ballistics
|
||||
name = "Ballistics"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/ballistics/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/weapon/gun/projectile/sec,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550,
|
||||
/obj/item/weapon/gun/projectile/automatic/z8)
|
||||
|
||||
/datum/supply_drop_loot/ballistics
|
||||
name = "Ballistics"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/ballistics/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/weapon/gun/projectile/sec,
|
||||
/obj/item/weapon/gun/projectile/shotgun/doublebarrel,
|
||||
/obj/item/weapon/gun/projectile/shotgun/pump/combat,
|
||||
/obj/item/weapon/gun/projectile/automatic/wt550,
|
||||
/obj/item/weapon/gun/projectile/automatic/z8)
|
||||
|
||||
/datum/supply_drop_loot/seeds
|
||||
name = "Seeds"
|
||||
container = /obj/structure/closet/crate
|
||||
/datum/supply_drop_loot/seeds/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/seeds/chiliseed,
|
||||
/obj/item/seeds/berryseed,
|
||||
/obj/item/seeds/cornseed,
|
||||
/obj/item/seeds/eggplantseed,
|
||||
/obj/item/seeds/tomatoseed,
|
||||
/obj/item/seeds/appleseed,
|
||||
/obj/item/seeds/soyaseed,
|
||||
/obj/item/seeds/wheatseed,
|
||||
/obj/item/seeds/carrotseed,
|
||||
/obj/item/seeds/lemonseed,
|
||||
/obj/item/seeds/orangeseed,
|
||||
/obj/item/seeds/grassseed,
|
||||
/obj/item/seeds/sunflowerseed,
|
||||
/obj/item/seeds/chantermycelium,
|
||||
/obj/item/seeds/potatoseed,
|
||||
/obj/item/seeds/sugarcaneseed)
|
||||
|
||||
/datum/supply_drop_loot/food
|
||||
name = "Food"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/food/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/weapon/reagent_containers/food/condiment/flour,
|
||||
/obj/item/weapon/reagent_containers/food/condiment/flour,
|
||||
/obj/item/weapon/reagent_containers/food/condiment/flour,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/milk,
|
||||
/obj/item/weapon/reagent_containers/food/drinks/milk,
|
||||
/obj/item/weapon/storage/fancy/egg_box,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/tofu,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/tofu,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat,
|
||||
/obj/item/weapon/reagent_containers/food/snacks/meat)
|
||||
|
||||
/datum/supply_drop_loot/armour
|
||||
name = "Armour"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/armour/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/head/helmet/riot,
|
||||
/obj/item/clothing/suit/armor/riot,
|
||||
/obj/item/clothing/suit/storage/vest,
|
||||
/obj/item/clothing/suit/storage/vest,
|
||||
/obj/item/clothing/suit/storage/vest/heavy,
|
||||
/obj/item/clothing/suit/storage/vest/heavy,
|
||||
/obj/item/clothing/suit/armor/laserproof,
|
||||
/obj/item/clothing/suit/armor/bulletproof)
|
||||
|
||||
/datum/supply_drop_loot/materials
|
||||
name = "Materials"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/materials/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/glass,
|
||||
/obj/item/stack/material/glass,
|
||||
/obj/item/stack/material/wood,
|
||||
/obj/item/stack/material/plastic,
|
||||
/obj/item/stack/material/glass/reinforced,
|
||||
/obj/item/stack/material/plasteel)
|
||||
|
||||
/datum/supply_drop_loot/medical
|
||||
name = "Medical"
|
||||
container = /obj/structure/closet/crate/medical
|
||||
/datum/supply_drop_loot/medical/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/weapon/storage/firstaid/regular,
|
||||
/obj/item/weapon/storage/firstaid/fire,
|
||||
/obj/item/weapon/storage/firstaid/toxin,
|
||||
/obj/item/weapon/storage/firstaid/o2,
|
||||
/obj/item/weapon/storage/firstaid/adv,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/antitoxin,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/inaprovaline,
|
||||
/obj/item/weapon/reagent_containers/glass/bottle/stoxin,
|
||||
/obj/item/weapon/storage/box/syringes,
|
||||
/obj/item/weapon/storage/box/autoinjectors)
|
||||
|
||||
/datum/supply_drop_loot/power
|
||||
name = "Power"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/power/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/steel,
|
||||
/obj/item/stack/material/glass,
|
||||
/obj/item/stack/material/glass,
|
||||
/obj/item/stack/material/wood,
|
||||
/obj/item/stack/material/plastic,
|
||||
/obj/item/stack/material/glass/reinforced,
|
||||
/obj/item/stack/material/plasteel)
|
||||
|
||||
/datum/supply_drop_loot/hydroponics
|
||||
name = "Hydroponics"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/hydroponics/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/machinery/portable_atmospherics/hydroponics,
|
||||
/obj/machinery/portable_atmospherics/hydroponics,
|
||||
/obj/machinery/portable_atmospherics/hydroponics)
|
||||
|
||||
/datum/supply_drop_loot/power
|
||||
name = "Power"
|
||||
container = /obj/structure/largecrate
|
||||
/datum/supply_drop_loot/power/New()
|
||||
..()
|
||||
contents = list(
|
||||
/obj/machinery/power/port_gen/pacman,
|
||||
/obj/machinery/power/port_gen/pacman/super,
|
||||
/obj/machinery/power/port_gen/pacman/mrs)
|
||||
|
||||
/datum/supply_drop_loot/power/contents()
|
||||
return list(pick(contents))
|
||||
@@ -0,0 +1,227 @@
|
||||
#define SD_FLOOR_TILE 0
|
||||
#define SD_WALL_TILE 1
|
||||
#define SD_DOOR_TILE 2
|
||||
#define SD_EMPTY_TILE 3
|
||||
#define SD_SUPPLY_TILE 7
|
||||
|
||||
/datum/random_map/droppod
|
||||
descriptor = "drop pod"
|
||||
initial_wall_cell = 0
|
||||
limit_x = 3
|
||||
limit_y = 3
|
||||
preserve_map = 0
|
||||
|
||||
wall_type = /turf/simulated/wall/titanium
|
||||
floor_type = /turf/simulated/floor/reinforced
|
||||
var/list/supplied_drop_types = list()
|
||||
var/door_type = /obj/structure/droppod_door
|
||||
var/drop_type = /mob/living/simple_animal/parrot
|
||||
var/auto_open_doors
|
||||
|
||||
var/placement_explosion_dev = 1
|
||||
var/placement_explosion_heavy = 2
|
||||
var/placement_explosion_light = 6
|
||||
var/placement_explosion_flash = 4
|
||||
|
||||
/datum/random_map/droppod/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly, var/do_not_apply, var/do_not_announce, var/supplied_drop, var/list/supplied_drops, var/automated)
|
||||
|
||||
if(supplied_drop)
|
||||
drop_type = supplied_drop
|
||||
else if(islist(supplied_drops) && supplied_drops.len)
|
||||
supplied_drop_types = supplied_drops
|
||||
drop_type = "custom"
|
||||
if(automated)
|
||||
auto_open_doors = 1
|
||||
|
||||
//Make sure there is a clear midpoint.
|
||||
if(limit_x % 2 == 0) limit_x++
|
||||
if(limit_y % 2 == 0) limit_y++
|
||||
..()
|
||||
|
||||
/datum/random_map/droppod/generate_map()
|
||||
|
||||
// No point calculating these 200 times.
|
||||
var/x_midpoint = n_ceil(limit_x / 2)
|
||||
var/y_midpoint = n_ceil(limit_y / 2)
|
||||
|
||||
// Draw walls/floors/doors.
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!current_cell)
|
||||
continue
|
||||
|
||||
var/on_x_bound = (x == 1 || x == limit_x)
|
||||
var/on_y_bound = (y == 1 || y == limit_x)
|
||||
var/draw_corners = (limit_x < 5 && limit_y < 5)
|
||||
if(on_x_bound || on_y_bound)
|
||||
// Draw access points in midpoint of each wall.
|
||||
if(x == x_midpoint || y == y_midpoint)
|
||||
map[current_cell] = SD_DOOR_TILE
|
||||
// Draw the actual walls.
|
||||
else if(draw_corners || (!on_x_bound || !on_y_bound))
|
||||
map[current_cell] = SD_WALL_TILE
|
||||
//Don't draw the far corners on large pods.
|
||||
else
|
||||
map[current_cell] = SD_EMPTY_TILE
|
||||
else
|
||||
// Fill in the corners.
|
||||
if((x == 2 || x == (limit_x-1)) && (y == 2 || y == (limit_y-1)))
|
||||
map[current_cell] = SD_WALL_TILE
|
||||
// Fill in EVERYTHING ELSE.
|
||||
else
|
||||
map[current_cell] = SD_FLOOR_TILE
|
||||
|
||||
// Draw the drop contents.
|
||||
var/current_cell = get_map_cell(x_midpoint,y_midpoint)
|
||||
if(current_cell)
|
||||
map[current_cell] = SD_SUPPLY_TILE
|
||||
return 1
|
||||
|
||||
/datum/random_map/droppod/apply_to_map()
|
||||
if(placement_explosion_dev || placement_explosion_heavy || placement_explosion_light || placement_explosion_flash)
|
||||
var/turf/T = locate((origin_x + n_ceil(limit_x / 2)-1), (origin_y + n_ceil(limit_y / 2)-1), origin_z)
|
||||
if(istype(T))
|
||||
explosion(T, placement_explosion_dev, placement_explosion_heavy, placement_explosion_light, placement_explosion_flash)
|
||||
sleep(15) // Let the explosion finish proccing before we ChangeTurf(), otherwise it might destroy our spawned objects.
|
||||
return ..()
|
||||
|
||||
/datum/random_map/droppod/get_appropriate_path(var/value)
|
||||
if(value == SD_FLOOR_TILE || value == SD_SUPPLY_TILE)
|
||||
return floor_type
|
||||
else if(value == SD_WALL_TILE)
|
||||
return wall_type
|
||||
else if(value == SD_DOOR_TILE )
|
||||
return wall_type
|
||||
return null
|
||||
|
||||
// Pods are circular. Get the direction this object is facing from the center of the pod.
|
||||
/datum/random_map/droppod/get_spawn_dir(var/x, var/y)
|
||||
var/x_midpoint = n_ceil(limit_x / 2)
|
||||
var/y_midpoint = n_ceil(limit_y / 2)
|
||||
if(x == x_midpoint && y == y_midpoint)
|
||||
return null
|
||||
var/turf/target = locate(origin_x+x-1, origin_y+y-1, origin_z)
|
||||
var/turf/middle = locate(origin_x+x_midpoint-1, origin_y+y_midpoint-1, origin_z)
|
||||
if(!istype(target) || !istype(middle))
|
||||
return null
|
||||
return get_dir(middle, target)
|
||||
|
||||
/datum/random_map/droppod/get_additional_spawns(var/value, var/turf/T, var/spawn_dir)
|
||||
|
||||
// Splatter anything under us that survived the explosion.
|
||||
if(value != SD_EMPTY_TILE && T.contents.len)
|
||||
for(var/atom/movable/AM in T)
|
||||
if(AM.simulated && !istype(AM, /mob/dead))
|
||||
qdel(AM)
|
||||
|
||||
// Also spawn doors and loot.
|
||||
if(value == SD_DOOR_TILE)
|
||||
var/obj/structure/S = new door_type(T, auto_open_doors)
|
||||
S.set_dir(spawn_dir)
|
||||
|
||||
else if(value == SD_SUPPLY_TILE)
|
||||
get_spawned_drop(T)
|
||||
|
||||
/datum/random_map/droppod/proc/get_spawned_drop(var/turf/T)
|
||||
var/obj/structure/bed/chair/C = new(T)
|
||||
C.set_light(3, l_color = "#CC0000")
|
||||
var/mob/living/drop
|
||||
// This proc expects a list of mobs to be passed to the spawner.
|
||||
// Use the supply pod if you don't want to drop mobs.
|
||||
// Mobs will not double up; if you want multiple mobs, you
|
||||
// will need multiple drop tiles.
|
||||
if(islist(supplied_drop_types) && supplied_drop_types.len)
|
||||
while(supplied_drop_types.len)
|
||||
drop = pick(supplied_drop_types)
|
||||
supplied_drop_types -= drop
|
||||
if(istype(drop))
|
||||
drop.tag = null
|
||||
if(drop.buckled)
|
||||
drop.buckled = null
|
||||
drop.forceMove(T)
|
||||
else if(ispath(drop_type))
|
||||
drop = new drop_type(T)
|
||||
if(istype(drop))
|
||||
if(drop.buckled)
|
||||
drop.buckled = null
|
||||
drop.forceMove(T)
|
||||
|
||||
/datum/admins/proc/call_drop_pod()
|
||||
set category = "Fun"
|
||||
set desc = "Call an immediate drop pod on your location."
|
||||
set name = "Call Drop Pod"
|
||||
|
||||
if(!check_rights(R_FUN)) return
|
||||
|
||||
var/client/selected_player
|
||||
var/mob/living/spawned_mob
|
||||
var/list/spawned_mobs = list()
|
||||
|
||||
var/spawn_path = input("Select a mob type.", "Drop Pod Selection", null) as null|anything in typesof(/mob/living)-/mob/living
|
||||
if(!spawn_path)
|
||||
return
|
||||
|
||||
if(alert("Do you wish the mob to have a player?",,"No","Yes") == "No")
|
||||
var/spawn_count = input("How many mobs do you wish the pod to contain?", "Drop Pod Selection", null) as num
|
||||
if(spawn_count <= 0)
|
||||
return
|
||||
for(var/i=0;i<spawn_count;i++)
|
||||
var/mob/living/M = new spawn_path()
|
||||
M.tag = "awaiting drop"
|
||||
spawned_mobs |= M
|
||||
else
|
||||
var/list/candidates = list()
|
||||
for(var/client/player in clients)
|
||||
if(player.mob && istype(player.mob, /mob/dead/observer))
|
||||
candidates |= player
|
||||
|
||||
if(!candidates.len)
|
||||
usr << "There are no candidates for a drop pod launch."
|
||||
return
|
||||
|
||||
// Get a player and a mob type.
|
||||
selected_player = input("Select a player.", "Drop Pod Selection", null) as null|anything in candidates
|
||||
if(!selected_player)
|
||||
return
|
||||
|
||||
// Spawn the mob in nullspace for now.
|
||||
spawned_mob = new spawn_path()
|
||||
spawned_mob.tag = "awaiting drop"
|
||||
|
||||
// Equip them, if they are human and it is desirable.
|
||||
if(istype(spawned_mob, /mob/living/carbon/human))
|
||||
var/antag_type = input("Select an equipment template to use or cancel for nude.", null) as null|anything in all_antag_types
|
||||
if(antag_type)
|
||||
var/datum/antagonist/A = all_antag_types[antag_type]
|
||||
A.equip(spawned_mob)
|
||||
|
||||
if(alert("Are you SURE you wish to deploy this drop pod? It will cause a sizable explosion and gib anyone underneath it.",,"No","Yes") == "No")
|
||||
if(spawned_mob)
|
||||
qdel(spawned_mob)
|
||||
if(spawned_mobs.len)
|
||||
for(var/mob/living/M in spawned_mobs)
|
||||
spawned_mobs -= M
|
||||
M.tag = null
|
||||
qdel(M)
|
||||
spawned_mobs.Cut()
|
||||
return
|
||||
|
||||
// Chuck them into the pod.
|
||||
var/automatic_pod
|
||||
if(spawned_mob && selected_player)
|
||||
if(selected_player.mob.mind)
|
||||
selected_player.mob.mind.transfer_to(spawned_mob)
|
||||
else
|
||||
spawned_mob.ckey = selected_player.mob.ckey
|
||||
spawned_mobs = list(spawned_mob)
|
||||
message_admins("[key_name(usr)] dropped a pod containing \the [spawned_mob] ([spawned_mob.key]) at ([usr.x],[usr.y],[usr.z])")
|
||||
log_admin("[key_name(usr)] dropped a pod containing \the [spawned_mob] ([spawned_mob.key]) at ([usr.x],[usr.y],[usr.z])")
|
||||
else if(spawned_mobs.len)
|
||||
automatic_pod = 1
|
||||
message_admins("[key_name(usr)] dropped a pod containing [spawned_mobs.len] [spawned_mobs[1]] at ([usr.x],[usr.y],[usr.z])")
|
||||
log_admin("[key_name(usr)] dropped a pod containing [spawned_mobs.len] [spawned_mobs[1]] at ([usr.x],[usr.y],[usr.z])")
|
||||
else
|
||||
return
|
||||
|
||||
new /datum/random_map/droppod(null, usr.x-1, usr.y-1, usr.z, supplied_drops = spawned_mobs, automated = automatic_pod)
|
||||
@@ -0,0 +1,80 @@
|
||||
/obj/structure/droppod_door
|
||||
name = "pod door"
|
||||
desc = "A drop pod door. Opens rapidly using explosive bolts."
|
||||
icon = 'icons/obj/structures.dmi'
|
||||
icon_state = "droppod_door_closed"
|
||||
anchored = 1
|
||||
density = 1
|
||||
opacity = 1
|
||||
layer = TURF_LAYER + 0.1
|
||||
var/deploying
|
||||
var/deployed
|
||||
|
||||
/obj/structure/droppod_door/New(var/newloc, var/autoopen)
|
||||
..(newloc)
|
||||
if(autoopen)
|
||||
spawn(100)
|
||||
deploy()
|
||||
|
||||
/obj/structure/droppod_door/attack_ai(var/mob/user)
|
||||
if(!user.Adjacent(src))
|
||||
return
|
||||
attack_hand(user)
|
||||
|
||||
/obj/structure/droppod_door/attack_generic(var/mob/user)
|
||||
attack_hand(user)
|
||||
|
||||
/obj/structure/droppod_door/attack_hand(var/mob/user)
|
||||
if(deploying) return
|
||||
user << "<span class='danger'>You prime the explosive bolts. Better get clear!</span>"
|
||||
sleep(30)
|
||||
deploy()
|
||||
|
||||
/obj/structure/droppod_door/proc/deploy()
|
||||
if(deployed)
|
||||
return
|
||||
|
||||
deployed = 1
|
||||
visible_message("<span class='danger'>The explosive bolts on \the [src] detonate, throwing it open!</span>")
|
||||
playsound(src.loc, 'sound/effects/bang.ogg', 50, 1, 5)
|
||||
|
||||
// This is shit but it will do for the sake of testing.
|
||||
for(var/obj/structure/droppod_door/D in range(5,src))
|
||||
if(D.deployed)
|
||||
continue
|
||||
D.deploy()
|
||||
|
||||
// Overwrite turfs.
|
||||
var/turf/origin = get_turf(src)
|
||||
origin.ChangeTurf(/turf/simulated/floor/reinforced)
|
||||
origin.set_light(0) // Forcing updates
|
||||
var/turf/T = get_step(origin, src.dir)
|
||||
T.ChangeTurf(/turf/simulated/floor/reinforced)
|
||||
T.set_light(0) // Forcing updates
|
||||
|
||||
// Destroy turf contents.
|
||||
for(var/obj/O in origin)
|
||||
if(!O.simulated)
|
||||
continue
|
||||
qdel(O) //crunch
|
||||
for(var/obj/O in T)
|
||||
if(!O.simulated)
|
||||
continue
|
||||
qdel(O) //crunch
|
||||
|
||||
// Hurl the mobs away.
|
||||
for(var/mob/living/M in T)
|
||||
M.throw_at(get_edge_target_turf(T,src.dir),rand(0,3),50)
|
||||
for(var/mob/living/M in origin)
|
||||
M.throw_at(get_edge_target_turf(origin,src.dir),rand(0,3),50)
|
||||
|
||||
// Create a decorative ramp bottom and flatten out our current ramp.
|
||||
density = 0
|
||||
opacity = 0
|
||||
icon_state = "ramptop"
|
||||
var/obj/structure/droppod_door/door_bottom = new(T)
|
||||
door_bottom.deployed = 1
|
||||
door_bottom.density = 0
|
||||
door_bottom.opacity = 0
|
||||
door_bottom.dir = src.dir
|
||||
door_bottom.icon_state = "rampbottom"
|
||||
@@ -0,0 +1,93 @@
|
||||
/datum/random_map/droppod/supply
|
||||
descriptor = "supply drop"
|
||||
limit_x = 5
|
||||
limit_y = 5
|
||||
|
||||
placement_explosion_light = 7
|
||||
placement_explosion_flash = 5
|
||||
|
||||
// UNLIKE THE DROP POD, this map deals ENTIRELY with strings and types.
|
||||
// Drop type is a string representing a mode rather than an atom or path.
|
||||
// supplied_drop_types is a list of types to spawn in the pod.
|
||||
/datum/random_map/droppod/supply/get_spawned_drop(var/turf/T)
|
||||
|
||||
if(!drop_type) drop_type = pick(supply_drop_random_loot_types())
|
||||
|
||||
if(drop_type == "custom")
|
||||
if(supplied_drop_types.len)
|
||||
var/obj/structure/largecrate/C = locate() in T
|
||||
for(var/drop_type in supplied_drop_types)
|
||||
var/atom/movable/A = new drop_type(T)
|
||||
if(!istype(A, /mob))
|
||||
if(!C) C = new(T)
|
||||
C.contents |= A
|
||||
return
|
||||
else
|
||||
drop_type = pick(supply_drop_random_loot_types())
|
||||
|
||||
if(istype(drop_type, /datum/supply_drop_loot))
|
||||
var/datum/supply_drop_loot/SDL = drop_type
|
||||
SDL.drop(T)
|
||||
else
|
||||
error("Unhandled drop type: [drop_type]")
|
||||
|
||||
|
||||
/datum/admins/proc/call_supply_drop()
|
||||
set category = "Fun"
|
||||
set desc = "Call an immediate supply drop on your location."
|
||||
set name = "Call Supply Drop"
|
||||
|
||||
if(!check_rights(R_FUN)) return
|
||||
|
||||
var/chosen_loot_type
|
||||
var/list/chosen_loot_types
|
||||
var/choice = alert("Do you wish to supply a custom loot list?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
chosen_loot_types = list()
|
||||
|
||||
choice = alert("Do you wish to add mobs?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
while(1)
|
||||
var/adding_loot_type = input("Select a new loot path. Cancel to finish.", "Loot Selection", null) as null|anything in typesof(/mob/living)
|
||||
if(!adding_loot_type)
|
||||
break
|
||||
chosen_loot_types |= adding_loot_type
|
||||
choice = alert("Do you wish to add structures or machines?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
while(1)
|
||||
var/adding_loot_type = input("Select a new loot path. Cancel to finish.", "Loot Selection", null) as null|anything in typesof(/obj) - typesof(/obj/item)
|
||||
if(!adding_loot_type)
|
||||
break
|
||||
chosen_loot_types |= adding_loot_type
|
||||
choice = alert("Do you wish to add any non-weapon items?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
while(1)
|
||||
var/adding_loot_type = input("Select a new loot path. Cancel to finish.", "Loot Selection", null) as null|anything in typesof(/obj/item) - typesof(/obj/item/weapon)
|
||||
if(!adding_loot_type)
|
||||
break
|
||||
chosen_loot_types |= adding_loot_type
|
||||
|
||||
choice = alert("Do you wish to add weapons?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
while(1)
|
||||
var/adding_loot_type = input("Select a new loot path. Cancel to finish.", "Loot Selection", null) as null|anything in typesof(/obj/item/weapon)
|
||||
if(!adding_loot_type)
|
||||
break
|
||||
chosen_loot_types |= adding_loot_type
|
||||
choice = alert("Do you wish to add ABSOLUTELY ANYTHING ELSE? (you really shouldn't need to)",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
while(1)
|
||||
var/adding_loot_type = input("Select a new loot path. Cancel to finish.", "Loot Selection", null) as null|anything in typesof(/atom/movable)
|
||||
if(!adding_loot_type)
|
||||
break
|
||||
chosen_loot_types |= adding_loot_type
|
||||
else
|
||||
choice = alert("Do you wish to specify a loot type?",,"No","Yes")
|
||||
if(choice == "Yes")
|
||||
chosen_loot_type = input("Select a loot type.", "Loot Selection", null) as null|anything in supply_drop_random_loot_types()
|
||||
|
||||
choice = alert("Are you SURE you wish to deploy this supply drop? It will cause a sizable explosion and gib anyone underneath it.",,"No","Yes")
|
||||
if(choice == "No")
|
||||
return
|
||||
log_admin("[key_name(usr)] dropped supplies at ([usr.x],[usr.y],[usr.z])")
|
||||
new /datum/random_map/droppod/supply(null, usr.x-2, usr.y-2, usr.z, supplied_drops = chosen_loot_types, supplied_drop = chosen_loot_type)
|
||||
@@ -38,8 +38,8 @@
|
||||
|
||||
/datum/random_map/noise/ore/apply_to_turf(var/x,var/y)
|
||||
|
||||
var/tx = (origin_x+(x-1))*chunk_size
|
||||
var/ty = (origin_y+(y-1))*chunk_size
|
||||
var/tx = ((origin_x-1)+x)*chunk_size
|
||||
var/ty = ((origin_y-1)+y)*chunk_size
|
||||
|
||||
for(var/i=0,i<chunk_size,i++)
|
||||
for(var/j=0,j<chunk_size,j++)
|
||||
|
||||
@@ -17,6 +17,7 @@ var/global/list/map_count = list()
|
||||
var/limit_x = 128 // Default x size.
|
||||
var/limit_y = 128 // Default y size.
|
||||
var/auto_apply = 1
|
||||
var/preserve_map = 1
|
||||
|
||||
// Turf paths.
|
||||
var/wall_type = /turf/simulated/wall
|
||||
@@ -38,12 +39,10 @@ var/global/list/map_count = list()
|
||||
else
|
||||
map_count[descriptor]++
|
||||
name = "[descriptor] #[map_count[descriptor]]"
|
||||
random_maps[name] = src
|
||||
if(preserve_map) random_maps[name] = src
|
||||
|
||||
// Get origins for applying the map later.
|
||||
origin_x = (!isnull(tx) ? tx : 1)
|
||||
origin_y = (!isnull(ty) ? ty : 1)
|
||||
origin_z = (!isnull(tz) ? tz : 1)
|
||||
set_origins(tx, ty, tz)
|
||||
if(tlx) limit_x = tlx
|
||||
if(tly) limit_y = tly
|
||||
|
||||
@@ -69,6 +68,8 @@ var/global/list/map_count = list()
|
||||
if(!do_not_announce) admin_notice("<span class='danger'>[capitalize(name)] failed to generate ([round(0.1*(world.timeofday-start_time),0.1)] seconds): could not produce sane map.</span>", R_DEBUG)
|
||||
|
||||
/datum/random_map/proc/get_map_cell(var/x,var/y)
|
||||
if(!islist(map))
|
||||
set_map_size()
|
||||
var/cell = ((y-1)*limit_x)+x
|
||||
if((cell < 1) || (cell > map.len))
|
||||
return null
|
||||
@@ -103,16 +104,11 @@ var/global/list/map_count = list()
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(within_bounds(current_cell))
|
||||
if(current_cell)
|
||||
dat += get_map_char(map[current_cell])
|
||||
dat += "<br>"
|
||||
user << "[dat]+------+</code>"
|
||||
|
||||
/datum/random_map/proc/within_bounds(var/val)
|
||||
if(!islist(map))
|
||||
set_map_size()
|
||||
return (val>0) && (val<=map.len)
|
||||
|
||||
/datum/random_map/proc/set_map_size()
|
||||
map = list()
|
||||
map.len = limit_x * limit_y
|
||||
@@ -148,29 +144,37 @@ var/global/list/map_count = list()
|
||||
/datum/random_map/proc/check_map_sanity()
|
||||
return 1
|
||||
|
||||
/datum/random_map/proc/apply_to_map(var/tx, var/ty, var/tz)
|
||||
if(!tx) tx = isnull(origin_x) ? 1 : origin_x
|
||||
if(!ty) ty = isnull(origin_y) ? 1 : origin_y
|
||||
if(!tz) tz = isnull(origin_z) ? 1 : origin_z
|
||||
/datum/random_map/proc/set_origins(var/tx, var/ty, var/tz)
|
||||
origin_x = tx ? tx : 1
|
||||
origin_y = ty ? ty : 1
|
||||
origin_z = tz ? tz : 1
|
||||
|
||||
/datum/random_map/proc/apply_to_map()
|
||||
if(!origin_x) origin_x = 1
|
||||
if(!origin_y) origin_y = 1
|
||||
if(!origin_z) origin_z = 1
|
||||
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
if(!priority_process) sleep(-1)
|
||||
apply_to_turf((tx-1)+x,(ty-1)+y,tz)
|
||||
apply_to_turf(x,y)
|
||||
|
||||
/datum/random_map/proc/apply_to_turf(var/x,var/y,var/z)
|
||||
/datum/random_map/proc/apply_to_turf(var/x,var/y)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!within_bounds(current_cell))
|
||||
if(!current_cell)
|
||||
return 0
|
||||
var/turf/T = locate(x,y,z)
|
||||
var/turf/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z)
|
||||
if(!T || (target_turf_type && !istype(T,target_turf_type)))
|
||||
return 0
|
||||
var/newpath = get_appropriate_path(map[current_cell])
|
||||
if(newpath)
|
||||
T.ChangeTurf(newpath)
|
||||
get_additional_spawns(map[current_cell],T)
|
||||
get_additional_spawns(map[current_cell],T,get_spawn_dir(x, y))
|
||||
return T
|
||||
|
||||
/datum/random_map/proc/get_spawn_dir()
|
||||
return 0
|
||||
|
||||
/datum/random_map/proc/get_appropriate_path(var/value)
|
||||
switch(value)
|
||||
if(FLOOR_CHAR)
|
||||
@@ -193,7 +197,7 @@ var/global/list/map_count = list()
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
var/current_cell = get_map_cell(x,y)
|
||||
if(!within_bounds(current_cell))
|
||||
if(!current_cell)
|
||||
continue
|
||||
if(tx+x > target_map.limit_x)
|
||||
continue
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
tz = !isnull(tz) ? tz : T.z
|
||||
message_admins("[key_name_admin(usr)] has applied [M.name] at x[tx],y[ty],z[tz].")
|
||||
log_admin("[key_name(usr)] has applied [M.name] at x[tx],y[ty],z[tz].")
|
||||
M.apply_to_map(tx,ty,tz)
|
||||
M.set_origins(tx,ty,tz)
|
||||
M.apply_to_map()
|
||||
|
||||
/client/proc/overlay_random_map()
|
||||
set category = "Debug"
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
/datum/reagent/cryoxadone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
if(M.bodytemperature < 170)
|
||||
M.adjustCloneLoss(-30 * removed)
|
||||
M.adjustOxyLoss(-3 * removed)
|
||||
M.adjustOxyLoss(-30 * removed)
|
||||
M.heal_organ_damage(30 * removed, 30 * removed)
|
||||
M.adjustToxLoss(-30 * removed)
|
||||
|
||||
|
||||
@@ -307,7 +307,7 @@
|
||||
if(material)
|
||||
for(var/i = 1 to 4)
|
||||
I = image(icon, "[material.icon_base]_[connections[i]]", dir = 1<<(i-1))
|
||||
I.color = material.icon_colour
|
||||
if(material.icon_colour) I.color = material.icon_colour
|
||||
I.alpha = 255 * material.opacity
|
||||
overlays += I
|
||||
|
||||
@@ -415,9 +415,16 @@
|
||||
connections = dirs_to_corner_states(connection_dirs)
|
||||
|
||||
#define CORNER_NONE 0
|
||||
#define CORNER_CLOCKWISE 1
|
||||
#define CORNER_COUNTERCLOCKWISE 1
|
||||
#define CORNER_DIAGONAL 2
|
||||
#define CORNER_COUNTERCLOCKWISE 4
|
||||
#define CORNER_CLOCKWISE 4
|
||||
|
||||
/*
|
||||
turn() is weird:
|
||||
turn(icon, angle) turns icon by angle degrees clockwise
|
||||
turn(matrix, angle) turns matrix by angle degrees clockwise
|
||||
turn(dir, angle) turns dir by angle degrees counter-clockwise
|
||||
*/
|
||||
|
||||
/proc/dirs_to_corner_states(list/dirs)
|
||||
if(!istype(dirs)) return
|
||||
@@ -430,14 +437,14 @@
|
||||
if(dir in dirs)
|
||||
. |= CORNER_DIAGONAL
|
||||
if(turn(dir,45) in dirs)
|
||||
. |= CORNER_CLOCKWISE
|
||||
if(turn(dir,-45) in dirs)
|
||||
. |= CORNER_COUNTERCLOCKWISE
|
||||
if(turn(dir,-45) in dirs)
|
||||
. |= CORNER_CLOCKWISE
|
||||
ret[i] = "[.]"
|
||||
|
||||
return ret
|
||||
|
||||
#undef CORNER_NONE
|
||||
#undef CORNER_EASTWEST
|
||||
#undef CORNER_COUNTERCLOCKWISE
|
||||
#undef CORNER_DIAGONAL
|
||||
#undef CORNER_NORTHSOUTH
|
||||
#undef CORNER_CLOCKWISE
|
||||
|
||||
@@ -97,15 +97,15 @@
|
||||
|
||||
|
||||
/datum/gas_mixture/proc/equalize(datum/gas_mixture/sharer)
|
||||
for(var/g in sharer.gas)
|
||||
var/our_heatcap = heat_capacity()
|
||||
var/share_heatcap = sharer.heat_capacity()
|
||||
|
||||
for(var/g in gas|sharer.gas)
|
||||
var/comb = gas[g] + sharer.gas[g]
|
||||
comb /= volume + sharer.volume
|
||||
gas[g] = comb * volume
|
||||
sharer.gas[g] = comb * sharer.volume
|
||||
|
||||
var/our_heatcap = heat_capacity()
|
||||
var/share_heatcap = sharer.heat_capacity()
|
||||
|
||||
if(our_heatcap + share_heatcap)
|
||||
temperature = ((temperature * our_heatcap) + (sharer.temperature * share_heatcap)) / (our_heatcap + share_heatcap)
|
||||
sharer.temperature = temperature
|
||||
|
||||
Reference in New Issue
Block a user