# Conflicts:
#	.gitignore
#	vorestation.dme
This commit is contained in:
Kelshark
2017-02-18 09:40:18 -05:00
117 changed files with 3371 additions and 321 deletions

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ cfg/
code/game/gamemodes/technomancer/spells/projectile/overload.dm code/game/gamemodes/technomancer/spells/projectile/overload.dm
code/game/gamemodes/technomancer/spells/projectile/overload.dm code/game/gamemodes/technomancer/spells/projectile/overload.dm
code/modules/client/preference_setup/loadout/loadout_xeno.dm code/modules/client/preference_setup/loadout/loadout_xeno.dm
temp.dmi
/maps/RandomZLevels/backup/blackmarketpackers.dmm /maps/RandomZLevels/backup/blackmarketpackers.dmm
/maps/backup/virgo-1.dmm /maps/backup/virgo-1.dmm
/maps/backup/virgo-2.dmm /maps/backup/virgo-2.dmm

View File

@@ -0,0 +1,10 @@
//Some defines for the rogue miner.
#define RM_STARTING_DIFF 100
#define RM_DIFF_DECAY_TIME 18000
#define RM_DIFF_DECAY_AMT -50
#define RM_DIFF_VALUE_MOB 10
#define RM_DIFF_VALUE_MOB_HARD 15
#define RM_DIFF_VALUE_MOB_BOSS 100
#define RM_DIFF_VALUE_ORE 5

View File

@@ -190,7 +190,7 @@ var/list/gamemode_cache = list()
var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle var/list/admin_levels= list(2) // Defines which Z-levels which are for admin functionality, for example including such areas as Central Command and the Syndicate Shuttle
var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect var/list/contact_levels = list(1, 5) // Defines which Z-levels which, for example, a Code Red announcement may affect
var/list/player_levels = list(1, 3, 4, 5, 6) // Defines all Z-levels a character can typically reach var/list/player_levels = list(1, 3, 4, 5, 6) // Defines all Z-levels a character can typically reach
var/list/sealed_levels = list() // Defines levels that do not allow random transit at the edges. var/list/sealed_levels = list(7) // Defines levels that do not allow random transit at the edges.
// Event settings // Event settings
var/expected_round_length = 3 * 60 * 60 * 10 // 3 hours var/expected_round_length = 3 * 60 * 60 * 10 // 3 hours

View File

@@ -397,5 +397,20 @@ var/global/datum/shuttle_controller/shuttle_controller
AM.move_time = 60 AM.move_time = 60
AM.warmup_time = 8 AM.warmup_time = 8
shuttles["AwayMission"] = AM shuttles["AwayMission"] = AM
//VOREStation Add End - Away-mission shuttle //VOREStation Add End - Away-mission shuttle
///////////////////////////////////////////////
//VOREStation Add - Belter Shuttle
shuttle = new/datum/shuttle/ferry()
shuttle.location = 0
shuttle.warmup_time = 6
shuttle.area_station = locate(/area/shuttle/belter/station)
shuttle.area_offsite = locate(/area/shuttle/belter/belt/zone1)
shuttle.area_transition = locate(/area/shuttle/belter/transit)
shuttle.docking_controller_tag = "belter_docking"
shuttle.dock_target_station = "belter_nodocking" //Fake tags to prevent the shuttle from opening doors.
shuttle.dock_target_offsite = "belter_nodocking"
shuttle.transit_direction = EAST
shuttle.move_time = 60 + rand(10,40)
process_shuttles += shuttle
shuttles["Belter"] = shuttle
//VOREStation Add End - Belter Shuttle

View File

@@ -28,6 +28,16 @@
return list("title" = title, "message" = message) return list("title" = title, "message" = message)
/datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args) /datum/uplink_item/abstract/announcements/fake_centcom/get_goods(var/obj/item/device/uplink/U, var/loc, var/mob/user, var/list/args)
for (var/obj/machinery/computer/communications/C in machines)
if(! (C.stat & (BROKEN|NOPOWER) ) )
var/obj/item/weapon/paper/P = new /obj/item/weapon/paper( C.loc )
P.name = "'[command_name()] Update.'"
P.info = replacetext(args["message"], "\n", "<br/>")
P.update_space(P.info)
P.update_icon()
C.messagetitle.Add(args["title"])
C.messagetext.Add(P.info)
command_announcement.Announce(args["message"], args["title"]) command_announcement.Announce(args["message"], args["title"])
return 1 return 1

View File

@@ -16,8 +16,8 @@ var/datum/antagonist/mercenary/mercs
hard_cap = 4 hard_cap = 4
hard_cap_round = 8 hard_cap_round = 8
initial_spawn_req = 4 initial_spawn_req = 3
initial_spawn_target = 6 initial_spawn_target = 4
/datum/antagonist/mercenary/New() /datum/antagonist/mercenary/New()
..() ..()

View File

@@ -14,8 +14,8 @@ var/datum/antagonist/raider/raiders
hard_cap = 6 hard_cap = 6
hard_cap_round = 10 hard_cap_round = 10
initial_spawn_req = 4 initial_spawn_req = 3
initial_spawn_target = 6 initial_spawn_target = 4
id_type = /obj/item/weapon/card/id/syndicate id_type = /obj/item/weapon/card/id/syndicate

View File

@@ -39,6 +39,7 @@
icon_state = "teleporter" icon_state = "teleporter"
music = "signal" music = "signal"
// New shuttles
/area/shuttle/administration/transit /area/shuttle/administration/transit
name = "Deep Space (AS)" name = "Deep Space (AS)"
icon_state = "shuttle" icon_state = "shuttle"
@@ -62,3 +63,48 @@
/area/shuttle/awaymission/oldengbase /area/shuttle/awaymission/oldengbase
name = "Old Construction Site (AM)" name = "Old Construction Site (AM)"
icon_state = "shuttle2" icon_state = "shuttle2"
/area/shuttle/belter/station
name = "Belter Shuttle Landed"
icon_state = "shuttle2"
base_turf = /turf/simulated/floor/tiled/asteroid_steel/airless
/area/shuttle/belter/belt //Don't use this one, use a subtype
name = "Belter Shuttle Holding Position"
icon_state = "shuttle2"
//Placeholders
/area/shuttle/belter/belt/zone1
/area/shuttle/belter/belt/zone2
/area/shuttle/belter/belt/zone3
/area/shuttle/belter/belt/zone4
/area/shuttle/belter/transit
name = "Belter Shuttle Warp"
icon_state = "shuttle"
//Rouguelike Mining
/area/asteroid/rogue
var/asteroid_spawns = list()
var/mob_spawns = list()
var/shuttle_area //It would be neat if this were more dynamic, but eh.
/area/asteroid/rogue/zone1
name = "Asteroid Belt Zone 1"
icon_state = "red2"
shuttle_area = /area/shuttle/belter/belt/zone1
/area/asteroid/rogue/zone2
name = "Asteroid Belt Zone 2"
icon_state = "blue2"
shuttle_area = /area/shuttle/belter/belt/zone2
/area/asteroid/rogue/zone3
name = "Asteroid Belt Zone 3"
icon_state = "blue2"
shuttle_area = /area/shuttle/belter/belt/zone3
/area/asteroid/rogue/zone4
name = "Asteroid Belt Zone 4"
icon_state = "red2"
shuttle_area = /area/shuttle/belter/belt/zone4

View File

@@ -7,9 +7,9 @@ var/global/list/obj/cortical_stacks = list() //Stacks for 'leave nobody behind'
/datum/game_mode/heist /datum/game_mode/heist
name = "Heist" name = "Heist"
config_tag = "heist" config_tag = "heist"
required_players = 15 required_players = 8
required_players_secret = 15 required_players_secret = 8
required_enemies = 4 required_enemies = 3
round_description = "An unidentified bluespace signature is approaching the station!" round_description = "An unidentified bluespace signature is approaching the station!"
extended_round_description = "The Company's majority control of phoron in "+starsys_name+" has marked the \ extended_round_description = "The Company's majority control of phoron in "+starsys_name+" has marked the \
station to be a highly valuable target for many competing organizations and individuals. Being a \ station to be a highly valuable target for many competing organizations and individuals. Being a \

View File

@@ -12,9 +12,9 @@ var/list/nuke_disks = list()
colony of sizable population and considerable wealth causes it to often be the target of various \ colony of sizable population and considerable wealth causes it to often be the target of various \
attempts of robbery, fraud and other malicious actions." attempts of robbery, fraud and other malicious actions."
config_tag = "mercenary" config_tag = "mercenary"
required_players = 15 required_players = 8
required_players_secret = 15 required_players_secret = 8
required_enemies = 1 required_enemies = 3
end_on_antag_death = 0 end_on_antag_death = 0
var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station var/nuke_off_station = 0 //Used for tracking if the syndies actually haul the nuke to the station
var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level var/syndies_didnt_escape = 0 //Used for tracking if the syndies got the shuttle off of the z-level

View File

@@ -158,7 +158,7 @@
//Body Scan Console //Body Scan Console
/obj/machinery/body_scanconsole /obj/machinery/body_scanconsole
var/obj/machinery/bodyscanner/scanner var/obj/machinery/bodyscanner/scanner
var/known_implants = list(/obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking) var/known_implants = list(/obj/item/weapon/implant/health, /obj/item/weapon/implant/chem, /obj/item/weapon/implant/death_alarm, /obj/item/weapon/implant/loyalty, /obj/item/weapon/implant/tracking, /obj/item/weapon/implant/language, /obj/item/weapon/implant/language/eal)
var/delete var/delete
var/temphtml var/temphtml
name = "Body Scanner Console" name = "Body Scanner Console"

View File

@@ -123,6 +123,7 @@
if(user.species.can_shred(user)) if(user.species.can_shred(user))
set_status(0) set_status(0)
user.do_attack_animation(src) user.do_attack_animation(src)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
visible_message("<span class='warning'>\The [user] slashes at [src]!</span>") visible_message("<span class='warning'>\The [user] slashes at [src]!</span>")
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)
add_hiddenprint(user) add_hiddenprint(user)

View File

@@ -10,6 +10,7 @@
var/active = 0 var/active = 0
/obj/machinery/computer/aifixer/New() /obj/machinery/computer/aifixer/New()
..()
update_icon() update_icon()
/obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user) /obj/machinery/computer/aifixer/proc/load_ai(var/mob/living/silicon/ai/transfer, var/obj/item/device/aicard/card, var/mob/user)

View File

@@ -253,7 +253,7 @@
desc = "Used to access the various cameras on the outpost." desc = "Used to access the various cameras on the outpost."
icon_keyboard = "mining_key" icon_keyboard = "mining_key"
icon_screen = "mining" icon_screen = "mining"
network = list("MINE") network = list("Mining Outpost")
circuit = /obj/item/weapon/circuitboard/security/mining circuit = /obj/item/weapon/circuitboard/security/mining
light_color = "#F9BBFC" light_color = "#F9BBFC"

View File

@@ -413,7 +413,7 @@
if(istype(W,/obj/item/weapon/implant/health)) if(istype(W,/obj/item/weapon/implant/health))
for(var/obj/machinery/computer/cloning/com in world) for(var/obj/machinery/computer/cloning/com in world)
for(var/datum/dna2/record/R in com.records) for(var/datum/dna2/record/R in com.records)
if(R.implant == W) if(locate(R.implant) == W)
qdel(R) qdel(R)
qdel(W) qdel(W)

View File

@@ -746,6 +746,7 @@ About the new airlock wires panel:
return return
src.add_fingerprint(user) src.add_fingerprint(user)
if (attempt_vr(src,"attackby_vr",list(C, user))) return
if(istype(C, /mob/living)) if(istype(C, /mob/living))
..() ..()
return return

View File

@@ -202,6 +202,8 @@
/obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob) /obj/machinery/door/attackby(obj/item/I as obj, mob/user as mob)
src.add_fingerprint(user) src.add_fingerprint(user)
if (attempt_vr(src,"attackby_vr",list(I, user))) return
if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name()) if(istype(I, /obj/item/stack/material) && I.get_material_name() == src.get_material_name())
if(stat & BROKEN) if(stat & BROKEN)
user << "<span class='notice'>It looks like \the [src] is pretty busted. It's going to need more than just patching up now.</span>" user << "<span class='notice'>It looks like \the [src] is pretty busted. It's going to need more than just patching up now.</span>"

View File

@@ -0,0 +1,93 @@
/turf/simulated/floor/proc/adjacent_fire_act_vr(turf/simulated/floor/adj_turf, datum/gas_mixture/adj_air, adj_temp, adj_volume)
for(var/obj/machinery/door/D in src) //makes doors next to fire affected by fire
D.fire_act(adj_air, adj_temp, adj_volume)
/obj/machinery/door
var/obj/item/stack/material/plasteel/reinforcing //vorestation addition
/obj/machinery/door/firedoor
heat_proof = 1
/obj/machinery/door/airlock/vault
heat_proof = 1
/obj/machinery/door/airlock/hatch
heat_proof = 1
/obj/machinery/door/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
var/maxtemperature = 1800 //same as a normal steel wall
var/destroytime = 20 //effectively gives an airlock 200HP between breaking and completely disintegrating
if(heat_proof)
maxtemperature = 6000 //same as a plasteel rwall
destroytime = 50 //fireproof airlocks need to take 500 damage after breaking before they're destroyed
if(exposed_temperature > maxtemperature)
var/burndamage = log(RAND_F(0.9, 1.1) * (exposed_temperature - maxtemperature))
if (burndamage && health <= 0) //once they break, start taking damage to destroy_hits
destroy_hits -= (burndamage / destroytime)
if (destroy_hits <= 0)
visible_message("<span class='danger'>\The [src.name] disintegrates!</span>")
new /obj/effect/decal/cleanable/ash(src.loc) // Turn it to ashes!
qdel(src)
take_damage(burndamage)
return ..()
/obj/machinery/door/proc/attackby_vr(obj/item/I as obj, mob/user as mob)
if(istype(I, /obj/item/stack/material) && I.get_material_name() == "plasteel") // Add heat shielding if it isn't already.
if(!heat_proof)
var/obj/item/stack/stack = I
var/transfer
var/amount_needed = 2
if (stack.amount >= amount_needed)
if(stat & BROKEN)
user << "<span class='notice'>It looks like \the [src] is pretty busted. There's not much point reinforcing it.</span>"
return 1
if (reinforcing)
transfer = stack.transfer_to(reinforcing, amount_needed - reinforcing.amount)
if (!transfer)
user << "<span class='warning'>You must weld or remove \the [reinforcing] from \the [src] before you can add anything else.</span>"
return 1
else
reinforcing = stack.split(amount_needed)
if (reinforcing)
reinforcing.loc = src
transfer = reinforcing.amount
if (transfer)
user << "<span class='notice'>You fit [transfer] [stack.singular_name]\s to \the [src].</span>"
return 1
return 0
if(reinforcing && istype(I, /obj/item/weapon/weldingtool))
if(!density)
user << "<span class='warning'>\The [src] must be closed before you can repair it.</span>"
return 1
var/obj/item/weapon/weldingtool/welder = I
if(welder.remove_fuel(0,user))
user << "<span class='notice'>You start to weld \the [reinforcing] into place.</span>"
playsound(src, 'sound/items/Welder.ogg', 100, 1)
if(do_after(user, 5 * reinforcing.amount) && welder && welder.isOn())
user << "<span class='notice'>You finish reinforcing \the [src].</span>"
heat_proof = 1
update_icon()
qdel(reinforcing)
reinforcing = null
return 1
if(reinforcing && istype(I, /obj/item/weapon/crowbar))
user << "<span class='notice'>You remove \the [reinforcing].</span>"
playsound(src.loc, 'sound/items/Crowbar.ogg', 100, 1)
reinforcing.loc = user.loc
reinforcing = null
return 1
return 0
/obj/machinery/door/blast/regular/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
return // blast doors are immune to fire completely.
/obj/machinery/door/blast/regular/
heat_proof = 1 //just so repairing them doesn't try to fireproof something that never takes fire damage

View File

@@ -160,6 +160,8 @@
if(H.species.can_shred(H)) if(H.species.can_shred(H))
playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1) playsound(src.loc, 'sound/effects/Glasshit.ogg', 75, 1)
visible_message("<span class='danger'>[user] smashes against the [src.name].</span>", 1) visible_message("<span class='danger'>[user] smashes against the [src.name].</span>", 1)
user.do_attack_animation(src)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
take_damage(25) take_damage(25)
return return
return src.attackby(user, user) return src.attackby(user, user)

View File

@@ -780,8 +780,8 @@
name = "SweatMAX" name = "SweatMAX"
desc = "Fueled by your inner inadequacy!" desc = "Fueled by your inner inadequacy!"
icon_state = "fitness" icon_state = "fitness"
products = list(/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton = 8, products = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 8,
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate = 8, /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 8,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 8, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 8,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 8,
/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 8,
@@ -789,8 +789,8 @@
/obj/item/weapon/reagent_containers/pill/diet = 8, /obj/item/weapon/reagent_containers/pill/diet = 8,
/obj/item/weapon/towel/random = 8) /obj/item/weapon/towel/random = 8)
prices = list(/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton = 3, prices = list(/obj/item/weapon/reagent_containers/food/drinks/smallmilk = 3,
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate = 3, /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk = 3,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 20, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask/proteinshake = 20,
/obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 5, /obj/item/weapon/reagent_containers/food/drinks/glass2/fitnessflask = 5,
/obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5, /obj/item/weapon/reagent_containers/food/snacks/candy/proteinbar = 5,

View File

@@ -11,7 +11,16 @@
products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5, products = list(/obj/item/weapon/handcuffs = 8,/obj/item/weapon/grenade/flashbang = 4,/obj/item/device/flash = 5,
/obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6, /obj/item/weapon/reagent_containers/food/snacks/donut/normal = 12,/obj/item/weapon/storage/box/evidence = 6,
/obj/item/weapon/gun/energy/taser = 8,/obj/item/weapon/gun/energy/stunrevolver = 4, /obj/item/weapon/gun/energy/taser = 8,/obj/item/weapon/gun/energy/stunrevolver = 4,
/obj/item/weapon/reagent_containers/spray/pepper = 6,/obj/item/taperoll/police = 6) /obj/item/weapon/reagent_containers/spray/pepper = 6,/obj/item/taperoll/police = 6,
/obj/item/weapon/gun/projectile/sec/flash = 4, /obj/item/ammo_magazine/c45m/flash = 8)
/obj/machinery/vending/tool
products = list(/obj/item/stack/cable_coil/random = 10,/obj/item/weapon/crowbar = 5,/obj/item/weapon/weldingtool = 3,/obj/item/weapon/wirecutters = 5,
/obj/item/weapon/wrench = 5,/obj/item/device/analyzer = 5,/obj/item/device/t_scanner = 5,/obj/item/weapon/screwdriver = 5,
/obj/item/device/flashlight/glowstick = 3, /obj/item/device/flashlight/glowstick/red = 3, /obj/item/device/flashlight/glowstick/blue = 3,
/obj/item/device/flashlight/glowstick/orange =3, /obj/item/device/flashlight/glowstick/yellow = 3, /obj/item/weapon/reagent_containers/spray/windowsealant = 5)
/* /*
var/list/log = list() var/list/log = list()
var/req_log_access = access_armory var/req_log_access = access_armory

View File

@@ -173,7 +173,7 @@
cell = C cell = C
return return
cell = new(src) cell = new(src)
cell.name = "high-capacity power cell" cell.name = "mecha power cell"
cell.charge = 15000 cell.charge = 15000
cell.maxcharge = 15000 cell.maxcharge = 15000
@@ -514,6 +514,7 @@
if(H.species.can_shred(user)) if(H.species.can_shred(user))
if(!prob(src.deflect_chance)) if(!prob(src.deflect_chance))
src.take_damage(15) src.take_damage(15)
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) src.check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST))
playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1) playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
user << "<span class='danger'>You slash at the armored suit!</span>" user << "<span class='danger'>You slash at the armored suit!</span>"

View File

@@ -77,6 +77,8 @@
desc = "They seem to pulse slightly with an inner life" desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs" icon_state = "eggs"
var/amount_grown = 0 var/amount_grown = 0
var/spiders_min = 6
var/spiders_max = 24
New() New()
pixel_x = rand(3,-3) pixel_x = rand(3,-3)
pixel_y = rand(3,-3) pixel_y = rand(3,-3)
@@ -97,7 +99,7 @@
/obj/effect/spider/eggcluster/process() /obj/effect/spider/eggcluster/process()
amount_grown += rand(0,2) amount_grown += rand(0,2)
if(amount_grown >= 100) if(amount_grown >= 100)
var/num = rand(6,24) var/num = rand(spiders_min, spiders_max)
var/obj/item/organ/external/O = null var/obj/item/organ/external/O = null
if(istype(loc, /obj/item/organ/external)) if(istype(loc, /obj/item/organ/external))
O = loc O = loc
@@ -108,6 +110,10 @@
O.implants += spiderling O.implants += spiderling
qdel(src) qdel(src)
/obj/effect/spider/eggcluster/small
spiders_min = 1
spiders_max = 3
/obj/effect/spider/spiderling /obj/effect/spider/spiderling
name = "spiderling" name = "spiderling"
desc = "It never stays still for long." desc = "It never stays still for long."

View File

@@ -86,7 +86,7 @@
if(C.stat != DEAD) if(C.stat != DEAD)
var/safety = C.eyecheck() var/safety = C.eyecheck()
if(safety <= 0) if(safety <= 0)
var/flash_strength = 5 var/flash_strength = 10 //Vorestation edit, making flashes behave the same as flash rounds
if(ishuman(C)) if(ishuman(C))
var/mob/living/carbon/human/H = C var/mob/living/carbon/human/H = C
flash_strength *= H.species.flash_mod flash_strength *= H.species.flash_mod

View File

@@ -0,0 +1,2 @@
/obj/item/device/flash
halloss_per_flash = 22

View File

@@ -26,7 +26,7 @@
/obj/item/weapon/circuitboard/security/mining /obj/item/weapon/circuitboard/security/mining
name = T_BOARD("mining camera monitor") name = T_BOARD("mining camera monitor")
build_path = /obj/machinery/computer/security/mining build_path = /obj/machinery/computer/security/mining
network = list("MINE") network = list("Mining Outpost")
req_access = list() req_access = list()
/obj/item/weapon/circuitboard/security/telescreen/entertainment /obj/item/weapon/circuitboard/security/telescreen/entertainment

View File

@@ -285,4 +285,59 @@
/obj/item/weapon/anobattery, /obj/item/weapon/anobattery,
/obj/item/device/ano_scanner, /obj/item/device/ano_scanner,
/obj/item/weapon/pickaxe/hand /obj/item/weapon/pickaxe/hand
) )
/obj/item/weapon/storage/belt/fannypack
name = "leather fannypack"
desc = "A dorky fannypack for keeping small items in."
icon_state = "fannypack_leather"
item_state = "fannypack_leather"
max_w_class = ITEMSIZE_SMALL
storage_slots = null
max_storage_space = ITEMSIZE_COST_NORMAL * 2
/obj/item/weapon/storage/belt/fannypack/black
name = "black fannypack"
icon_state = "fannypack_black"
item_state = "fannypack_black"
/obj/item/weapon/storage/belt/fannypack/blue
name = "blue fannypack"
icon_state = "fannypack_blue"
item_state = "fannypack_blue"
/obj/item/weapon/storage/belt/fannypack/cyan
name = "cyan fannypack"
icon_state = "fannypack_cyan"
item_state = "fannypack_cyan"
/obj/item/weapon/storage/belt/fannypack/green
name = "green fannypack"
icon_state = "fannypack_green"
item_state = "fannypack_green"
/obj/item/weapon/storage/belt/fannypack/orange
name = "orange fannypack"
icon_state = "fannypack_orange"
item_state = "fannypack_orange"
/obj/item/weapon/storage/belt/fannypack/purple
name = "purple fannypack"
icon_state = "fannypack_purple"
item_state = "fannypack_purple"
/obj/item/weapon/storage/belt/fannypack/red
name = "red fannypack"
icon_state = "fannypack_red"
item_state = "fannypack_red"
/obj/item/weapon/storage/belt/fannypack/white
name = "white fannypack"
icon_state = "fannypack_white"
item_state = "fannypack_white"
/obj/item/weapon/storage/belt/fannypack/yellow
name = "yellow fannypack"
icon_state = "fannypack_yellow"
item_state = "fannypack_yellow"

View File

@@ -50,10 +50,10 @@
if (!( user.restrained() ) && !( user.stat )) if (!( user.restrained() ) && !( user.stat ))
switch(over_object.name) switch(over_object.name)
if("r_hand") if("r_hand")
user.u_equip(master_item) user.unEquip(master_item)
user.put_in_r_hand(master_item) user.put_in_r_hand(master_item)
if("l_hand") if("l_hand")
user.u_equip(master_item) user.unEquip(master_item)
user.put_in_l_hand(master_item) user.put_in_l_hand(master_item)
master_item.add_fingerprint(user) master_item.add_fingerprint(user)
return 0 return 0

View File

@@ -77,10 +77,10 @@
switch(over_object.name) switch(over_object.name)
if("r_hand") if("r_hand")
usr.u_equip(src) usr.unEquip(src)
usr.put_in_r_hand(src) usr.put_in_r_hand(src)
if("l_hand") if("l_hand")
usr.u_equip(src) usr.unEquip(src)
usr.put_in_l_hand(src) usr.put_in_l_hand(src)
src.add_fingerprint(usr) src.add_fingerprint(usr)

View File

@@ -129,4 +129,30 @@
prob(1);/obj/item/ammo_magazine/stg,\ prob(1);/obj/item/ammo_magazine/stg,\
prob(1);/obj/item/ammo_magazine/tommydrum,\ prob(1);/obj/item/ammo_magazine/tommydrum,\
prob(1);/obj/item/ammo_magazine/tommymag prob(1);/obj/item/ammo_magazine/tommymag
) )
/obj/random/cargopod
name = "Random Cargo Item"
desc = "Hot Stuff."
icon = 'icons/obj/items.dmi'
icon_state = "purplecomb"
spawn_nothing_percentage = 0
/obj/random/cargopod/item_to_spawn()
return pick(prob(6);/obj/item/weapon/storage/pill_bottle/tramadol,
prob(8);/obj/item/weapon/haircomb,
prob(4);/obj/item/weapon/storage/pill_bottle/happy,
prob(4);/obj/item/weapon/storage/pill_bottle/zoom,
prob(10);/obj/item/weapon/contraband/poster,
prob(4);/obj/item/weapon/material/butterfly,
prob(6);/obj/item/weapon/material/butterflyblade,
prob(6);/obj/item/weapon/material/butterflyhandle,
prob(6);/obj/item/weapon/material/wirerod,
prob(2);/obj/item/weapon/material/butterfly/switchblade,
prob(2);/obj/item/weapon/material/knuckledusters,
prob(1);/obj/item/weapon/material/hatchet/tacknife,
prob(1);/obj/item/clothing/suit/storage/vest/heavy/merc,
prob(1);/obj/item/weapon/beartrap,
prob(1);/obj/item/weapon/handcuffs,
prob(1);/obj/item/weapon/legcuffs,
prob(2);/obj/item/weapon/reagent_containers/syringe/drugs,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid)

View File

@@ -37,6 +37,7 @@
new /obj/item/taperoll/engineering(src) new /obj/item/taperoll/engineering(src)
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src) new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
new /obj/item/weapon/tank/emergency/oxygen/engi(src) new /obj/item/weapon/tank/emergency/oxygen/engi(src)
new /obj/item/weapon/reagent_containers/spray/windowsealant(src) //vorestation addition
return return
@@ -128,6 +129,7 @@
new /obj/item/taperoll/engineering(src) new /obj/item/taperoll/engineering(src)
new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src) new /obj/item/clothing/suit/storage/hooded/wintercoat/engineering(src)
new /obj/item/weapon/tank/emergency/oxygen/engi(src) new /obj/item/weapon/tank/emergency/oxygen/engi(src)
new /obj/item/weapon/reagent_containers/spray/windowsealant(src) //vorestation addition
return return

View File

@@ -137,7 +137,8 @@
new /obj/item/clothing/gloves/yellow(src) new /obj/item/clothing/gloves/yellow(src)
if(prob(40)) if(prob(40))
new /obj/item/clothing/head/hardhat(src) new /obj/item/clothing/head/hardhat(src)
if(prob(30))
new /obj/item/weapon/reagent_containers/spray/windowsealant(src) //vorestation addition
/* /*
* Radiation Closet * Radiation Closet

View File

@@ -5,11 +5,7 @@
if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN)) if(!(Proj.damage_type == BRUTE || Proj.damage_type == BURN))
return return
health -= Proj.damage if(locked && tamper_proof && health <= Proj.damage)
..()
if(locked && tamper_proof && health <= 0)
if(tamper_proof == 2) // Mainly used for events to prevent any chance of opening the box improperly. if(tamper_proof == 2) // Mainly used for events to prevent any chance of opening the box improperly.
visible_message("<font color='red'><b>The anti-tamper mechanism of [src] triggers an explosion!</b></font>") visible_message("<font color='red'><b>The anti-tamper mechanism of [src] triggers an explosion!</b></font>")
var/turf/T = get_turf(src.loc) var/turf/T = get_turf(src.loc)
@@ -33,9 +29,6 @@
visible_message("<font color='green'><b>The anti-tamper mechanism of [src] fails!</b></font>") visible_message("<font color='green'><b>The anti-tamper mechanism of [src] fails!</b></font>")
return return
if(health <= 0) ..()
for(var/atom/movable/A as mob|obj in src)
A.loc = src.loc
qdel(src)
return return

View File

@@ -0,0 +1,10 @@
//Airless versions of shuttle floor tiles.
/turf/simulated/shuttle/floor/airless
oxygen = 0
nitrogen = 0
temperature = TCMB
/turf/simulated/shuttle/plating/airless
oxygen = 0
nitrogen = 0
temperature = TCMB

View File

@@ -43,3 +43,5 @@
for(var/obj/structure/window/W in src) for(var/obj/structure/window/W in src)
if(W.dir == dir_to || W.is_fulltile()) //Same direction or diagonal (full tile) if(W.dir == dir_to || W.is_fulltile()) //Same direction or diagonal (full tile)
W.fire_act(adj_air, adj_temp, adj_volume) W.fire_act(adj_air, adj_temp, adj_volume)
attempt_vr(src,"adjacent_fire_act_vr",list(adj_turf,adj_air,adj_temp,adj_volume))

View File

@@ -1245,7 +1245,7 @@ proc/admin_notice(var/message, var/rights)
M = whom M = whom
C = M.client C = M.client
else else
return "<b>(*not an mob*)</b>" return "<b>(*not a mob*)</b>"
switch(detail) switch(detail)
if(0) if(0)
return "<b>[key_name(C, link, name, highlight_special)]</b>" return "<b>[key_name(C, link, name, highlight_special)]</b>"
@@ -1255,15 +1255,15 @@ proc/admin_notice(var/message, var/rights)
if(2) //Admins if(2) //Admins
var/ref_mob = "\ref[M]" var/ref_mob = "\ref[M]"
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)</b>" return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>) (<A HREF='?_src_=holder;take_question=\ref[M]'>TAKE</A>)</b>"
if(3) //Devs if(3) //Devs
var/ref_mob = "\ref[M]" var/ref_mob = "\ref[M]"
return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>)([admin_jump_link(M, src)])</b>" return "<b>[key_name(C, link, name, highlight_special)](<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>)([admin_jump_link(M, src)]) (<A HREF='?_src_=holder;take_question=\ref[M]'>TAKE</A>)</b>"
if(4) //Mentors if(4) //Mentors
var/ref_mob = "\ref[M]" var/ref_mob = "\ref[M]"
return "<b>[key_name(C, link, name, highlight_special)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)])</b>" return "<b>[key_name(C, link, name, highlight_special)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) ([admin_jump_link(M, src)]) (<A HREF='?_src_=holder;take_question=\ref[M]'>TAKE</A>)</b>"
/proc/ishost(whom) /proc/ishost(whom)

View File

@@ -195,6 +195,7 @@ var/list/admin_verbs_debug = list(
/client/proc/SDQL_query, /client/proc/SDQL_query,
/client/proc/SDQL2_query, /client/proc/SDQL2_query,
/client/proc/Jump, /client/proc/Jump,
/client/proc/debug_rogueminer,
/client/proc/jumptomob, /client/proc/jumptomob,
/client/proc/jumptocoord, /client/proc/jumptocoord,
/client/proc/dsay, /client/proc/dsay,

View File

@@ -1218,6 +1218,18 @@
else if(href_list["check_antagonist"]) else if(href_list["check_antagonist"])
check_antagonists() check_antagonists()
else if(href_list["take_question"])
var/mob/M = locate(href_list["take_question"])
if(ismob(M))
var/take_msg = "<span class='notice'><b>ADMINHELP</b>: <b>[key_name(usr.client)]</b> is attending to <b>[key_name(M)]'s</b> adminhelp, please don't dogpile them.</span>"
for(var/client/X in admins)
if((R_ADMIN|R_MOD|R_MENTOR) & X.holder.rights)
to_chat(X, take_msg)
to_chat(M, "<span class='notice'><b>Your adminhelp is being attended to by [usr.client]. Thanks for your patience!</b></span>")
else
to_chat(usr, "<span class='warning'>Unable to locate mob.</span>")
else if(href_list["adminplayerobservecoodjump"]) else if(href_list["adminplayerobservecoodjump"])
if(!check_rights(R_ADMIN|R_SERVER|R_MOD)) return if(!check_rights(R_ADMIN|R_SERVER|R_MOD)) return

View File

@@ -1,6 +1,6 @@
/obj/item/device/assembly/signaler /obj/item/device/assembly/signaler
name = "remote signaling device" name = "remote signaling device"
desc = "Used to remotely activate devices." desc = "Used to remotely activate devices. Tap against another secured signaler to transfer configuration."
icon_state = "signaller" icon_state = "signaller"
item_state = "signaler" item_state = "signaler"
origin_tech = list(TECH_MAGNET = 1) origin_tech = list(TECH_MAGNET = 1)
@@ -98,6 +98,15 @@
return return
attackby(obj/item/weapon/W, mob/user, params)
if(issignaler(W))
var/obj/item/device/assembly/signaler/signaler2 = W
if(secured && signaler2.secured)
code = signaler2.code
frequency = signaler2.frequency
user << "You transfer the frequency and code of [signaler2] to [src]"
else
..()
proc/signal() proc/signal()
if(!radio_connection) return if(!radio_connection) return

View File

@@ -280,6 +280,18 @@
path = /obj/item/clothing/accessory/storage/white_drop_pouches path = /obj/item/clothing/accessory/storage/white_drop_pouches
allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor") allowed_roles = list("Station Engineer","Atmospheric Technician","Chief Engineer","Security Officer","Detective","Head of Security","Warden","Paramedic","Chief Medical Officer","Medical Doctor")
/datum/gear/accessory/fannypack
display_name = "fannypack selection"
cost = 2
/datum/gear/accessory/fannypack/New()
..()
var/list/fannys = list()
for(var/fanny in typesof(/obj/item/weapon/storage/belt/fannypack))
var/obj/item/weapon/storage/belt/fannypack/fanny_type = fanny
fannys[initial(fanny_type.name)] = fanny_type
gear_tweaks += new/datum/gear_tweak/path(sortAssoc(fannys))
/datum/gear/accessory/webbing /datum/gear/accessory/webbing
display_name = "webbing, simple" display_name = "webbing, simple"
path = /obj/item/clothing/accessory/storage/webbing path = /obj/item/clothing/accessory/storage/webbing

View File

@@ -34,6 +34,7 @@
item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD item_flags = STOPPRESSUREDAMAGE | THICKMATERIAL | PHORONGUARD
allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank) allowed = list(/obj/item/weapon/gun,/obj/item/ammo_magazine,/obj/item/ammo_casing,/obj/item/weapon/melee/baton,/obj/item/weapon/melee/energy/sword,/obj/item/weapon/handcuffs,/obj/item/weapon/tank)
phoronproof = 1 phoronproof = 1
slowdown = 2
armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 30, rad = 30) armor = list(melee = 60, bullet = 50, laser = 40,energy = 15, bomb = 30, bio = 30, rad = 30)
siemens_coefficient = 0.2 siemens_coefficient = 0.2
heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS heat_protection = UPPER_TORSO|LOWER_TORSO|LEGS|FEET|ARMS|HANDS

View File

@@ -49,6 +49,9 @@
item_flags = THICKMATERIAL item_flags = THICKMATERIAL
siemens_coefficient = 0.2 siemens_coefficient = 0.2
phoronproof = 1 phoronproof = 1
offline_slowdown = 5
slowdown = 2
allowed = list(/obj/item/weapon/gun,/obj/item/device/flashlight,/obj/item/weapon/tank,/obj/item/device/suit_cooling_unit)
air_type = /obj/item/weapon/tank/vox air_type = /obj/item/weapon/tank/vox
@@ -108,7 +111,6 @@
icon_state = "voxstealth_rig" icon_state = "voxstealth_rig"
armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 30, bio = 100, rad = 100) armor = list(melee = 40, bullet = 30, laser = 30, energy = 15, bomb = 30, bio = 100, rad = 100)
emp_protection = 40 //change this to 30 if too high. emp_protection = 40 //change this to 30 if too high.
slowdown = 0
phoronproof = 1 phoronproof = 1
req_access = list(access_syndicate) req_access = list(access_syndicate)

View File

@@ -25,7 +25,7 @@
icon_state = "webbing-vox" icon_state = "webbing-vox"
slot = "vox" slot = "vox"
slots = 5 slots = 3
/obj/item/clothing/accessory/storage/vox/New() /obj/item/clothing/accessory/storage/vox/New()
..() ..()

View File

@@ -5,12 +5,9 @@
var/chaotic = 0 // A number showing how chaotic the action may be. If danger is high, the GM will avoid it. var/chaotic = 0 // A number showing how chaotic the action may be. If danger is high, the GM will avoid it.
var/reusable = FALSE // If true, the event does not become disabled upon being used. Should be used sparingly. var/reusable = FALSE // If true, the event does not become disabled upon being used. Should be used sparingly.
var/observers_used = FALSE // Determines if the GM should check if ghosts are available before using this. var/observers_used = FALSE // Determines if the GM should check if ghosts are available before using this.
var/length = 0 // Determines how long the event lasts, until end() is called.
var/datum/game_master/gm = null var/datum/game_master/gm = null
/datum/gm_action/New(var/datum/game_master/new_gm)
..()
gm = new_gm
/datum/gm_action/proc/set_up() /datum/gm_action/proc/set_up()
return return

View File

@@ -0,0 +1,65 @@
//carp_migration
/datum/gm_action/carp_migration
name = "carp migration"
departments = list(ROLE_SECURITY, ROLE_EVERYONE)
chaotic = 50
var/list/spawned_carp = list()
var/carp_amount = 0
length = 20 MINUTES
/datum/gm_action/carp_migration/get_weight()
var/people_in_space = 0
for(var/mob/living/L in player_list)
if(!(L.z in config.station_levels))
continue // Not on the right z-level.
var/turf/T = get_turf(L)
if(istype(T, /turf/space) && istype(T.loc,/area/space))
people_in_space++
return 50 + (metric.count_people_in_department(ROLE_SECURITY) * 10) + (people_in_space * 20)
/datum/gm_action/carp_migration/announce()
var/announcement = "Unknown biological entities have been detected near [station_name()], please stand-by."
command_announcement.Announce(announcement, "Lifesign Alert")
/datum/gm_action/carp_migration/set_up()
// Higher filled roles means more groups of fish.
var/station_strength = 0
station_strength += (metric.count_people_in_department(ROLE_SECURITY) * 3)
station_strength += (metric.count_people_in_department(ROLE_ENGINEERING) * 2)
station_strength += metric.count_people_in_department(ROLE_MEDICAL)
// Less active emergency response departments tones the event down.
var/activeness = ((metric.assess_department(ROLE_SECURITY) + metric.assess_department(ROLE_ENGINEERING) + metric.assess_department(ROLE_MEDICAL)) / 3)
activeness = max(activeness, 20)
carp_amount = Ceiling(station_strength * (activeness / 100) + 1)
/datum/gm_action/carp_migration/start()
..()
var/list/spawn_locations = list()
var/group_size_min = 3
var/group_size_max = 5
for(var/obj/effect/landmark/C in landmarks_list)
if(C.name == "carpspawn")
spawn_locations.Add(C.loc)
spawn_locations = shuffle(spawn_locations)
carp_amount = min(carp_amount, spawn_locations.len)
var/i = 1
while (i <= carp_amount)
var/group_size = rand(group_size_min, group_size_max)
for (var/j = 1, j <= group_size, j++)
spawned_carp.Add(new /mob/living/simple_animal/hostile/carp(spawn_locations[i]))
i++
message_admins("[spawned_carp.len] carp spawned by event.")
/datum/gm_action/carp_migration/end()
for(var/mob/living/simple_animal/hostile/carp/C in spawned_carp)
if(!C.stat)
var/turf/T = get_turf(C)
if(istype(T, /turf/space))
if(!prob(25))
qdel(C)

View File

@@ -1,9 +1,21 @@
// Comms blackout is, just like grid check, mostly the same as always, yet engineering has an option to get it back sooner.
/datum/gm_action/comms_blackout /datum/gm_action/comms_blackout
name = "communications blackout" name = "communications blackout"
departments = list(ROLE_ENGINEERING, ROLE_EVERYONE) departments = list(ROLE_ENGINEERING, ROLE_EVERYONE)
chaotic = 35 chaotic = 35
/datum/gm_action/comms_blackout/get_weight() /datum/gm_action/comms_blackout/get_weight()
return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 40) return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 40)
/datum/gm_action/comms_blackout/announce()
if(prob(33))
command_announcement.Announce("Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT", new_sound = 'sound/misc/interference.ogg')
// AIs will always know if there's a comm blackout, rogue AIs could then lie about comm blackouts in the future while they shutdown comms
for(var/mob/living/silicon/ai/A in player_list)
A << "<br>"
A << "<span class='warning'><b>Ionospheric anomalies detected. Temporary telecommunication failure imminent. Please contact you-BZZT</b></span>"
A << "<br>"
/datum/gm_action/comms_blackout/start()
..()
for(var/obj/machinery/telecomms/T in telecomms_list)
T.emp_act(1)

View File

@@ -0,0 +1,17 @@
/datum/gm_action/dust
name = "dust"
departments = list(ROLE_ENGINEERING)
chaotic = 10
reusable = TRUE
/datum/gm_action/dust/announce()
command_announcement.Announce("Debris resulting from activity on another nearby asteroid is approaching your colony.", "Dust Alert")
/datum/gm_action/dust/get_weight()
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
var/weight = 30 + (engineers * 25)
return weight
/datum/gm_action/dust/start()
..()
dust_swarm("norm")

View File

@@ -13,6 +13,7 @@
return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 30) return 50 + (metric.count_people_in_department(ROLE_ENGINEERING) * 30)
/datum/gm_action/grid_check/start() /datum/gm_action/grid_check/start()
..()
// This sets off a chain of events that lead to the actual grid check (or perhaps worse). // This sets off a chain of events that lead to the actual grid check (or perhaps worse).
// First, the Supermatter engine makes a power spike. // First, the Supermatter engine makes a power spike.
for(var/obj/machinery/power/generator/engine in machines) for(var/obj/machinery/power/generator/engine in machines)

View File

@@ -0,0 +1,51 @@
// This event gives the station an advance warning about meteors, so that they can prepare in various ways.
/datum/gm_action/meteor_defense
name = "meteor defense"
departments = list(ROLE_ENGINEERING)
chaotic = 50
var/direction = null
var/dir_text = null
var/waves = 0
/datum/gm_action/meteor_defense/get_weight()
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
var/weight = (max(engineers - 1, 0) * 25) // If only one engineer exists, no meteors for now.
return weight
/datum/gm_action/meteor_defense/set_up()
direction = pick(cardinal) // alldirs doesn't work with current meteor code unfortunately.
waves = rand(5, 8)
switch(direction)
if(NORTH)
dir_text = "aft" // For some reason this is needed.
if(SOUTH)
dir_text = "fore"
if(EAST)
dir_text = "port"
if(WEST)
dir_text = "starboard"
/datum/gm_action/meteor_defense/announce()
var/announcement = "Alert! Two other asteroids have collided near [station_name()]. Chunks of it are expected to approach from the [dir_text] side. ETA to arrival is \
approximately 10 minutes."
command_announcement.Announce(announcement, "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
/datum/gm_action/meteor_defense/start()
..()
spawn(0)
// sleep(5 MINUTES)
var/announcement = "The incoming debris are expected to approach from the [dir_text] side. ETA to arrival is approximately 5 minutes."
command_announcement.Announce(announcement, "Meteor Alert - Update")
// sleep(5 MINUTES)
announcement = "Incoming debris approaches from the [dir_text] side!"
command_announcement.Announce(announcement, "Meteor Alert - Update")
while(waves)
message_admins("[waves] more wave\s of meteors remain.")
spawn(1) // Dir is reversed because the direction describes where meteors are going, not what side it's gonna hit.
spawn_meteors(rand(8, 12), meteors_threatening, reverse_dir[direction])
waves--
sleep(30 SECONDS)
announcement = "The colony has cleared the incoming debris."
command_announcement.Announce(announcement, "Meteor Alert - Update")
message_admins("Meteor defense event has ended.")

View File

@@ -0,0 +1,17 @@
/datum/gm_action/shipping_error
name = "shipping error"
departments = list(ROLE_CARGO)
reusable = TRUE
/datum/gm_action/shipping_error/get_weight()
var/cargo = metric.count_people_in_department(ROLE_CARGO)
var/weight = (cargo * 40)
return weight
/datum/gm_action/shipping_error/start()
..()
var/datum/supply_order/O = new /datum/supply_order()
O.ordernum = supply_controller.ordernum
O.object = supply_controller.supply_packs[pick(supply_controller.supply_packs)]
O.orderedby = random_name(pick(MALE,FEMALE), species = "Human")
supply_controller.shoppinglist += O

View File

@@ -0,0 +1,53 @@
// This event sends a few carp after someone in space.
/datum/gm_action/surprise_carp_attack
name = "surprise carp attack"
departments = list(ROLE_EVERYONE)
reusable = TRUE
chaotic = 10
var/mob/living/victim = null
/datum/gm_action/surprise_carp_attack/get_weight()
var/people_in_space = 0
for(var/mob/living/L in player_list)
if(!(L.z in config.station_levels))
continue // Not on the right z-level.
var/turf/T = get_turf(L)
if(istype(T, /turf/space) && istype(T.loc,/area/space))
people_in_space++
return people_in_space * 50
/datum/gm_action/surprise_carp_attack/set_up()
var/list/potential_victims = list()
victim = null
for(var/mob/living/L in player_list)
if(!(L.z in config.station_levels))
continue // Not on the right z-level.
if(L.stat)
continue // Don't want dead people.
var/turf/T = get_turf(L)
if(istype(T, /turf/space) && istype(T.loc,/area/space))
potential_victims.Add(L)
victim = pick(potential_victims)
/datum/gm_action/surprise_carp_attack/start()
..()
if(!victim)
message_admins("Surprise carp attack failed to find a target.")
return
var/number_of_carp = rand(1, 2)
message_admins("Sending [number_of_carp] carp\s after [victim].")
while(number_of_carp)
var/turf/spawning_turf = null
var/list/nearby_things = oview(10, victim)
for(var/turf/space/space in nearby_things)
if(get_dist(space, victim) <= 7)
continue
spawning_turf = space
break
if(spawning_turf)
var/mob/living/simple_animal/hostile/carp/C = new(spawning_turf)
C.target_mob = victim
C.stance = STANCE_ATTACK
number_of_carp--

View File

@@ -0,0 +1,17 @@
// This event sends one wave of meteors unannounced.
/datum/gm_action/surprise_meteors
name = "surprise meteors"
departments = list(ROLE_ENGINEERING)
chaotic = 25
/datum/gm_action/surprise_meteors/get_weight()
var/engineers = metric.count_people_in_department(ROLE_ENGINEERING)
var/weight = (max(engineers - 1, 0) * 25) // If only one engineer exists, no meteors for now.
return weight
/datum/gm_action/surprise_meteors/start()
..()
spawn(1)
spawn_meteors(rand(4, 8), meteors_normal, pick(cardinal))
message_admins("Surprise meteors event has ended.")

View File

@@ -24,7 +24,7 @@
for(var/datum/gm_action/action in available_actions) for(var/datum/gm_action/action in available_actions)
if(action.enabled == FALSE) if(action.enabled == FALSE)
continue continue
HTML += "[action.name] ([english_list(action.departments)]) (weight: [action.get_weight()])<br>" HTML += "[action.name] ([english_list(action.departments)]) (weight: [action.get_weight()]) <a href='?src=\ref[action];force=1'>\[Force\]</a> <br>"
HTML += "<br>" HTML += "<br>"
HTML += "All living mobs activity: [metric.assess_all_living_mobs()]%<br>" HTML += "All living mobs activity: [metric.assess_all_living_mobs()]%<br>"
@@ -77,4 +77,16 @@
adjust_danger(amount) adjust_danger(amount)
message_admins("GM danger was adjusted by [amount] by [usr.key].") message_admins("GM danger was adjusted by [amount] by [usr.key].")
interact(usr) // To refresh the UI. interact(usr) // To refresh the UI.
/datum/gm_action/Topic(href, href_list)
if(..())
return
if(!is_admin(usr))
message_admins("[usr] has attempted to force an event without being an admin.")
return
if(href_list["force"])
gm.run_action(src)
message_admins("GM event [name] was forced by [usr.key].")

View File

@@ -19,6 +19,8 @@
/datum/game_master/New() /datum/game_master/New()
..() ..()
available_actions = init_subtypes(/datum/gm_action) available_actions = init_subtypes(/datum/gm_action)
for(var/datum/gm_action/action in available_actions)
action.gm = src
/datum/game_master/proc/process() /datum/game_master/proc/process()
if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended) if(ticker && ticker.current_state == GAME_STATE_PLAYING && !suspended)
@@ -68,17 +70,26 @@
if(best_actions && best_actions.len) if(best_actions && best_actions.len)
var/list/weighted_actions = list() var/list/weighted_actions = list()
for(var/datum/gm_action/action in best_actions) for(var/datum/gm_action/action in best_actions)
if(action.chaotic > danger)
continue // We skip dangerous events when bad stuff is already occuring.
weighted_actions[action] = action.get_weight() weighted_actions[action] = action.get_weight()
var/datum/gm_action/choice = pickweight(weighted_actions) var/datum/gm_action/choice = pickweight(weighted_actions)
if(choice) if(choice)
log_debug("[choice.name] was chosen by the Game Master, and is now being ran.") log_debug("[choice.name] was chosen by the Game Master, and is now being ran.")
choice.set_up() run_action(choice)
choice.start()
next_action = world.time + rand(15 MINUTES, 30 MINUTES)
last_department_used = choice.departments[1]
/datum/game_master/proc/run_action(var/datum/gm_action/action)
action.set_up()
action.start()
action.announce()
if(action.chaotic)
danger += action.chaotic
if(action.length)
spawn(action.length)
action.end()
next_action = world.time + rand(15 MINUTES, 30 MINUTES)
last_department_used = action.departments[1]
/datum/game_master/proc/decide_best_action(var/list/most_active_departments) /datum/game_master/proc/decide_best_action(var/list/most_active_departments)

View File

@@ -148,11 +148,19 @@
return return
user << "<span class='notice'>The crate is locked with a Deca-code lock.</span>" user << "<span class='notice'>The crate is locked with a Deca-code lock.</span>"
var/input = input(user, "Enter [codelen] digits.", "Deca-Code Lock", "") as text var/input = input(usr, "Enter [codelen] digits. All digits must be unique.", "Deca-Code Lock", "") as text
if(!Adjacent(user)) if(!Adjacent(user))
return return
var/list/sanitised = list()
var/sanitycheck = 1
for(var/i=1,i<=length(input),i++) //put the guess into a list
sanitised += text2num(copytext(input,i,i+1))
for(var/i=1,i<=(length(input)-1),i++) //compare each digit in the guess to all those following it
for(var/j=(i+1),j<=length(input),j++)
if(sanitised[i] == sanitised[j])
sanitycheck = null //if a digit is repeated, reject the input
if(input == null || length(input) != codelen) if(input == null || sanitycheck == null || length(input) != codelen)
user << "<span class='notice'>You leave the crate alone.</span>" user << "<span class='notice'>You leave the crate alone.</span>"
else if(check_input(input)) else if(check_input(input))
user << "<span class='notice'>The crate unlocks!</span>" user << "<span class='notice'>The crate unlocks!</span>"
@@ -203,6 +211,9 @@
else if(lastattempt[i] in code_contents) else if(lastattempt[i] in code_contents)
++cows ++cows
code_contents -= lastattempt[i] code_contents -= lastattempt[i]
user << "<span class='notice'>Last code attempt had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions.</span>" var/previousattempt = null //convert back to string for readback
for(var/i in 1 to codelen)
previousattempt = addtext(previousattempt, lastattempt[i])
user << "<span class='notice'>Last code attempt, [previousattempt], had [bulls] correct digits at correct positions and [cows] correct digits at incorrect positions.</span>"
return return
..() ..()

View File

@@ -17,7 +17,7 @@
var/list/resource_field = list() var/list/resource_field = list()
var/ore_types = list( var/ore_types = list(
"iron" = /obj/item/weapon/ore/iron, "hematite" = /obj/item/weapon/ore/iron,
"uranium" = /obj/item/weapon/ore/uranium, "uranium" = /obj/item/weapon/ore/uranium,
"gold" = /obj/item/weapon/ore/gold, "gold" = /obj/item/weapon/ore/gold,
"silver" = /obj/item/weapon/ore/silver, "silver" = /obj/item/weapon/ore/silver,
@@ -26,7 +26,7 @@
"osmium" = /obj/item/weapon/ore/osmium, "osmium" = /obj/item/weapon/ore/osmium,
"hydrogen" = /obj/item/weapon/ore/hydrogen, "hydrogen" = /obj/item/weapon/ore/hydrogen,
"silicates" = /obj/item/weapon/ore/glass, "silicates" = /obj/item/weapon/ore/glass,
"carbonaceous rock" = /obj/item/weapon/ore/coal "carbon" = /obj/item/weapon/ore/coal
) )
//Upgrades //Upgrades

View File

@@ -29,7 +29,7 @@
var/ore_type var/ore_type
switch(metal) switch(metal)
if("silicates", "carbonaceous rock", "iron") ore_type = "surface minerals" if("silicates", "carbon", "hematite") ore_type = "surface minerals"
if("gold", "silver", "diamond") ore_type = "precious metals" if("gold", "silver", "diamond") ore_type = "precious metals"
if("uranium") ore_type = "nuclear fuel" if("uranium") ore_type = "nuclear fuel"
if("phoron", "osmium", "hydrogen") ore_type = "exotic matter" if("phoron", "osmium", "hydrogen") ore_type = "exotic matter"

View File

@@ -175,9 +175,8 @@ var/list/mining_overlay_cache = list()
if(severity <= 2) // Now to expose the ore lying under the sand. if(severity <= 2) // Now to expose the ore lying under the sand.
spawn(1) // Otherwise most of the ore is lost to the explosion, which makes this rather moot. spawn(1) // Otherwise most of the ore is lost to the explosion, which makes this rather moot.
var/losses = rand(0.5, 1) // Between 0% to 50% loss due to booms.
for(var/ore in resources) for(var/ore in resources)
var/amount_to_give = Ceiling(resources[ore] * losses) // Should result in at least one piece of ore. var/amount_to_give = rand(Ceiling(resources[ore]/2), resources[ore]) // Should result in at least one piece of ore.
for(var/i=1, i <= amount_to_give, i++) for(var/i=1, i <= amount_to_give, i++)
var/oretype = ore_types[ore] var/oretype = ore_types[ore]
new oretype(src) new oretype(src)

View File

@@ -708,6 +708,10 @@
icon_state = module_sprites[icontype] icon_state = module_sprites[icontype]
return return
if(typing)
typing = FALSE
set_typing_indicator(1)
/mob/living/silicon/robot/proc/installed_modules() /mob/living/silicon/robot/proc/installed_modules()
if(weapon_lock) if(weapon_lock)
src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]" src << "\red Weapon lock active, unable to use modules! Count:[weaponlock_time]"

View File

@@ -29,7 +29,7 @@
cold_damage_per_tick = 20 cold_damage_per_tick = 20
var/poison_per_bite = 5 var/poison_per_bite = 5
var/poison_chance = 10 var/poison_chance = 10
var/poison_type = "toxin" var/poison_type = "spidertoxin"
faction = "spiders" faction = "spiders"
var/busy = 0 var/busy = 0
pass_flags = PASSTABLE pass_flags = PASSTABLE
@@ -85,9 +85,14 @@
if(prob(5)) if(prob(5))
var/obj/item/organ/external/O = pick(H.organs) var/obj/item/organ/external/O = pick(H.organs)
if(!(O.robotic >= ORGAN_ROBOT)) if(!(O.robotic >= ORGAN_ROBOT))
var/eggs = PoolOrNew(/obj/effect/spider/eggcluster/, list(O, src)) var/eggcount
O.implants += eggs for(var/obj/I in O.implants)
H << "<span class='warning'>The [src] injects something into your [O.name]!</span>" if(istype(I, /obj/effect/spider/eggcluster))
eggcount ++
if(!eggcount)
var/eggs = PoolOrNew(/obj/effect/spider/eggcluster/small, list(O, src))
O.implants += eggs
H << "<span class='warning'>The [src] injects something into your [O.name]!</span>"
/mob/living/simple_animal/hostile/giant_spider/Life() /mob/living/simple_animal/hostile/giant_spider/Life()
..() ..()

View File

@@ -0,0 +1,11 @@
/mob/living/simple_animal/hostile/goose
//Space geese aren't affected by atmos.
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0

View File

@@ -23,10 +23,10 @@
if(!M.restrained() && !M.stat) if(!M.restrained() && !M.stat)
switch(over_object.name) switch(over_object.name)
if("r_hand") if("r_hand")
M.u_equip(src) M.unEquip(src)
M.put_in_r_hand(src) M.put_in_r_hand(src)
if("l_hand") if("l_hand")
M.u_equip(src) M.unEquip(src)
M.put_in_l_hand(src) M.put_in_l_hand(src)
add_fingerprint(usr) add_fingerprint(usr)

View File

@@ -16,6 +16,7 @@
var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier! var/maxcopies = 10 //how many copies can be copied at once- idea shamelessly stolen from bs12's copier!
/obj/machinery/photocopier/New() /obj/machinery/photocopier/New()
..()
component_parts = list() component_parts = list()
component_parts += new /obj/item/weapon/stock_parts/scanning_module(src) component_parts += new /obj/item/weapon/stock_parts/scanning_module(src)
component_parts += new /obj/item/weapon/stock_parts/motor(src) component_parts += new /obj/item/weapon/stock_parts/motor(src)

View File

@@ -98,10 +98,10 @@ var/global/photo_count = 0
if((!( M.restrained() ) && !( M.stat ) && M.back == src)) if((!( M.restrained() ) && !( M.stat ) && M.back == src))
switch(over_object.name) switch(over_object.name)
if("r_hand") if("r_hand")
M.u_equip(src) M.unEquip(src)
M.put_in_r_hand(src) M.put_in_r_hand(src)
if("l_hand") if("l_hand")
M.u_equip(src) M.unEquip(src)
M.put_in_l_hand(src) M.put_in_l_hand(src)
add_fingerprint(usr) add_fingerprint(usr)
return return

View File

@@ -701,6 +701,7 @@
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.species.can_shred(H)) if(H.species.can_shred(H))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
user.visible_message("<span call='warning'>[user.name] slashes at the [src.name]!</span>", "<span class='notice'>You slash at the [src.name]!</span>") user.visible_message("<span call='warning'>[user.name] slashes at the [src.name]!</span>", "<span class='notice'>You slash at the [src.name]!</span>")
playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1) playsound(src.loc, 'sound/weapons/slash.ogg', 100, 1)

View File

@@ -535,6 +535,7 @@
if(istype(user,/mob/living/carbon/human)) if(istype(user,/mob/living/carbon/human))
var/mob/living/carbon/human/H = user var/mob/living/carbon/human/H = user
if(H.species.can_shred(H)) if(H.species.can_shred(H))
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
for(var/mob/M in viewers(src)) for(var/mob/M in viewers(src))
M.show_message("\red [user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2) M.show_message("\red [user.name] smashed the light!", 3, "You hear a tinkle of breaking glass", 2)
broken() broken()

View File

@@ -0,0 +1,87 @@
/obj/item/weapon/gun/energy/particle
name = "Antiparticle projector gun"
icon = 'icons/obj/gun_vr.dmi'
icon_state = "particle"
item_state = "particle"
desc = "An unconventional firearm, APP guns generate attogram-scale quantities of antimatter which are then launched using an electromagnetic field."
force = 5
fire_sound = 'sound/weapons/Laser.ogg'
slot_flags = SLOT_BELT
w_class = ITEMSIZE_NORMAL
projectile_type = /obj/item/projectile/bullet/particle
origin_tech = null
fire_delay = 10
charge_cost = 240 //same cost as lasers
var/safetycatch = 0 //if 1, won't let you fire in pressurised environment, rather than malfunctioning
/obj/item/weapon/gun/energy/particle/special_check(var/mob/user)
if (..())
var/turf/T = get_turf(src)
var/datum/gas_mixture/environment = T ? T.return_air() : null
var/pressure = environment ? environment.return_pressure() : 0
if (!power_supply || power_supply.charge < charge_cost)
user.visible_message("<span class='warning'>*click*</span>", "<span class='danger'>*click*</span>")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
return 0
if(pressure >= 10)
if (safetycatch) //weapons with a pressure regulator simply won't fire
user.visible_message("<span class='warning'>*click*</span>", "<span class='danger'>The pressure-interlock prevents you from firing \the [src].</span>")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
return 0
else if (prob(min(pressure, 100))) //pressure% chance of failing
var/severity = rand(pressure)
if (severity <= 10) // just doesn't fire. 10% chance in 100 atmo.
user.visible_message("<span class='warning'>*click*</span>", "<span class='danger'>\The [src] jams.</span>")
playsound(src.loc, 'sound/weapons/empty.ogg', 100, 1)
else if (severity <= 60) //50% chance of fizzling and wasting a shot
user.visible_message("<span class='warning'>\The [user] fires \the [src], but the shot fizzles in the air!</span>", "<span class='danger'>You fire \the [src], but the shot fizzles in the air!</span>")
power_supply.charge -= charge_cost
playsound(src.loc, fire_sound, 100, 1)
var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread)
sparks.set_up(2, 1, T)
sparks.start()
update_icon()
else if (severity <= 80) //20% chance of shorting out and emptying the cell
user.visible_message("<span class='warning'>\The [user] pulls the trigger, but \the [src] shorts out!</span>", "<span class='danger'>You pull the trigger, but \the [src] shorts out!</span>")
power_supply.charge = 0
var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread)
sparks.set_up(2, 1, T)
sparks.start()
update_icon()
else if (severity <= 90) //10% chance of breaking the gun
user.visible_message("<span class='warning'>\The [user] pulls the trigger, but \the [src] erupts in a shower of sparks!</span>", "<span class='danger'>You pull the trigger, but \the [src] bursts into a shower of sparks!</span>")
var/datum/effect/effect/system/spark_spread/sparks = PoolOrNew(/datum/effect/effect/system/spark_spread)
sparks.set_up(2, 1, T)
sparks.start()
power_supply.charge = 0
power_supply.maxcharge = 0
power_supply.desc += " It seems to be burnt out!"
desc += " The casing is covered in scorch-marks."
fire_delay += fire_delay // even if you swap out the cell for a good one, the gun's cluckety-clucked.
charge_cost += charge_cost
update_icon()
else if (severity <= 150) // 10% chance of exploding
user << "<span class='danger'>The [src] explodes!</span>"
explosion(T, -1, -1, 1, 1)
qdel(src)
else //can only possibly happen if you're dumb enough to fire it in an OVER pressure environment, over 150kPa
user << "<span class='danger'>The [src] explodes catastrophically!</span>"
explosion(T, -1, 1, 2, 2)
qdel(src)
return 0
return 1
return 0
// projectiles below
/obj/item/projectile/bullet/particle
name = "particle"
icon = 'icons/obj/projectiles_vr.dmi'
icon_state = "particle"
damage = 40
damage_type = BURN
check_armour = "energy"
embed_chance = 0

View File

@@ -0,0 +1,6 @@
/obj/item/weapon/gun/energy/taser
charge_cost = 160
fire_delay = 4
/obj/item/weapon/gun/energy/stunrevolver
charge_cost = 400

View File

@@ -0,0 +1,2 @@
/obj/item/weapon/gun/projectile/sec/flash
name = ".45 pistol"

View File

@@ -57,6 +57,7 @@
icon_state = "darkcannon" icon_state = "darkcannon"
item_state = "darkcannon" item_state = "darkcannon"
fire_sound = 'sound/weapons/eLuger.ogg' fire_sound = 'sound/weapons/eLuger.ogg'
w_class = ITEMSIZE_HUGE
charge_cost = 600 charge_cost = 600
projectile_type = /obj/item/projectile/beam/darkmatter projectile_type = /obj/item/projectile/beam/darkmatter
self_recharge = 1 self_recharge = 1
@@ -102,6 +103,7 @@
icon_state = "noise" icon_state = "noise"
item_state = "noise" item_state = "noise"
fire_sound = 'sound/effects/basscannon.ogg' fire_sound = 'sound/effects/basscannon.ogg'
w_class = ITEMSIZE_HUGE
self_recharge = 1 self_recharge = 1
charge_cost = 600 charge_cost = 600

View File

@@ -10,3 +10,6 @@
muzzle_type = /obj/effect/projectile/laser_omni/muzzle muzzle_type = /obj/effect/projectile/laser_omni/muzzle
tracer_type = /obj/effect/projectile/laser_omni/tracer tracer_type = /obj/effect/projectile/laser_omni/tracer
impact_type = /obj/effect/projectile/laser_omni/impact impact_type = /obj/effect/projectile/laser_omni/impact
/obj/item/projectile/beam/stun
agony = 35

View File

@@ -0,0 +1,11 @@
/obj/item/projectile/energy/electrode/strong
agony = 70
/obj/item/projectile/energy
flash_strength = 10
/obj/item/projectile/energy/flash
flash_range = 1
/obj/item/projectile/energy/flash/flare
flash_range = 2

View File

@@ -107,8 +107,10 @@ obj/aiming_overlay/proc/update_aiming_deferred()
cancel_aiming() cancel_aiming()
return return
if(!locked && lock_time >= world.time) if(!locked && lock_time <= world.time)
locked = 1 locked = 1
owner << "<span class ='notice'>You are locked onto your target.</span>"
aiming_at << "<span class='danger'>The gun is trained on you!</span>"
update_icon() update_icon()
var/cancel_aim = 1 var/cancel_aim = 1
@@ -176,7 +178,7 @@ obj/aiming_overlay/proc/update_aiming_deferred()
toggle_active(1) toggle_active(1)
locked = 0 locked = 0
update_icon() update_icon()
lock_time = world.time + 35 lock_time = world.time + 25
/obj/aiming_overlay/update_icon() /obj/aiming_overlay/update_icon()
if(locked) if(locked)

View File

@@ -27,3 +27,5 @@
var/obj/item/weapon/gun/G = aiming_with var/obj/item/weapon/gun/G = aiming_with
if(istype(G)) if(istype(G))
G.Fire(aiming_at, owner, reflex = 1) G.Fire(aiming_at, owner, reflex = 1)
locked = 0
lock_time = world.time+10

View File

@@ -49,11 +49,11 @@
if(!priority_process) sleep(-1) if(!priority_process) sleep(-1)
T.resources = list() T.resources = list()
T.resources["silicates"] = rand(3,5) T.resources["silicates"] = rand(3,5)
T.resources["carbonaceous rock"] = rand(3,5) T.resources["carbon"] = rand(3,5)
var/current_cell = map[get_map_cell(x,y)] var/current_cell = map[get_map_cell(x,y)]
if(current_cell < rare_val) // Surface metals. if(current_cell < rare_val) // Surface metals.
T.resources["iron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) T.resources["hematite"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX)
T.resources["gold"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) T.resources["gold"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX)
T.resources["silver"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) T.resources["silver"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX)
T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX)
@@ -69,14 +69,14 @@
T.resources["osmium"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) T.resources["osmium"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX)
T.resources["hydrogen"] = 0 T.resources["hydrogen"] = 0
T.resources["diamond"] = 0 T.resources["diamond"] = 0
T.resources["iron"] = 0 T.resources["hematite"] = 0
else // Deep metals. else // Deep metals.
T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) T.resources["uranium"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX)
T.resources["diamond"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX) T.resources["diamond"] = rand(RESOURCE_LOW_MIN, RESOURCE_LOW_MAX)
T.resources["phoron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) T.resources["phoron"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX)
T.resources["osmium"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX) T.resources["osmium"] = rand(RESOURCE_HIGH_MIN, RESOURCE_HIGH_MAX)
T.resources["hydrogen"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX) T.resources["hydrogen"] = rand(RESOURCE_MID_MIN, RESOURCE_MID_MAX)
T.resources["iron"] = 0 T.resources["hematite"] = 0
T.resources["gold"] = 0 T.resources["gold"] = 0
T.resources["silver"] = 0 T.resources["silver"] = 0
return return

View File

@@ -75,7 +75,7 @@
return return
else else
trans = reagents.splash(target, amount_per_transfer_from_this, max_spill=30) //sprinkling reagents on generic non-mobs trans = reagents.splash(target, amount_per_transfer_from_this, max_spill=0) //sprinkling reagents on generic non-mobs
user << "<span class='notice'>You transfer [trans] units of the solution.</span>" user << "<span class='notice'>You transfer [trans] units of the solution.</span>"
else // Taking from something else // Taking from something

View File

@@ -131,23 +131,28 @@
..() ..()
reagents.add_reagent("soymilk", 50) reagents.add_reagent("soymilk", 50)
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton /obj/item/weapon/reagent_containers/food/drinks/smallmilk
name = "small milk carton" name = "small milk carton"
desc = "It's milk. White and nutritious goodness!"
volume = 30 volume = 30
icon_state = "mini-milk" icon_state = "mini-milk"
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/New() item_state = "carton"
center_of_mass = list("x"=16, "y"=9)
/obj/item/weapon/reagent_containers/food/drinks/smallmilk/New()
..() ..()
reagents.add_reagent("milk", 30) reagents.add_reagent("milk", 30)
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate /obj/item/weapon/reagent_containers/food/drinks/smallchocmilk
name = "small chocolate milk carton" name = "small chocolate milk carton"
desc = "It's milk! This one is in delicious chocolate flavour." desc = "It's milk! This one is in delicious chocolate flavour."
volume = 30
icon_state = "mini-milk_choco" icon_state = "mini-milk_choco"
/obj/item/weapon/reagent_containers/food/drinks/milk/smallcarton/chocolate/New() item_state = "carton"
center_of_mass = list("x"=16, "y"=9)
/obj/item/weapon/reagent_containers/food/drinks/smallchocmilk/New()
..() ..()
reagents.add_reagent("chocolate_milk", 30) reagents.add_reagent("chocolate_milk", 30)
/obj/item/weapon/reagent_containers/food/drinks/coffee /obj/item/weapon/reagent_containers/food/drinks/coffee
name = "\improper Robust Coffee" name = "\improper Robust Coffee"
desc = "Careful, the beverage you're about to enjoy is extremely hot." desc = "Careful, the beverage you're about to enjoy is extremely hot."

View File

@@ -22,16 +22,16 @@
if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/breadslice)) if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/breadslice))
sandwich_limit += 4 sandwich_limit += 4
if(src.contents.len > sandwich_limit) if(istype(W,/obj/item/weapon/material/shard))
user << "\red If you put anything else on \the [src] it's going to collapse."
return
else if(istype(W,/obj/item/weapon/material/shard))
user << "\blue You hide [W] in \the [src]." user << "\blue You hide [W] in \the [src]."
user.drop_item() user.drop_item()
W.loc = src W.loc = src
update() update()
return return
else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks)) else if(istype(W,/obj/item/weapon/reagent_containers/food/snacks))
if(src.contents.len > sandwich_limit)
user << "\red If you put anything else on \the [src] it's going to collapse."
return
user << "\blue You layer [W] over \the [src]." user << "\blue You layer [W] over \the [src]."
var/obj/item/weapon/reagent_containers/F = W var/obj/item/weapon/reagent_containers/F = W
F.reagents.trans_to_obj(src, F.reagents.total_volume) F.reagents.trans_to_obj(src, F.reagents.total_volume)

View File

@@ -0,0 +1,12 @@
/obj/item/weapon/reagent_containers/spray/windowsealant
name = "Krak-b-gone"
desc = "A spray bottle of silicate sealant for rapid window repair."
icon = 'icons/obj/items_vr.dmi'
icon_state = "windowsealant"
item_state = "spraycan"
possible_transfer_amounts = null
volume = 80
/obj/item/weapon/reagent_containers/spray/windowsealant/New()
..()
reagents.add_reagent("silicate", 80)

View File

@@ -0,0 +1,150 @@
//////////////////////////////
// An asteroid object, could be spawned in, or not
// May or may not include phat lewt
//////////////////////////////
/datum/rogue/asteroid
//Composition
var/type_wall = /turf/simulated/mineral //Type of turf used to generate the asteroid
var/type_under = /turf/simulated/mineral/floor //Type of turf that's under the normal one
//Dimensions
var/coresize = 3 //The size of the center square
var/width = 9
//Other Attribs
var/hollow = 0 //Might be hollow for loot injection purposes
var/spawned = 0 //Is this asteroid in-play right now
var/difficulty = 0 //Difficulty this asteroid was created at
//Locational stats
var/obj/effect/landmark/asteroid_spawn/mylandmark //The landmark I'm spawned at, if any.
//Asteroid map
//The map struct is:
// map list()
// 0 = list()
// 1 = list() //These are x coordinates
// 2 = list()
// ^0 = list()
// 1 = list() //These are y coordinates at x2
// 2 = list()
// ^type1
// type2 //These are items/objects at the coordinate
// type3 //This would be object 3 at x2,y2
var/list/map
//Builds an empty map
/datum/rogue/asteroid/New(var/core, var/tw, var/tu)
rm_controller.dbg("A(n): New asteroid, with: C:[core], TW:[tw], TU:[tu].")
if(core)
coresize = core
if(tw)
type_wall = tw
if(tu)
type_under = tu
width = coresize*3
rm_controller.dbg("A(n): My width is [width].")
map = new/list(width,width,0)
rm_controller.dbg("A(n): Created empty map lists. Map now has [map.len] X-lists.")
//Adds something to a spot in the asteroid map
/datum/rogue/asteroid/proc/spot_add(var/x,var/y,var/thing)
if(!x || !y || !thing)
return
rm_controller.dbg("A(sa): Adding [thing] at [x],[y] in the map.")
var/list/work = map[x][y]
work.Add(thing)
rm_controller.dbg("A(n): [x],[y] now contains [work.len] items.")
//Removes something from a spot in the asteroid map
/datum/rogue/asteroid/proc/spot_remove(var/x,var/y,var/thing)
if(!x || !y || !thing)
return
var/list/work = map[x][y]
work.Add(thing)
//Just removes everything from a spot in the asteroid map
/datum/rogue/asteroid/proc/spot_clear(var/x,var/y)
if(!x || !y)
return
var/list/work = map[x][y]
work.Cut()
/////////////////////////////
// Predefined asteroid maps
/////////////////////////////
/datum/rogue/asteroid/predef
width = 3 //Small 1-tile room by default.
/datum/rogue/asteroid/predef/New() //Basically just ignore what we're told.
rm_controller.dbg("Ap(n): A predefined asteroid is created with width [width].")
map = new/list(width,width,0)
//Abandoned 1-tile hollow cargo box (pressurized).
/datum/rogue/asteroid/predef/cargo
type_wall = /turf/simulated/wall
type_under = /turf/simulated/floor/plating
New()
..()
spot_add(1,1,type_wall) //Bottom left corner
spot_add(1,2,type_wall)
spot_add(1,3,type_wall)
spot_add(2,1,type_wall)
spot_add(2,2,type_under) //Center floor
spot_add(2,2,/obj/random/cargopod) //Loot!
spot_add(2,3,type_wall)
spot_add(3,1,type_wall)
spot_add(3,2,type_wall)
spot_add(3,3,type_wall) //Bottom right corner
//Abandoned 1-tile hollow cargo box (ANGRY).
/datum/rogue/asteroid/predef/cargo/angry
type_wall = /turf/simulated/wall
type_under = /turf/simulated/floor/plating
New()
..()
spot_add(2,2,/obj/random/cargopod) //EXTRA loot!
spot_add(2,2,/mob/living/simple_animal/hostile/vore/alien) //GRRR
//Longer cargo container for higher difficulties
/datum/rogue/asteroid/predef/cargo_large
width = 5
type_wall = /turf/simulated/wall
type_under = /turf/simulated/floor/plating
New()
..()
spot_add(1,2,type_wall) //--
spot_add(1,3,type_wall) //Left end of cargo container
spot_add(1,4,type_wall) //--
spot_add(5,2,type_wall) //--
spot_add(5,3,type_wall) //Right end of cargo container
spot_add(5,4,type_wall) //--
spot_add(2,4,type_wall) //--
spot_add(3,4,type_wall) //Top and
spot_add(4,4,type_wall) //bottom of
spot_add(2,2,type_wall) //cargo
spot_add(3,2,type_wall) //container
spot_add(4,2,type_wall) //--
spot_add(2,3,type_under) //Left floor
spot_add(3,3,type_under) //Mid floor
spot_add(4,3,type_under) //Right floor
spot_add(2,3,/obj/random/cargopod) //Left loot
spot_add(3,3,/obj/random/cargopod) //Mid loot
spot_add(4,3,/obj/random/cargopod) //Right loot
if(prob(30))
spot_add(3,3,/mob/living/simple_animal/hostile/vore/alien) //And maybe a friend.

View File

@@ -0,0 +1,164 @@
//////////////////////////////
// Tracks mining zone progress and decay
// Makes mining zones more difficult as you enter new ones
// THIS IS THE FIRST UNIT INITIALIZED THAT STARTS EVERYTHING
//////////////////////////////
var/datum/controller/rogue/rm_controller = new()
/datum/controller/rogue
var/list/datum/rogue/zonemaster/all_zones = list()
var/list/datum/rogue/zonemaster/clean_zones = list()
var/list/datum/rogue/zonemaster/ready_zones = list()
//So I don't have to do absurd list[list[thing]] over and over.
var/list/diffstep_nums = list(
100,
200,
300,
450,
600,
800)
var/list/diffstep_strs = list(
"Low",
"Moderate",
"High",
"Very High",
"Extreme",
"ERROR!!@MEM:CH@05R31GN5")
//The ever-changing difficulty
var/difficulty = 100
//Info about our current step
var/diffstep = 1
//The current mining zone that the shuttle goes to and whatnot
var/datum/rogue/zonemaster/current_zone = null
var/datum/rogue/zonemaster/previous_zone = null
// The world.time at which the scanner was last run (for cooldown)
var/last_scan = 0
var/scan_wait = 10 //In minutes
var/debugging = 0
///// Prefab Asteroids /////
var/prefabs = list(
"tier1" = list(/datum/rogue/asteroid/predef/cargo),
"tier2" = list(/datum/rogue/asteroid/predef/cargo,/datum/rogue/asteroid/predef/cargo/angry),
"tier3" = list(/datum/rogue/asteroid/predef/cargo/angry,/datum/rogue/asteroid/predef/cargo_large),
"tier4" = list(/datum/rogue/asteroid/predef/cargo/angry,/datum/rogue/asteroid/predef/cargo_large),
"tier5" = list(/datum/rogue/asteroid/predef/cargo/angry,/datum/rogue/asteroid/predef/cargo_large),
"tier6" = list(/datum/rogue/asteroid/predef/cargo/angry,/datum/rogue/asteroid/predef/cargo_large)
)
///// Monster Lists /////
var/mobs = list(
"tier1" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose),
"tier2" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose),
"tier3" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose,/mob/living/simple_animal/hostile/vore/bear),
"tier4" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose,/mob/living/simple_animal/hostile/vore/bear),
"tier5" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose,/mob/living/simple_animal/hostile/vore/bear),
"tier6" = list(/mob/living/simple_animal/hostile/carp,/mob/living/simple_animal/hostile/goose,/mob/living/simple_animal/hostile/vore/bear)
)
/datum/controller/rogue/New()
//How many zones are we working with here
for(var/area/asteroid/rogue/A in world)
all_zones += new /datum/rogue/zonemaster(A)
//decay() //Decay removed for now, since people aren't getting high scores as it is.
/datum/controller/rogue/proc/decay(var/manual = 0)
world.log << "RM(stats): DECAY on controller from [difficulty] to [difficulty+(RM_DIFF_DECAY_AMT)] min 100." //DEBUG code for playtest stats gathering.
adjust_difficulty(RM_DIFF_DECAY_AMT)
if(!manual) //If it was called manually somehow, then don't start the timer, just decay now.
spawn(RM_DIFF_DECAY_TIME)
decay()
return difficulty
/datum/controller/rogue/proc/dbg(var/message)
ASSERT(message) //I want a stack trace if there's no message
if(debugging)
world.log << "[message]"
/datum/controller/rogue/proc/adjust_difficulty(var/amt)
ASSERT(amt)
difficulty = max(difficulty+amt, diffstep_nums[1]) //Can't drop below the lowest level.
if(difficulty < diffstep_nums[diffstep])
diffstep--
else if(difficulty >= diffstep_nums[diffstep+1])
diffstep++
/datum/controller/rogue/proc/get_oldest_zone()
var/oldest_time = world.time
var/oldest_zone
for(var/datum/rogue/zonemaster/ZM in ready_zones)
if(ZM.prepared_at < oldest_time) //Check ready so we don't return zones that ARE cleaning
oldest_zone = ZM
oldest_time = ZM.prepared_at
return oldest_zone
/datum/controller/rogue/proc/mark_clean(var/datum/rogue/zonemaster/ZM)
if(!ZM in all_zones) //What? Who?
rm_controller.dbg("RMC(mc): Some unknown zone asked to be listed.")
if(ZM in ready_zones)
rm_controller.dbg("RMC(mc): Finite state machine broken.")
clean_zones += ZM
/datum/controller/rogue/proc/mark_ready(var/datum/rogue/zonemaster/ZM)
if(!ZM in all_zones) //What? Who?
rm_controller.dbg("RMC(mr): Some unknown zone asked to be listed.")
if(ZM in clean_zones)
rm_controller.dbg("RMC(mr): Finite state machine broken.")
ready_zones += ZM
/datum/controller/rogue/proc/unmark_clean(var/datum/rogue/zonemaster/ZM)
if(!ZM in all_zones) //What? Who?
rm_controller.dbg("RMC(umc): Some unknown zone asked to be listed.")
if(!ZM in clean_zones)
rm_controller.dbg("RMC(umc): Finite state machine broken.")
clean_zones -= ZM
/datum/controller/rogue/proc/unmark_ready(var/datum/rogue/zonemaster/ZM)
if(!ZM in all_zones) //What? Who?
rm_controller.dbg("RMC(umr): Some unknown zone asked to be listed.")
if(!ZM in ready_zones)
rm_controller.dbg("RMC(umr): Finite state machine broken.")
ready_zones -= ZM
/datum/controller/rogue/proc/prepare_new_zone()
var/datum/rogue/zonemaster/ZM_target
if(clean_zones.len)
ZM_target = pick(clean_zones)
if(ZM_target)
world.log << "RM(stats): SCORING [ready_zones.len] zones (if unscored)." //DEBUG code for playtest stats gathering.
for(var/datum/rogue/zonemaster/ZM_toscore in ready_zones) //Score all the zones first.
if(ZM_toscore.scored) continue
ZM_toscore.score_zone()
ZM_target.prepare_zone()
else
rm_controller.dbg("RMC(pnz): I was asked for a new zone but there's no space.")
if(clean_zones.len <= 1) //Need to clean the oldest one, too.
rm_controller.dbg("RMC(pnz): Cleaning up oldest zone.")
spawn(0) //Detatch it so we can return the new zone for now.
var/datum/rogue/zonemaster/ZM_oldest = get_oldest_zone()
ZM_oldest.clean_zone()
return ZM_target

View File

@@ -0,0 +1,8 @@
/client/proc/debug_rogueminer()
set category = "Debug"
set name = "Debug RogueMiner"
set desc = "Debug the RogueMiner controller."
if(!holder) return
debug_variables(rm_controller)
feedback_add_details("admin_verb","DRM")

View File

@@ -0,0 +1,30 @@
//////////////////////////////
// Landmarks for asteroid positioning
// Just makes the placement more safe/sane
//////////////////////////////
/obj/asteroid_spawner
name = "asteroid spawn"
icon = 'icons/mob/screen1.dmi'
icon_state = "x2"
invisibility = 101
anchored = 1
var/datum/rogue/asteroid/myasteroid
/obj/asteroid_spawner/New()
if(loc && istype(loc,/turf/space) && istype(loc.loc,/area/asteroid/rogue))
var/area/asteroid/rogue/A = loc.loc
A.asteroid_spawns += src
/obj/rogue_mobspawner
name = "mob spawn"
icon = 'icons/mob/screen1.dmi'
icon_state = "x"
invisibility = 101
anchored = 1
var/mob/mymob
/obj/rogue_mobspawner/New()
if(loc && istype(loc,/turf/space) && istype(loc.loc,/area/asteroid/rogue))
var/area/asteroid/rogue/A = loc.loc
A.mob_spawns += src

View File

@@ -0,0 +1,206 @@
/obj/effect/step_trigger/teleporter/random/rogue
teleport_z = 7
teleport_z_offset = 7
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour
var/margin = 15 //How far from the side should we teleport? Make sure to place the opposite
//side's wrappers at less than this far from the hard boundary
//else people will get stuck in the margins
//Important for auto-determining the size, as well.
var/mapsize = 300 //I don't know of a way to obtain map size sorry.
//Important infos!
var/quad_L
var/quad_R
var/quad_U
var/quad_D
//Relative to the quadrant
var/rel_x
var/rel_y
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/New()
..()
//Figure out where I am on the map and set up vars.
if(x < mapsize/2 && y < mapsize/2) //We're in area 1!
quad_L = 0
quad_R = mapsize/2
quad_U = mapsize/2
quad_D = 0
rel_x = x
rel_y = y
else if(x >= mapsize/2 && y < mapsize/2) //We're in area 2!
quad_L = mapsize/2
quad_R = mapsize
quad_U = mapsize/2
quad_D = 0
rel_x = x-(mapsize/2)
rel_y = y
else if(x < mapsize/2 && y >= mapsize/2) //We're in area 3!
quad_L = 0
quad_R = mapsize/2
quad_U = mapsize
quad_D = mapsize/2
rel_x = x
rel_y = y-(mapsize/2)
else if(x >= mapsize/2 && y >= mapsize/2) //We're in area 4!
quad_L = mapsize/2
quad_R = mapsize
quad_U = mapsize
quad_D = mapsize/2
rel_x = x-(mapsize/2)
rel_y = y-(mapsize/2)
else
return
//These are placed ON the side they are named after.
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onleft/New()
..()
teleport_x = quad_R - margin
teleport_x_offset = quad_R - margin
teleport_y = quad_D + margin
teleport_y_offset = quad_U - margin
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onright/New()
..()
teleport_x = quad_L + margin
teleport_x_offset = quad_L + margin
teleport_y = quad_D + margin
teleport_y_offset = quad_U - margin
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/ontop/New()
..()
teleport_x = quad_L + margin
teleport_x_offset = quad_R - margin
teleport_y = quad_D + margin
teleport_y_offset = quad_D + margin
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onbottom/New()
..()
teleport_x = quad_L + margin
teleport_x_offset = quad_R - margin
teleport_y = quad_U - margin
teleport_y_offset = quad_U - margin
//Sure, I could probably do this with math. But I'm tired.
/*
S1 300
-----------------------------------
|015/285 135/285|166/285 285/285|
| | |S
| A3 | A4 |2
| | |
0|015/166 135/166|166/166 285/166|3
0|---------------------------------|0
0|015/135 135/135|166/135 285/135|0
| | |
S| A1 | A2 |
4| | |
|015/015 135/015|166/015 285/015|
-----------------------------------
000 S3
*/
/*
//////////// AREA 1
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A1S1
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A1S2
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A1S3
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A1S4
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
//////////// AREA 2
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A2S1
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A2S2
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A2S3
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A2S4
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
//////////// AREA 3
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A3S1
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A3S2
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A3S3
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A3S4
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
//////////// AREA 4
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A4S1
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A4S2
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A4S3
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/A4S4
teleport_x =
teleport_y =
teleport_x_offset =
teleport_y_offset =
*/

View File

@@ -0,0 +1,174 @@
//////////////////////////////
// The zone control console, fluffed ingame as
// a scanner console for the asteroid belt
//////////////////////////////
#define OUTPOST_Z 5
#define TRANSIT_Z 2
#define BELT_Z 7
/obj/machinery/computer/roguezones
name = "asteroid belt scanning computer"
desc = "Used to monitor the nearby asteroid belt and detect new areas."
icon_keyboard = "tech_key"
icon_screen = "request"
light_color = "#315ab4"
use_power = 1
idle_power_usage = 250
active_power_usage = 500
circuit = /obj/item/weapon/circuitboard/roguezones
var/debug = 0
var/debug_scans = 0
var/scanning = 0
var/legacy_zone = 0 //Disable scanning and whatnot.
var/obj/machinery/computer/shuttle_control/belter/shuttle_control
/obj/machinery/computer/roguezones/initialize()
..()
shuttle_control = locate(/obj/machinery/computer/shuttle_control/belter)
/obj/machinery/computer/roguezones/attack_ai(mob/user as mob)
return attack_hand(user)
/obj/machinery/computer/roguezones/attack_hand(mob/user as mob)
add_fingerprint(user)
if(stat & (BROKEN|NOPOWER))
return
user.set_machine(src)
ui_interact(user)
/obj/machinery/computer/roguezones/ui_interact(mob/user, ui_key = "main", var/datum/nanoui/ui = null, var/force_open = 1)
user.set_machine(src)
var/chargePercent = min(100, ((((world.time - rm_controller.last_scan) / 10) / 60) / rm_controller.scan_wait) * 100)
var/curZoneOccupied = rm_controller.current_zone ? rm_controller.current_zone.is_occupied() : 0
var/list/data = list()
data["timeout_percent"] = chargePercent
data["diffstep"] = rm_controller.diffstep
data["difficulty"] = rm_controller.diffstep_strs[rm_controller.diffstep]
data["occupied"] = curZoneOccupied
data["scanning"] = scanning
data["updated"] = world.time - rm_controller.last_scan < 200 //Very recently scanned (20 seconds)
data["debug"] = debug
if(!shuttle_control)
data["shuttle_location"] = "Unknown"
data["shuttle_at_station"] = 0
else if(shuttle_control.z == OUTPOST_Z)
data["shuttle_location"] = "Landed"
data["shuttle_at_station"] = 1
else if(shuttle_control.z == TRANSIT_Z)
data["shuttle_location"] = "In-transit"
data["shuttle_at_station"] = 0
else if(shuttle_control.z == BELT_Z)
data["shuttle_location"] = "Belt"
data["shuttle_at_station"] = 0
var/can_scan = 0
if(chargePercent >= 100) //Keep having weird problems with these in one 'if' statement
if(shuttle_control && shuttle_control.z == OUTPOST_Z) //Even though I put them all in parens to avoid OoO problems...
if(!curZoneOccupied) //Not sure why.
if(!scanning)
can_scan = 1
if(debug_scans) can_scan = 1
data["scan_ready"] = can_scan
// Permit emergency recall of the shuttle if its stranded in a zone with just dead people.
data["can_recall_shuttle"] = (shuttle_control && shuttle_control.z == BELT_Z && !curZoneOccupied)
ui = nanomanager.try_update_ui(user, src, ui_key, ui, data, force_open)
if (!ui)
ui = new(user, src, ui_key, "zone_console.tmpl", src.name, 600, 400)
ui.set_initial_data(data)
ui.open()
ui.set_auto_update(5)
/obj/machinery/computer/roguezones/Topic(href, href_list)
if(..())
return 1
usr.set_machine(src)
if (href_list["action"])
switch(href_list["action"])
if ("scan_for_new")
scan_for_new_zone()
if ("point_at_old")
point_at_old_zone()
if ("recall_shuttle")
failsafe_shuttle_recall()
src.add_fingerprint(usr)
nanomanager.update_uis(src)
/obj/machinery/computer/roguezones/proc/scan_for_new_zone()
if(scanning) return
//Set some kinda scanning var to pause UI input on console
rm_controller.last_scan = world.time
scanning = 1
sleep(60)
//Break the shuttle temporarily.
shuttle_control.shuttle_tag = null
//Build and get a new zone.
var/datum/rogue/zonemaster/ZM_target = rm_controller.prepare_new_zone()
//Update shuttle destination.
var/datum/shuttle/ferry/S = shuttle_controller.shuttles["Belter"]
S.area_offsite = ZM_target.myshuttle
//Re-enable shuttle.
shuttle_control.shuttle_tag = "Belter"
//Update rm_previous
rm_controller.previous_zone = rm_controller.current_zone
//Update rm_current
rm_controller.current_zone = ZM_target
//Unset scanning
scanning = 0
return
/obj/machinery/computer/roguezones/proc/point_at_old_zone()
return
/obj/machinery/computer/roguezones/proc/failsafe_shuttle_recall()
if(!shuttle_control)
return // Shuttle computer has been destroyed
if (shuttle_control.z != BELT_Z)
return // Usable only when shuttle is away
if(rm_controller.current_zone && rm_controller.current_zone.is_occupied())
return // Not usable if shuttle is in occupied zone
// Okay do it
var/datum/shuttle/ferry/S = shuttle_controller.shuttles["Belter"]
S.launch(usr)
/obj/item/weapon/circuitboard/roguezones
name = T_BOARD("asteroid belt scanning computer")
build_path = /obj/machinery/computer/roguezones
origin_tech = list(TECH_DATA = 3, TECH_BLUESPACE = 1)
// Undefine our constants to not pollute namespace
#undef OUTPOST_Z
#undef TRANSIT_Z
#undef BELT_Z
/obj/item/weapon/paper/rogueminer
name = "R-38 Scanner Console Guide"
info = {"<h4>Getting Started</h4>
Congratulations, your station has purchased the R-38 industrial asteroid belt scanner!<br>
Using the R-38 is almost as simple as brain surgery! Simply press the scan button to scan for a new mineral-rich asteroid belt location!<br>
<b>That's all there is to it!</b><br>
Notice, scan may cause extreme brain damage to those present in asteroid belt, so scanning will be disabled in that case.<br>
Existing minerals and living creatures interfere with the scans, so the more minerals extracted and creatures 'removed'/made-not-living in the belt, the more accurate future scans will be.<br>
<h4>Traveling to the belt</h4>
When a new zone has been scanned, your station's shuttle destination will be updated to direct it to the newly discovered area automatically.<br>
You can then travel to the new area to mine in that location.<br>
<br>
<font size=1>This technology produced under license from Thinktronic Systems, LTD.</font>"}

View File

@@ -0,0 +1,418 @@
//////////////////////////////
// The zonemaster object, spawned to track the zone and
// clean/populate the zone with asteroids and loot
//////////////////////////////
/datum/rogue/zonemaster
//our area
var/area/asteroid/rogue/myarea
var/area/shuttle/belter/myshuttle
//world.time
var/prepared_at = 0
//accepting shuttles
var/ready = 0
//completely empty
var/clean = 1
//scored or not
var/scored = 0
//for scoring
var/list/mineral_rocks = list()
var/list/spawned_mobs = list()
var/original_mobs = 0
//in-use spawns from the area
var/obj/asteroid_spawner/list/rockspawns = list()
var/obj/rogue_mobspawner/list/mobspawns = list()
/datum/rogue/zonemaster/New(var/area/A)
ASSERT(A)
myarea = A
myshuttle = locate(myarea.shuttle_area)
spawn(10) //This is called from controller New() and freaks out if this calls back too fast.
rm_controller.mark_clean(src)
///////////////////////////////
///// Utility Procs ///////////
///////////////////////////////
/datum/rogue/zonemaster/proc/is_occupied()
var/humans = 0
for(var/mob/living/carbon/human/H in human_mob_list)
if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it.
continue
var/area/A = get_area(H)
if((A == myarea) || (A == myshuttle)) //The loc of a turf is the area it is in.
humans++
return humans
///////////////////////////////
///// Asteroid Generation /////
///////////////////////////////
/datum/rogue/zonemaster/proc/generate_asteroid(var/core_min = 2, var/core_max = 5)
//Chance for a predefined structure instead, more common later
if(prob(rm_controller.diffstep*4))
rm_controller.dbg("ZM(ga): Fell into prefab asteroid chance.")
var/prefab = pick(rm_controller.prefabs["tier[rm_controller.diffstep]"])
rm_controller.dbg("ZM(ga): Picked [prefab] as the prefab.")
var/prefabinst = new prefab(null)
return prefabinst
var/datum/rogue/asteroid/A = new(rand(core_min,core_max))
rm_controller.dbg("ZM(ga): New asteroid with C:[A.coresize], TW:[A.type_wall].")
//Add the core to the asteroid's map
rm_controller.dbg("ZM(ga): Starting core generation for [A.coresize] size core..")
for(var/x = 1; x <= A.coresize, x++)
for(var/y = 1; y <= A.coresize, y++)
rm_controller.dbg("ZM(ga): Doing core-relative [x],[y] at [A.coresize+x],[A.coresize+y], [A.type_wall].")
A.spot_add(A.coresize+x, A.coresize+y, A.type_wall)
var/max_armlen = A.coresize - 1 //Can tweak to change appearance.
//Add the arms to the asteroid's map
//Vertical arms
for(var/x = A.coresize+1, x <= A.coresize*2, x++) //Start at leftmost side of core, work towards higher X.
rm_controller.dbg("ZM(ga): Vert arms. My current column is x:[x].")
var/B_arm = rand(0,max_armlen)
var/T_arm = rand(0,max_armlen)
rm_controller.dbg("ZM(ga): B/T. Going to make B:[B_arm], T:[T_arm] for x:[x].")
//Bottom arm
for(var/y = A.coresize, y > A.coresize-B_arm, y--) //Start at bottom edge of the core, work towards lower Y.
A.spot_add(x,y,A.type_wall)
//Top arm
for(var/y = (A.coresize*2)+1, y < ((A.coresize*2)+1)+T_arm, y++) //Start at top edge of the core, work towards higher Y.
A.spot_add(x,y,A.type_wall)
//Horizontal arms
for(var/y = A.coresize+1, y <= A.coresize*2, y++) //Start at lower side of core, work towards higher Y.
rm_controller.dbg("ZM(ga): Horiz arms. My current row is y:[y].")
var/R_arm = rand(0,max_armlen)
var/L_arm = rand(0,max_armlen)
rm_controller.dbg("ZM(ga): R/L. Going to make R:[R_arm], L:[L_arm] for y:[y].")
//Right arm
for(var/x = (A.coresize*2)+1, x <= ((A.coresize*2)+1)+R_arm, x++) //Start at right edge of core, work towards higher X.
A.spot_add(x,y,A.type_wall)
//Left arm
for(var/x = A.coresize, x > A.coresize-L_arm, x--) //Start at left edge of core, work towards lower X.
A.spot_add(x,y,A.type_wall)
//Diagonals
// hao do
rm_controller.dbg("ZM(ga): Asteroid generation done.")
return A
/datum/rogue/zonemaster/proc/place_asteroid(var/datum/rogue/asteroid/A,var/obj/asteroid_spawner/SP)
ASSERT(SP && A)
rm_controller.dbg("ZM(pa): Placing at point [SP.x],[SP.y],[SP.z].")
SP.myasteroid = A
//Bottom-left corner of our bounding box
var/BLx = SP.x - (A.width/2)
var/BLy = SP.y - (A.width/2)
rm_controller.dbg("ZM(pa): BLx is [BLx], BLy is [BLy].")
rm_controller.dbg("ZM(pa): The asteroid has [A.map.len] X-lists.")
for(var/Ix=1, Ix <= A.map.len, Ix++)
var/list/curr_x = A.map[Ix]
rm_controller.dbg("ZM(pa): Now doing X:[Ix] which has [curr_x.len] Y-lists.")
for(var/Iy=1, Iy <= curr_x.len, Iy++)
var/list/curr_y = curr_x[Iy]
rm_controller.dbg("ZM(pa): Now doing Y:[Iy] which has [curr_y.len] items.")
var/world_x = BLx+Ix
var/world_y = BLy+Iy
var/world_z = SP.z
var/spot = locate(world_x,world_y,world_z)
for(var/T in curr_y)
rm_controller.dbg("ZM(pa): Doing entry [T] in Y-list [Iy].")
if(ispath(T,/turf)) //We're spawning a turf
rm_controller.dbg("ZM(pa): Turf-generate mode.")
//Make sure we locate()'d a turf and not something else
if(!isturf(spot))
spot = get_turf(spot)
var/turf/P = spot
rm_controller.dbg("ZM(pa): Replacing [P.type] with [T].")
var/turf/newturf = P.ChangeTurf(T)
switch(newturf.type)
if(/turf/simulated/mineral)
place_resources(newturf)
newturf.update_icon(1)
else //Anything not a turf
rm_controller.dbg("ZM(pa): Creating [T].")
new T(spot)
/datum/rogue/zonemaster/proc/place_resources(var/turf/simulated/mineral/M)
#define XENOARCH_SPAWN_CHANCE 0.3
#define DIGSITESIZE_LOWER 4
#define DIGSITESIZE_UPPER 12
#define ARTIFACTSPAWNNUM_LOWER 6
#define ARTIFACTSPAWNNUM_UPPER 12 //Replace with difficulty-based ones.
if(!M.mineral && prob(rm_controller.diffstep_nums[rm_controller.diffstep]/10)) //Difficulty translates directly into ore chance
rm_controller.dbg("ZM(par): Adding mineral to [M.x],[M.y].")
M.make_ore(rm_controller.diffstep >= 3 ? 1 : 0)
mineral_rocks += M
//If above difficulty threshold make rare ore instead (M.make_ore(1))
//Increase with difficulty etc
if(!M.density)
return
if(isnull(M.geologic_data))
M.geologic_data = new /datum/geosample(M)
if(!prob(XENOARCH_SPAWN_CHANCE))
return
var/farEnough = 1
for(var/A in master_controller.digsite_spawning_turfs)
var/turf/T = A
if(T in range(5, M))
farEnough = 0
break
if(!farEnough)
return
master_controller.digsite_spawning_turfs.Add(M)
var/digsite = get_random_digsite_type()
var/target_digsite_size = rand(DIGSITESIZE_LOWER, DIGSITESIZE_UPPER)
var/list/processed_turfs = list()
var/list/turfs_to_process = list(M)
var/list/viable_adjacent_turfs = list()
if(target_digsite_size > 1)
for(var/turf/simulated/mineral/T in orange(2, M))
if(!T.density)
continue
if(T.finds)
continue
if(T in processed_turfs)
continue
viable_adjacent_turfs.Add(T)
target_digsite_size = min(target_digsite_size, viable_adjacent_turfs.len)
for(var/i = 1 to target_digsite_size)
turfs_to_process += pick_n_take(viable_adjacent_turfs)
while(turfs_to_process.len)
var/turf/simulated/mineral/archeo_turf = pop(turfs_to_process)
rm_controller.dbg("ZM(par): Adding archeo find to [M.x],[M.y].")
processed_turfs.Add(archeo_turf)
if(isnull(archeo_turf.finds))
archeo_turf.finds = list()
if(prob(50))
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 190)))
else if(prob(75))
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 90)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(110, 190)))
else
archeo_turf.finds.Add(new /datum/find(digsite, rand(10, 50)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(60, 140)))
archeo_turf.finds.Add(new /datum/find(digsite, rand(150, 190)))
//sometimes a find will be close enough to the surface to show
var/datum/find/F = archeo_turf.finds[1]
if(F.excavation_required <= F.view_range)
archeo_turf.archaeo_overlay = "overlay_archaeo[rand(1,3)]"
archeo_turf.update_icon()
//have a chance for an artifact to spawn here, but not in animal or plant digsites
if(isnull(M.artifact_find) && digsite != DIGSITE_GARDEN && digsite != DIGSITE_ANIMAL)
master_controller.artifact_spawning_turfs.Add(archeo_turf)
//create artifact machinery
var/num_artifacts_spawn = rand(ARTIFACTSPAWNNUM_LOWER, ARTIFACTSPAWNNUM_UPPER)
while(master_controller.artifact_spawning_turfs.len > num_artifacts_spawn)
pick_n_take(master_controller.artifact_spawning_turfs)
var/list/artifacts_spawnturf_temp = master_controller.artifact_spawning_turfs.Copy()
while(artifacts_spawnturf_temp.len > 0)
var/turf/simulated/mineral/artifact_turf = pop(artifacts_spawnturf_temp)
artifact_turf.artifact_find = new()
#undef XENOARCH_SPAWN_CHANCE
#undef DIGSITESIZE_LOWER
#undef DIGSITESIZE_UPPER
#undef ARTIFACTSPAWNNUM_LOWER
#undef ARTIFACTSPAWNNUM_UPPER //Replace with difficulty-based ones.
///////////////////////////////
///// Zone Population /////////
///////////////////////////////
//Overall 'prepare' proc (marks as ready)
/datum/rogue/zonemaster/proc/prepare_zone(var/delay = 0)
rm_controller.unmark_clean(src)
rm_controller.dbg("ZM(p): Preparing zone with difficulty level [rm_controller.diffstep].")
rm_controller.dbg("ZM(p): Randomizing spawns.")
randomize_spawns()
rm_controller.dbg("ZM(p): [rockspawns.len] picked.")
for(var/obj/asteroid_spawner/SP in rockspawns)
rm_controller.dbg("ZM(p): Creating asteroid for [SP.x],[SP.y],[SP.z].")
var/datum/rogue/asteroid/A = generate_asteroid()
rm_controller.dbg("ZM(p): Placing asteroid.")
place_asteroid(A,SP)
if(delay)
sleep(delay)
for(var/obj/rogue_mobspawner/SP in mobspawns)
rm_controller.dbg("ZM(p): Spawning mob at [SP.x],[SP.y],[SP.z].")
//Make sure we can spawn a spacemob here
if(!istype(get_turf(SP),/turf/space))
rm_controller.dbg("ZM(p): Turf blocking mob spawn at [SP.x],[SP.y],[SP.z].")
mobspawns -= SP
for(var/obj/rogue_mobspawner/NS in myarea.mob_spawns)
if(NS in mobspawns)
continue
if(istype(get_turf(NS),/turf/space))
SP = NS
break
if(SP)
rm_controller.dbg("ZM(p): Got a mob spawnpoint, so picking a type.")
var/mobchoice = pick(rm_controller.mobs["tier[rm_controller.diffstep]"])
rm_controller.dbg("ZM(p): Picked [mobchoice] to spawn.")
var/newmob = new mobchoice(get_turf(SP))
spawned_mobs += newmob
if(delay)
sleep(delay)
rm_controller.dbg("ZM(p): Zone generation done.")
world.log << "RM(stats): PREP [myarea] at [world.time] with [spawned_mobs.len] mobs, [mineral_rocks.len] minrocks, total of [rockspawns.len] rockspawns, [mobspawns.len] mobspawns." //DEBUG code for playtest stats gathering.
prepared_at = world.time
rm_controller.mark_ready(src)
return myarea
//Randomize the landmarks that are enabled
/datum/rogue/zonemaster/proc/randomize_spawns(var/chance = 50)
rm_controller.dbg("ZM(rs): Previously [rockspawns.len] rockspawns.")
rockspawns.Cut()
rm_controller.dbg("ZM(rs): Now [rockspawns.len] rockspawns.")
for(var/obj/asteroid_spawner/SP in myarea.asteroid_spawns)
if(prob(chance))
rockspawns += SP
rm_controller.dbg("ZM(rs): Picked [rockspawns.len] new rockspawns with [chance]% chance.")
rm_controller.dbg("ZM(rs): Previously [mobspawns.len] mobspawns.")
mobspawns.Cut()
rm_controller.dbg("ZM(rs): Now [mobspawns.len] mobspawns.")
for(var/obj/rogue_mobspawner/SP in myarea.mob_spawns)
if(prob(rm_controller.diffstep_nums[rm_controller.diffstep]/10))
mobspawns += SP
original_mobs++
rm_controller.dbg("ZM(rs): Picked [mobspawns.len] new mobspawns with [chance]% chance.")
return myarea
///////////////////////////////
///// Zone Cleaning ///////////
///////////////////////////////
/datum/rogue/zonemaster/proc/score_zone(var/bonus = 10)
rm_controller.dbg("ZM(sz): Scoring zone with area [myarea].")
scored = 1
var/tally = bonus
//Ore-bearing rocks that were mined
for(var/turf/T in mineral_rocks)
var/has_minerals = 0
for(var/atom/I in T.contents)
if(istype(I,/obj/effect/mineral))
has_minerals++
break
if(has_minerals == 0)
tally += RM_DIFF_VALUE_ORE
mineral_rocks.Cut() //For good measure, to prevent rescoring.
for(var/I = 1, I <= spawned_mobs.len, I++)
if(isnull(spawned_mobs[I]))
tally += RM_DIFF_VALUE_MOB //Mobs so annihilated they were deleted
rm_controller.dbg("ZM(sz): Scoring one mob annihilated.")
if(istype(spawned_mobs[I],/mob))
var/mob/M = spawned_mobs[I]
if(M.stat > 0) //Knocked out or dead or anything other than normal
tally += RM_DIFF_VALUE_MOB
rm_controller.dbg("ZM(sz): Scoring one mob dead.")
spawned_mobs.Cut()
original_mobs = 0
rm_controller.adjust_difficulty(tally)
rm_controller.dbg("ZM(sz): Finished scoring and adjusted by [tally].")
world.log << "RM(stats): SCORE [myarea] for [tally]." //DEBUG code for playtest stats gathering.
return tally
//Overall 'destroy' proc (marks as unready)
/datum/rogue/zonemaster/proc/clean_zone(var/delay = 1)
rm_controller.dbg("ZM(cz): Cleaning zone with area [myarea].")
world.log << "RM(stats): CLEAN start [myarea] at [world.time] prepared at [prepared_at]." //DEBUG code for playtest stats gathering.
rm_controller.unmark_ready(src)
//Cut these lists so qdel can dereference the things properly
mineral_rocks.Cut()
spawned_mobs.Cut()
rockspawns.Cut()
mobspawns.Cut()
var/ignored = list(
/obj/asteroid_spawner,
/obj/rogue_mobspawner,
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onleft,
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onright,
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/ontop,
/obj/effect/step_trigger/teleporter/random/rogue/fourbyfour/onbottom)
for(var/atom/I in myarea.contents)
if(I.type == /turf/space)
I.overlays.Cut()
continue
else if(I.type in ignored)
continue
qdel(I)
sleep(delay)
//A deletion so nice that I give it twice
for(var/atom/I in myarea.contents)
if(I.type in ignored)
continue
qdel(I)
sleep(delay)
//Clean up vars
scored = 0
original_mobs = 0
prepared_at = 0
world.log << "RM(stats): CLEAN done [myarea] at [world.time]." //DEBUG code for playtest stats gathering.
rm_controller.dbg("ZM(cz): Finished cleaning up zone area [myarea].")
rm_controller.mark_clean(src)
return myarea
///////////////////////////////
///// Mysterious Mystery //////
///////////////////////////////
//Throw a meteor at a player in the zone

View File

@@ -1,4 +0,0 @@
/obj/machinery/computer/shuttle_control/multi/admin
name = "centcom shuttle control console"
req_access = list(access_cent_general)
shuttle_tag = "Administration"

View File

@@ -1,4 +0,0 @@
/obj/machinery/computer/shuttle_control/multi/awaymission
name = "exploration shuttle control console"
req_access = list(access_gateway)
shuttle_tag = "AwayMission"

View File

@@ -1,8 +0,0 @@
/obj/machinery/computer/shuttle_control/mining
name = "mining elevator control console"
/obj/machinery/computer/shuttle_control/engineering
name = "engineering elevator control console"
/obj/machinery/computer/shuttle_control/research
name = "research elevator control console"

View File

@@ -0,0 +1,23 @@
/obj/machinery/computer/shuttle_control/multi/admin
name = "centcom shuttle control console"
req_access = list(access_cent_general)
shuttle_tag = "Administration"
/obj/machinery/computer/shuttle_control/multi/awaymission
name = "exploration shuttle control console"
req_access = list(access_gateway)
shuttle_tag = "AwayMission"
/obj/machinery/computer/shuttle_control/belter
name = "belter control console"
req_access = list(access_mining)
// shuttle_tag = "Belter" //The scanning console needs to enable/disable this at will.
/obj/machinery/computer/shuttle_control/mining
name = "mining elevator control console"
/obj/machinery/computer/shuttle_control/engineering
name = "engineering elevator control console"
/obj/machinery/computer/shuttle_control/research
name = "research elevator control console"

View File

@@ -1,7 +1,7 @@
//This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here. //This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here.
//I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu //I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu
/obj/vehicle/train/securiengine /obj/vehicle/train/security/engine
name = "Security Cart" name = "Security Cart"
desc = "A ridable electric car designed for pulling trolleys as well as personal transport." desc = "A ridable electric car designed for pulling trolleys as well as personal transport."
icon = 'icons/obj/vehicles_vr.dmi' icon = 'icons/obj/vehicles_vr.dmi'
@@ -23,17 +23,17 @@
var/car_limit = 0 //how many cars an engine can pull before performance degrades. This should be 0 to prevent trailers from unhitching. var/car_limit = 0 //how many cars an engine can pull before performance degrades. This should be 0 to prevent trailers from unhitching.
active_engines = 1 active_engines = 1
var/obj/item/weapon/key/securitrain/key var/obj/item/weapon/key/security/key
var/siren = 0 //This is for eventually getting the siren sprite to work. var/siren = 0 //This is for eventually getting the siren sprite to work.
/obj/item/weapon/key/securitrain /obj/item/weapon/key/security
name = "The Security Cart key" name = "The Security Cart key"
desc = "The Security Cart Key used to start it." desc = "The Security Cart Key used to start it."
icon = 'icons/obj/vehicles_vr.dmi' icon = 'icons/obj/vehicles_vr.dmi'
icon_state = "securikey" icon_state = "securikey"
w_class = ITEMSIZE_TINY w_class = ITEMSIZE_TINY
/obj/vehicle/train/securitrolley /obj/vehicle/train/security/trolley
name = "Train trolley" name = "Train trolley"
desc = "A trolly designed to transport security personnel or prisoners." desc = "A trolly designed to transport security personnel or prisoners."
icon = 'icons/obj/vehicles_vr.dmi' icon = 'icons/obj/vehicles_vr.dmi'
@@ -47,7 +47,7 @@
load_offset_y = 4 load_offset_y = 4
mob_offset_y = 8 mob_offset_y = 8
/obj/vehicle/train/securitrolley/cargo /obj/vehicle/train/security/trolley/cargo
name = "Train trolley" name = "Train trolley"
desc = "A trolley designed to transport security equipment to a scene." desc = "A trolley designed to transport security equipment to a scene."
icon = 'icons/obj/vehicles_vr.dmi' icon = 'icons/obj/vehicles_vr.dmi'
@@ -58,15 +58,15 @@
//------------------------------------------- //-------------------------------------------
// Standard procs // Standard procs
//------------------------------------------- //-------------------------------------------
/obj/vehicle/train/securiengine/New() /obj/vehicle/train/security/engine/New()
..() ..()
cell = new /obj/item/weapon/cell/high(src) cell = new /obj/item/weapon/cell/high(src)
key = new(src) key = new(src)
var/image/I = new(icon = 'icons/obj/vehicles_vr.dmi', icon_state = null, layer = src.layer + 0.2) //over mobs var/image/I = new(icon = 'icons/obj/vehicles.dmi', icon_state = "cargo_engine_overlay", layer = src.layer + 0.2) //over mobs
overlays += I overlays += I
turn_off() //so engine verbs are correctly set turn_off() //so engine verbs are correctly set
/obj/vehicle/train/securiengine/Move(var/turf/destination) /obj/vehicle/train/security/engine/Move(var/turf/destination)
if(on && cell.charge < charge_use) if(on && cell.charge < charge_use)
turn_off() turn_off()
update_stats() update_stats()
@@ -82,48 +82,48 @@
return ..() return ..()
/obj/vehicle/train/securitrolley/attackby(obj/item/weapon/W as obj, mob/user as mob) /obj/vehicle/train/security/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(open && istype(W, /obj/item/weapon/wirecutters)) if(open && istype(W, /obj/item/weapon/wirecutters))
passenger_allowed = !passenger_allowed passenger_allowed = !passenger_allowed
user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>") user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>")
else else
..() ..()
/obj/vehicle/train/securiengine/attackby(obj/item/weapon/W as obj, mob/user as mob) /obj/vehicle/train/security/engine/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/key/securitrain)) if(istype(W, /obj/item/weapon/key/cargo_train))
if(!key) if(!key)
user.drop_item() user.drop_item()
W.forceMove(src) W.forceMove(src)
key = W key = W
verbs += /obj/vehicle/train/securiengine/verb/remove_key verbs += /obj/vehicle/train/security/engine/verb/remove_key
return return
..() ..()
//cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead //cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead
/obj/vehicle/train/securitrolley/bullet_act(var/obj/item/projectile/Proj) /obj/vehicle/train/security/bullet_act(var/obj/item/projectile/Proj)
if(buckled_mob && prob(70)) if(buckled_mob && prob(70))
buckled_mob.bullet_act(Proj) buckled_mob.bullet_act(Proj)
return return
..() ..()
/obj/vehicle/train/securitrolley/update_icon() /obj/vehicle/train/security/update_icon()
if(open) if(open)
icon_state = initial(icon_state) + "_open" icon_state = initial(icon_state) + "_open"
else else
icon_state = initial(icon_state) icon_state = initial(icon_state)
/obj/vehicle/train/securitrolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) /obj/vehicle/train/security/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
return return
/obj/vehicle/train/securiengine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H) /obj/vehicle/train/security/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
..() ..()
update_stats() update_stats()
/obj/vehicle/train/securiengine/remove_cell(var/mob/living/carbon/human/H) /obj/vehicle/train/security/engine/remove_cell(var/mob/living/carbon/human/H)
..() ..()
update_stats() update_stats()
/obj/vehicle/train/securiengine/Bump(atom/Obstacle) /obj/vehicle/train/security/engine/Bump(atom/Obstacle)
var/obj/machinery/door/D = Obstacle var/obj/machinery/door/D = Obstacle
var/mob/living/carbon/human/H = load var/mob/living/carbon/human/H = load
if(istype(D) && istype(H)) if(istype(D) && istype(H))
@@ -131,7 +131,7 @@
..() ..()
/obj/vehicle/train/securitrolley/Bump(atom/Obstacle) /obj/vehicle/train/security/trolley/Bump(atom/Obstacle)
if(!lead) if(!lead)
return //so people can't knock others over by pushing a trolley around return //so people can't knock others over by pushing a trolley around
..() ..()
@@ -139,44 +139,44 @@
//------------------------------------------- //-------------------------------------------
// Train procs // Train procs
//------------------------------------------- //-------------------------------------------
/obj/vehicle/train/securiengine/turn_on() /obj/vehicle/train/security/engine/turn_on()
if(!key) if(!key)
return return
else else
..() ..()
update_stats() update_stats()
verbs -= /obj/vehicle/train/securiengine/verb/stop_engine verbs -= /obj/vehicle/train/security/engine/verb/stop_engine
verbs -= /obj/vehicle/train/securiengine/verb/start_engine verbs -= /obj/vehicle/train/security/engine/verb/start_engine
if(on) if(on)
verbs += /obj/vehicle/train/securiengine/verb/stop_engine verbs += /obj/vehicle/train/security/engine/verb/stop_engine
else else
verbs += /obj/vehicle/train/securiengine/verb/start_engine verbs += /obj/vehicle/train/security/engine/verb/start_engine
/obj/vehicle/train/securiengine/turn_off() /obj/vehicle/train/security/engine/turn_off()
..() ..()
verbs -= /obj/vehicle/train/securiengine/verb/stop_engine verbs -= /obj/vehicle/train/security/engine/verb/stop_engine
verbs -= /obj/vehicle/train/securiengine/verb/start_engine verbs -= /obj/vehicle/train/security/engine/verb/start_engine
if(!on) if(!on)
verbs += /obj/vehicle/train/securiengine/verb/start_engine verbs += /obj/vehicle/train/security/engine/verb/start_engine
else else
verbs += /obj/vehicle/train/securiengine/verb/stop_engine verbs += /obj/vehicle/train/security/engine/verb/stop_engine
/obj/vehicle/train/securitrolley/RunOver(var/mob/living/carbon/human/H) /obj/vehicle/train/security/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM) var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)
H.apply_effects(5, 5) H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++) for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts)) H.apply_damage(rand(1,5), BRUTE, pick(parts))
/obj/vehicle/train/securitrolley/RunOver(var/mob/living/carbon/human/H) /obj/vehicle/train/security/trolley/RunOver(var/mob/living/carbon/human/H)
..() ..()
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>") attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
/obj/vehicle/train/securiengine/RunOver(var/mob/living/carbon/human/H) /obj/vehicle/train/security/engine/RunOver(var/mob/living/carbon/human/H)
..() ..()
if(is_train_head() && istype(load, /mob/living/carbon/human)) if(is_train_head() && istype(load, /mob/living/carbon/human))
@@ -192,7 +192,7 @@
//------------------------------------------- //-------------------------------------------
// Interaction procs // Interaction procs
//------------------------------------------- //-------------------------------------------
/obj/vehicle/train/securiengine/relaymove(mob/user, direction) /obj/vehicle/train/security/engine/relaymove(mob/user, direction)
if(user != load) if(user != load)
return 0 return 0
@@ -205,8 +205,7 @@
else else
return ..() return ..()
/obj/vehicle/train/security/engine/examine(mob/user)
/obj/vehicle/train/securiengine/examine(mob/user)
if(!..(user, 1)) if(!..(user, 1))
return return
@@ -216,7 +215,7 @@
user << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition." user << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
user << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%" user << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%"
/obj/vehicle/train/securiengine/verb/start_engine() /obj/vehicle/train/security/engine/verb/start_engine()
set name = "Start engine" set name = "Start engine"
set category = "Vehicle" set category = "Vehicle"
set src in view(0) set src in view(0)
@@ -237,7 +236,7 @@
else else
usr << "[src]'s engine won't start." usr << "[src]'s engine won't start."
/obj/vehicle/train/securiengine/verb/stop_engine() /obj/vehicle/train/security/engine/verb/stop_engine()
set name = "Stop engine" set name = "Stop engine"
set category = "Vehicle" set category = "Vehicle"
set src in view(0) set src in view(0)
@@ -253,7 +252,7 @@
if (!on) if (!on)
usr << "You stop [src]'s engine." usr << "You stop [src]'s engine."
/obj/vehicle/train/securiengine/verb/remove_key() /obj/vehicle/train/security/engine/verb/remove_key()
set name = "Remove key" set name = "Remove key"
set category = "Vehicle" set category = "Vehicle"
set src in view(0) set src in view(0)
@@ -272,12 +271,12 @@
usr.put_in_hands(key) usr.put_in_hands(key)
key = null key = null
verbs -= /obj/vehicle/train/securiengine/verb/remove_key verbs -= /obj/vehicle/train/security/engine/verb/remove_key
//------------------------------------------- //-------------------------------------------
// Loading/unloading procs // Loading/unloading procs
//------------------------------------------- //-------------------------------------------
/obj/vehicle/train/securitrolley/load(var/atom/movable/C) /obj/vehicle/train/security/trolley/load(var/atom/movable/C)
if(ismob(C) && !passenger_allowed) if(ismob(C) && !passenger_allowed)
return 0 return 0
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human)) if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human))
@@ -293,7 +292,7 @@
if(load) if(load)
return 1 return 1
/obj/vehicle/train/securiengine/load(var/atom/movable/C) /obj/vehicle/train/security/engine/load(var/atom/movable/C)
if(!istype(C, /mob/living/carbon/human)) if(!istype(C, /mob/living/carbon/human))
return 0 return 0
@@ -303,7 +302,7 @@
//This prevents the object from being interacted with until it has //This prevents the object from being interacted with until it has
// been unloaded. A dummy object is loaded instead so the loading // been unloaded. A dummy object is loaded instead so the loading
// code knows to handle it correctly. // code knows to handle it correctly.
/obj/vehicle/train/securitrolley/proc/load_object(var/atom/movable/C) /obj/vehicle/train/security/trolley/proc/load_object(var/atom/movable/C)
if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly. if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly.
return 0 return 0
if(load || C.anchored) if(load || C.anchored)
@@ -329,7 +328,7 @@
C.pixel_y = initial(C.pixel_y) C.pixel_y = initial(C.pixel_y)
C.layer = initial(C.layer) C.layer = initial(C.layer)
/obj/vehicle/train/securitrolley/unload(var/mob/user, var/direction) /obj/vehicle/train/security/trolley/unload(var/mob/user, var/direction)
if(istype(load, /datum/vehicle_dummy_load)) if(istype(load, /datum/vehicle_dummy_load))
var/datum/vehicle_dummy_load/dummy_load = load var/datum/vehicle_dummy_load/dummy_load = load
load = dummy_load.actual_load load = dummy_load.actual_load
@@ -342,15 +341,13 @@
// Latching/unlatching procs // Latching/unlatching procs
//------------------------------------------- //-------------------------------------------
/obj/vehicle/train/securiengine/latch(obj/vehicle/train/T, mob/user) /obj/vehicle/train/security/engine/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T)) if(!istype(T) || !Adjacent(T))
return 0 return 0
//if we are attaching a trolley to an engine we don't care what direction //if we are attaching a trolley to an engine we don't care what direction
// it is in and it should probably be attached with the engine in the lead // it is in and it should probably be attached with the engine in the lead
if(istype(T, /obj/vehicle/train/securitrolley)) if(istype(T, /obj/vehicle/train/security/trolley))
T.attach_to(src, user)
if (istype(T, /obj/vehicle/train/securitrolley/cargo))
T.attach_to(src, user) T.attach_to(src, user)
else else
var/T_dir = get_dir(src, T) //figure out where T is wrt src var/T_dir = get_dir(src, T) //figure out where T is wrt src
@@ -371,7 +368,7 @@
// more engines increases this limit by car_limit per // more engines increases this limit by car_limit per
// engine. // engine.
//------------------------------------------------------- //-------------------------------------------------------
/obj/vehicle/train/securiengine/update_car(var/train_length, var/active_engines) /obj/vehicle/train/security/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length src.train_length = train_length
src.active_engines = active_engines src.active_engines = active_engines
@@ -382,9 +379,9 @@
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines) move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed move_delay += config.run_speed //base reference speed
move_delay *= 1.5 //makes cargo trains 10% slower than running when not overweight move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/securitrolley/update_car(var/train_length, var/active_engines) /obj/vehicle/train/security/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length src.train_length = train_length
src.active_engines = active_engines src.active_engines = active_engines
@@ -392,32 +389,3 @@
anchored = 0 anchored = 0
else else
anchored = 1 anchored = 1
//-----------------------------------------------------
//Update layer stuff
//
//This is supposed to update the layers and put the mob in the correct spot.
//Pls help squirrel get this to work. ;m;
//-----------------------------------------------------
/obj/vehicle/train/securiengine/proc/update_layer()
if(dir == SOUTH)
layer = FLY_LAYER
else
layer = OBJ_LAYER
/obj/vehicle/train/securiengine/proc/update_mob()
if(buckled_mob)
buckled_mob.set_dir(dir)
switch(dir)
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 7
if(WEST)
buckled_mob.pixel_x = 13
buckled_mob.pixel_y = 7
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -13
buckled_mob.pixel_y = 7

View File

@@ -0,0 +1,398 @@
//This is the initial set up for the new carts. Feel free to improve and/or rewrite everything here.
//I don't know what the hell I'm doing right now. Please help. Especially with the update_icons stuff. -Joan Risu
/obj/vehicle/train/rover/engine
name = "NT Humvee"
desc = "The NT version of the UF T-41LV, a Federation recon vehicle used as a personal transport. Can be latched to a trolly to transport equipment. "
icon = 'icons/vore/rover_vr.dmi'
icon_state = "rover"
on = 0
powered = 1
locked = 0
move_delay = 0.5
//Health stuff
health = 100
maxhealth = 100
fire_dam_coeff = 0.6
brute_dam_coeff = 0.5
load_item_visible = 0
load_offset_x = 0
pixel_x = -8
pixel_y = -8
var/car_limit = 0 //how many cars an engine can pull before performance degrades. This should be 0 to prevent trailers from unhitching.
active_engines = 1
var/obj/item/weapon/key/rover/key
var/siren = 0 //This is for eventually getting the siren sprite to work.
/obj/item/weapon/key/rover
name = "The Rover key"
desc = "The Rover key used to start it."
icon = 'icons/obj/vehicles_vr.dmi'
icon_state = "securikey"
w_class = ITEMSIZE_TINY
/obj/vehicle/train/rover/trolley
name = "Train trolley"
desc = "A trolley designed to transport security equipment to a scene."
icon = 'icons/obj/vehicles_vr.dmi'
icon_state = "secitemcarrierbot"
anchored = 0
passenger_allowed = 0
locked = 0
load_item_visible = 0
load_offset_x = 0
load_offset_y = 0
mob_offset_y = 0
//-------------------------------------------
// Standard procs
//-------------------------------------------
/obj/vehicle/train/rover/engine/New()
..()
cell = new /obj/item/weapon/cell/high(src)
key = new(src)
turn_off() //so engine verbs are correctly set
/obj/vehicle/train/rover/engine/Move(var/turf/destination)
if(on && cell.charge < charge_use)
turn_off()
update_stats()
if(load && is_train_head())
load << "The drive motor briefly whines, then drones to a stop."
if(is_train_head() && !on)
return 0
//space check ~no flying space trains sorry
if(on && istype(destination, /turf/space))
return 0
return ..()
/obj/vehicle/train/rover/trolley/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(open && istype(W, /obj/item/weapon/wirecutters))
passenger_allowed = !passenger_allowed
user.visible_message("<span class='notice'>[user] [passenger_allowed ? "cuts" : "mends"] a cable in [src].</span>","<span class='notice'>You [passenger_allowed ? "cut" : "mend"] the load limiter cable.</span>")
else
..()
/obj/vehicle/train/rover/engine/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W, /obj/item/weapon/key/rover))
if(!key)
user.drop_item()
W.forceMove(src)
key = W
verbs += /obj/vehicle/train/rover/engine/verb/remove_key
return
..()
//cargo trains are open topped, so there is a chance the projectile will hit the mob ridding the train instead
/obj/vehicle/train/rover/bullet_act(var/obj/item/projectile/Proj)
if(buckled_mob && prob(70))
buckled_mob.bullet_act(Proj)
return
..()
/obj/vehicle/train/rover/update_icon()
if(open)
icon_state = initial(icon_state) + "_open"
else
icon_state = initial(icon_state)
/obj/vehicle/train/rover/trolley/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
return
/obj/vehicle/train/rover/engine/insert_cell(var/obj/item/weapon/cell/C, var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/rover/engine/remove_cell(var/mob/living/carbon/human/H)
..()
update_stats()
/obj/vehicle/train/rover/engine/Bump(atom/Obstacle)
var/obj/machinery/door/D = Obstacle
var/mob/living/carbon/human/H = load
if(istype(D) && istype(H))
D.Bumped(H) //a little hacky, but hey, it works, and respects access rights
..()
/obj/vehicle/train/rover/trolley/Bump(atom/Obstacle)
if(!lead)
return //so people can't knock others over by pushing a trolley around
..()
//-------------------------------------------
// Train procs
//-------------------------------------------
/obj/vehicle/train/rover/engine/turn_on()
if(!key)
return
else
..()
update_stats()
verbs -= /obj/vehicle/train/rover/engine/verb/stop_engine
verbs -= /obj/vehicle/train/rover/engine/verb/start_engine
if(on)
verbs += /obj/vehicle/train/rover/engine/verb/stop_engine
else
verbs += /obj/vehicle/train/rover/engine/verb/start_engine
/obj/vehicle/train/rover/engine/turn_off()
..()
verbs -= /obj/vehicle/train/rover/engine/verb/stop_engine
verbs -= /obj/vehicle/train/rover/engine/verb/start_engine
if(!on)
verbs += /obj/vehicle/train/rover/engine/verb/start_engine
else
verbs += /obj/vehicle/train/rover/engine/verb/stop_engine
/obj/vehicle/train/rover/RunOver(var/mob/living/carbon/human/H)
var/list/parts = list(BP_HEAD, BP_TORSO, BP_L_LEG, BP_R_LEG, BP_L_ARM, BP_R_ARM)
H.apply_effects(5, 5)
for(var/i = 0, i < rand(1,3), i++)
H.apply_damage(rand(1,5), BRUTE, pick(parts))
/obj/vehicle/train/rover/trolley/RunOver(var/mob/living/carbon/human/H)
..()
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
/obj/vehicle/train/rover/engine/RunOver(var/mob/living/carbon/human/H)
..()
if(is_train_head() && istype(load, /mob/living/carbon/human))
var/mob/living/carbon/human/D = load
D << "\red \b You ran over [H]!"
visible_message("<B>\red \The [src] ran over [H]!</B>")
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey]), driven by [D.name] ([D.ckey])</font>")
msg_admin_attack("[D.name] ([D.ckey]) ran over [H.name] ([H.ckey]). (<A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[src.x];Y=[src.y];Z=[src.z]'>JMP</a>)")
else
attack_log += text("\[[time_stamp()]\] <font color='red'>ran over [H.name] ([H.ckey])</font>")
//-------------------------------------------
// Interaction procs
//-------------------------------------------
/obj/vehicle/train/rover/engine/relaymove(mob/user, direction)
if(user != load)
return 0
if(is_train_head())
if(direction == reverse_direction(dir) && tow)
return 0
if(Move(get_step(src, direction)))
return 1
return 0
else
return ..()
/obj/vehicle/train/rover/engine/examine(mob/user)
if(!..(user, 1))
return
if(!istype(usr, /mob/living/carbon/human))
return
user << "The power light is [on ? "on" : "off"].\nThere are[key ? "" : " no"] keys in the ignition."
user << "The charge meter reads [cell? round(cell.percent(), 0.01) : 0]%"
/obj/vehicle/train/rover/engine/verb/start_engine()
set name = "Start engine"
set category = "Vehicle"
set src in view(0)
if(!istype(usr, /mob/living/carbon/human))
return
if(on)
usr << "The engine is already running."
return
turn_on()
if (on)
usr << "You start [src]'s engine."
else
if(cell.charge < charge_use)
usr << "[src] is out of power."
else
usr << "[src]'s engine won't start."
/obj/vehicle/train/rover/engine/verb/stop_engine()
set name = "Stop engine"
set category = "Vehicle"
set src in view(0)
if(!istype(usr, /mob/living/carbon/human))
return
if(!on)
usr << "The engine is already stopped."
return
turn_off()
if (!on)
usr << "You stop [src]'s engine."
/obj/vehicle/train/rover/engine/verb/remove_key()
set name = "Remove key"
set category = "Vehicle"
set src in view(0)
if(!istype(usr, /mob/living/carbon/human))
return
if(!key || (load && load != usr))
return
if(on)
turn_off()
key.loc = usr.loc
if(!usr.get_active_hand())
usr.put_in_hands(key)
key = null
verbs -= /obj/vehicle/train/rover/engine/verb/remove_key
//-------------------------------------------
// Loading/unloading procs
//-------------------------------------------
/obj/vehicle/train/rover/trolley/load(var/atom/movable/C)
if(ismob(C) && !passenger_allowed)
return 0
if(!istype(C,/obj/machinery) && !istype(C,/obj/structure/closet) && !istype(C,/obj/structure/largecrate) && !istype(C,/obj/structure/reagent_dispensers) && !istype(C,/obj/structure/ore_box) && !istype(C, /mob/living/carbon/human))
return 0
//if there are any items you don't want to be able to interact with, add them to this check
// ~no more shielded, emitter armed death trains
if(istype(C, /obj/machinery))
load_object(C)
else
..()
if(load)
return 1
/obj/vehicle/train/rover/engine/load(var/atom/movable/C)
if(!istype(C, /mob/living/carbon/human))
return 0
if(ismob(C))
buckle_mob(C)
C.alpha = 0
return ..()
/obj/vehicle/train/rover/engine/unload(var/mob/user, var/direction)
var/mob/living/carbon/human/C = load
if(ismob(load))
unbuckle_mob(load)
C.alpha = 255
load = null
//Load the object "inside" the trolley and add an overlay of it.
//This prevents the object from being interacted with until it has
// been unloaded. A dummy object is loaded instead so the loading
// code knows to handle it correctly.
/obj/vehicle/train/rover/trolley/proc/load_object(var/atom/movable/C)
if(!isturf(C.loc)) //To prevent loading things from someone's inventory, which wouldn't get handled properly.
return 0
if(load || C.anchored)
return 0
var/datum/vehicle_dummy_load/dummy_load = new()
load = dummy_load
if(!load)
return
dummy_load.actual_load = C
C.forceMove(src)
if(load_item_visible)
C.pixel_x += load_offset_x
C.pixel_y += load_offset_y
C.layer = layer
overlays += C
//we can set these back now since we have already cloned the icon into the overlay
C.pixel_x = initial(C.pixel_x)
C.pixel_y = initial(C.pixel_y)
C.layer = initial(C.layer)
/obj/vehicle/train/rover/trolley/unload(var/mob/user, var/direction)
if(istype(load, /datum/vehicle_dummy_load))
var/datum/vehicle_dummy_load/dummy_load = load
load = dummy_load.actual_load
dummy_load.actual_load = null
qdel(dummy_load)
overlays.Cut()
..()
//-------------------------------------------
// Latching/unlatching procs
//-------------------------------------------
/obj/vehicle/train/rover/engine/latch(obj/vehicle/train/T, mob/user)
if(!istype(T) || !Adjacent(T))
return 0
//if we are attaching a trolley to an engine we don't care what direction
// it is in and it should probably be attached with the engine in the lead
if(istype(T, /obj/vehicle/train/rover/trolley))
T.attach_to(src, user)
else
var/T_dir = get_dir(src, T) //figure out where T is wrt src
if(dir == T_dir) //if car is ahead
src.attach_to(T, user)
else if(reverse_direction(dir) == T_dir) //else if car is behind
T.attach_to(src, user)
//-------------------------------------------------------
// Stat update procs
//
// Update the trains stats for speed calculations.
// The longer the train, the slower it will go. car_limit
// sets the max number of cars one engine can pull at
// full speed. Adding more cars beyond this will slow the
// train proportionate to the length of the train. Adding
// more engines increases this limit by car_limit per
// engine.
//-------------------------------------------------------
/obj/vehicle/train/rover/engine/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
//Update move delay
if(!is_train_head() || !on)
move_delay = initial(move_delay) //so that engines that have been turned off don't lag behind
else
move_delay = max(0, (-car_limit * active_engines) + train_length - active_engines) //limits base overweight so you cant overspeed trains
move_delay *= (1 / max(1, active_engines)) * 2 //overweight penalty (scaled by the number of engines)
move_delay += config.run_speed //base reference speed
move_delay *= 1.1 //makes cargo trains 10% slower than running when not overweight
/obj/vehicle/train/rover/trolley/update_car(var/train_length, var/active_engines)
src.train_length = train_length
src.active_engines = active_engines
if(!lead && !tow)
anchored = 0
else
anchored = 1

View File

@@ -156,7 +156,10 @@
has_items = list( has_items = list(
/obj/item/weapon/storage/backpack/fluff/aronai, /obj/item/weapon/storage/backpack/fluff/aronai,
/obj/item/weapon/rig/light/hacker/fluff/aronai, /obj/item/weapon/rig/light/hacker/fluff/aronai,
/obj/item/clothing/under/rank/khi/fluff/aronai) /obj/item/clothing/under/rank/khi/fluff/aronai,
/obj/item/fluff/permit/aronai_kadigan,
/obj/item/weapon/gun/projectile/khi/pistol,
/obj/item/ammo_magazine/c45m/flash)
/* /*
Swimsuits, for general use, to avoid arriving to work with your swimsuit. Swimsuits, for general use, to avoid arriving to work with your swimsuit.

View File

@@ -533,6 +533,8 @@
icon_override = 'icons/vore/custom_clothes_vr.dmi' icon_override = 'icons/vore/custom_clothes_vr.dmi'
item_state = "scree-helm_mob" item_state = "scree-helm_mob"
item_state_slots = list(slot_r_hand_str = "engspace_helmet", slot_l_hand_str = "engspace_helmet")
light_overlay = "helmet_light_dual" light_overlay = "helmet_light_dual"
species_restricted = null species_restricted = null
@@ -556,6 +558,8 @@
icon_override = 'icons/vore/custom_clothes_vr.dmi' icon_override = 'icons/vore/custom_clothes_vr.dmi'
item_state = "scree-spess_mob" item_state = "scree-spess_mob"
item_state_slots = list(slot_r_hand_str = "eng_voidsuit", slot_l_hand_str = "eng_voidsuit")
species_restricted = null species_restricted = null
mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0) mob_can_equip(var/mob/living/carbon/human/H, slot, disable_warning = 0)

View File

@@ -312,7 +312,6 @@
if(!ignore_inhands) update_held_icon() if(!ignore_inhands) update_held_icon()
//-----------------------G44 Energy Variant-------------------- //-----------------------G44 Energy Variant--------------------
/obj/item/weapon/gun/energy/gun/burst/g44e /obj/item/weapon/gun/energy/gun/burst/g44e
name = "G44 Energy Rifle" name = "G44 Energy Rifle"
desc = "The G44 Energy is a laser variant of the G44 lightweight assault rifle manufactured by the National Armory of Gaia. Though almost exclusively to the United Federation's Military Assault Command Operations Department (MACOs) and Starfleet, it is occassionally sold to security departments for their stun capabilities." desc = "The G44 Energy is a laser variant of the G44 lightweight assault rifle manufactured by the National Armory of Gaia. Though almost exclusively to the United Federation's Military Assault Command Operations Department (MACOs) and Starfleet, it is occassionally sold to security departments for their stun capabilities."
@@ -357,6 +356,78 @@
name = "\improper MEUSOC .45" name = "\improper MEUSOC .45"
desc = "Some serious drywall work, coming up!" desc = "Some serious drywall work, coming up!"
//-----------------------KHI Common----------------------------------
/obj/item/weapon/gun/projectile/khi/process_chambered()
if (!chambered) return
qdel(chambered) //Devours ammo rather than fires it.
//-----------------------KHI Pistol----------------------------------
/obj/item/weapon/gun/projectile/khi/pistol
name = "alien pistol"
desc = "This KHI handgun doesn't so much 'fire' .45 ammo as 'devour' it and make it's own proprietary ammunition."
icon = 'icons/obj/gun_vr.dmi'
icon_state = "khipistol"
item_state = "gun" // Placeholder
magazine_type = /obj/item/ammo_magazine/c45m/flash //Dun wanna KILL all the people.
allowed_magazines = list(/obj/item/ammo_magazine/c45m)
caliber = ".45"
handle_casings = CYCLE_CASINGS
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 5)
fire_sound = 'sound/weapons/semiauto.ogg'
load_method = MAGAZINE
dna_lock = 1
//-----------------------KHI PDW----------------------------------
// For general use
/obj/item/weapon/gun/projectile/automatic/khi/pdw
name = "alien pdw"
desc = "The KHI personal defense mainstay. If KHI had any standards whatsoever, that is. Insert 9mm ammo for good times."
icon = 'icons/obj/gun_vr.dmi'
icon_state = "khipdw"
item_state = "c20r" // Placeholder
w_class = ITEMSIZE_NORMAL
caliber = "9mm"
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 5)
slot_flags = SLOT_BELT
load_method = MAGAZINE
handle_casings = CYCLE_CASINGS
magazine_type = /obj/item/ammo_magazine/mc9mml
allowed_magazines = list(/obj/item/ammo_magazine/mc9mm, /obj/item/ammo_magazine/mc9mml)
dna_lock = 1
firemodes = list(
list(mode_name="semiauto", burst=1, fire_delay=0, move_delay=null, burst_accuracy=null, dispersion=null),
list(mode_name="3-round bursts", burst=3, fire_delay=null, move_delay=6, burst_accuracy=list(0,-1,-2), dispersion=list(0.0, 0.6, 0.6))
)
//-----------------------KHI LIM Rifle----------------------------------
//Unfinished
/obj/item/weapon/limrifle //Not even a subtype of gun because it behaves differently.
name = "lim rifle"
desc = "The KHI-101-R linear induction motor rifle can propel a small 2mm slug at extreme velocity through nearly any solid object. Whether it has the time to impart any force is another question entirely."
//icon = 'icons/obj/gun64_vr.dmi'
icon_state = "limrifle"
item_state = "gun" //Should probably be huge-r
//dna_lock = 1
//safety_level = 1
var/charge_time = 5 SECONDS
var/charge_percent = 100
/obj/item/weapon/limrifle/New()
..()
update_icon()
/obj/item/weapon/limrifle/update_icon()
..()
var/charge_icon = round(charge_percent,20)
icon_state = "[initial(icon_state)]_[charge_icon]"
/obj/item/weapon/limrifle/proc/recharge()
charge_percent = 0
update_icon()
//////////////////// Energy Weapons //////////////////// //////////////////// Energy Weapons ////////////////////
// -------------- Dominator ------------- // -------------- Dominator -------------
/obj/item/weapon/gun/energy/gun/fluff/dominator /obj/item/weapon/gun/energy/gun/fluff/dominator

View File

@@ -73,11 +73,12 @@
/obj/item/fluff/permit/aronai_kadigan /obj/item/fluff/permit/aronai_kadigan
name = "Aronai Kadigan's Sidearm Permit" name = "Aronai Kadigan's Sidearm Permit"
desc = {" desc = {"
<b>NAME:</b> Aronai Kadigan | <b>RACE:</b> Cross Fox | <b>HOMEWORLD:</b> New Kitsuhana, KHI1 <b>NAME:</b> Aronai Kadigan | <b>RACE:</b> Cross Fox (Synth) | <b>HOMEWORLD:</b> Kitsuhana Prime
<b>DOB:</b> 12/Jul/2530 | <b>HEIGHT:</b> 188cm | <b>SEX:</b> Male <b>DOB:</b> 12/Jul/2530 | <b>HEIGHT:</b> 188cm | <b>SEX:</b> Male
The individual named above is licensed by the Nanotrasen Department of Civil Protection to carry one KIN-H21 (Egun Variant). The individual named above is licensed by the Nanotrasen Department of Civil Protection
This license expires on 30/Sep/2560 and must be renewed by CentCom prior to this date."} to carry one KIN (foreign) handgun with flash ammo.
This license expires on 16/Feb/2562 and must be renewed by CentCom prior to this date."}
// joanrisu:Joan Risu // joanrisu:Joan Risu
/obj/item/fluff/permit/joanrisu /obj/item/fluff/permit/joanrisu

View File

@@ -0,0 +1,36 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- rscadd: "Fake command reports now make the paper show up."

View File

@@ -0,0 +1,36 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: Anewbe
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- bugfix: "Mining cameras should work now."

View File

@@ -0,0 +1,36 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: MagmaRam
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- tweak: "There is now a short delay before being able to fire when using hostage-taking mode, and a short delay between shots. This should make hostage mode useful for taking hostages and ambushes, rather than as an aimbot in actual firefights."

View File

@@ -0,0 +1,36 @@
################################
# Example Changelog File
#
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
#
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
# When it is, any changes listed below will disappear.
#
# Valid Prefixes:
# bugfix
# wip (For works in progress)
# tweak
# soundadd
# sounddel
# rscadd (general adding of nice things)
# rscdel (general deleting of nice things)
# imageadd
# imagedel
# maptweak
# spellcheck (typo fixes)
# experiment
#################################
# Your name.
author: MagmaRam
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
delete-after: True
# Any changes you've made. See valid prefix list above.
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
# SCREW THIS UP AND IT WON'T WORK.
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
changes:
- bugfix: "Sandwiches at max size can be eaten with a fork."

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