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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,462 changes: 2,462 additions & 0 deletions _maps/RandomRuins/StationRuins/BoxStation/engine_rbmk.dmm

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion code/__DEFINES/sound.dm
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
#define CHANNEL_BUZZ 1017
#define CHANNEL_BICYCLE 1016
#define CHANNEL_VOICE_ANNOUNCE 1015
#define CHANNEL_REACTOR_ALERT 1014

//THIS SHOULD ALWAYS BE THE LOWEST ONE!
//KEEP IT UPDATED

#define CHANNEL_HIGHEST_AVAILABLE 1014
#define CHANNEL_HIGHEST_AVAILABLE 1013

#define MAX_INSTRUMENT_CHANNELS (128 * 6)

Expand Down
44 changes: 44 additions & 0 deletions code/__HELPERS/matrices.dm
Original file line number Diff line number Diff line change
Expand Up @@ -205,3 +205,47 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro
for(x in 1 to 4)
output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001)
return output

/atom/proc/shake_animation(var/intensity = 8) //Makes the object visibly shake
var/initial_transform = new/matrix(transform)
var/init_px = pixel_x
var/shake_dir = pick(-1, 1)
var/rotation = 2+soft_cap(intensity, 1, 1, 0.94)
var/offset = 1+soft_cap(intensity*0.3, 1, 1, 0.8)
var/time = 2+soft_cap(intensity*0.3, 2, 1, 0.92)
animate(src, transform=turn(transform, rotation*shake_dir), pixel_x=init_px + offset*shake_dir, time=1)
animate(transform=initial_transform, pixel_x=init_px, time=time, easing=ELASTIC_EASING)

/*
This proc makes the input taper off above cap. But there's no absolute cutoff.
Chunks of the input value above cap, are reduced more and more with each successive one and added to the output
A higher input value always makes a higher output value. but the rate of growth slows
*/
/proc/soft_cap(var/input, var/cap = 0, var/groupsize = 1, var/groupmult = 0.9)

//The cap is a ringfenced amount. If we're below that, just return the input
if (input <= cap)
return input

var/output = 0
var/buffer = 0
var/power = 1//We increment this after each group, then apply it to the groupmult as a power

//Ok its above, so the cap is a safe amount, we move that to the output
input -= cap
output += cap

//Now we start moving groups from input to buffer


while (input > 0)
buffer = min(input, groupsize) //We take the groupsize, or all the input has left if its less
input -= buffer

buffer *= groupmult**power //This reduces the group by the groupmult to the power of which index we're on.
//This ensures that each successive group is reduced more than the previous one

output += buffer
power++ //Transfer to output, increment power, repeat until the input pile is all used

return output
7 changes: 5 additions & 2 deletions code/__HELPERS/radiation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
/proc/radiation_pulse(atom/source, intensity, range_modifier, log=FALSE, can_contaminate=TRUE)
if(!SSradiation.can_fire)
return
for(var/dir in GLOB.cardinals)
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate)
if(istype(get_turf(source), /turf/open/indestructible/sound/pool)) //Nsv13 - Pools heavily block rads. Spent fuel pool!
intensity *= 0.10
if(intensity >= 10) // Don't bother to spawn rad waves if they're just going to immediately go out
for(var/dir in GLOB.cardinals)
new /datum/radiation_wave(source, dir, intensity, range_modifier, can_contaminate)

var/list/things = get_rad_contents(source) //copypasta because I don't want to put special code in waves to handle their origin
for(var/k in 1 to things.len)
Expand Down
2 changes: 2 additions & 0 deletions code/game/atoms.dm
Original file line number Diff line number Diff line change
Expand Up @@ -693,6 +693,8 @@
* Default behaviour is to send COMSIG_ATOM_RAD_ACT and return
*/
/atom/proc/rad_act(strength)
if(istype(get_turf(src), /turf/open/indestructible/sound/pool)) //Nsv13 - Pools protect you from rads.
strength *= 0.25
SEND_SIGNAL(src, COMSIG_ATOM_RAD_ACT, strength)

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

var/list/datum/pipeline/parents
var/list/datum/gas_mixture/airs
var/startingvolume = 200

/obj/machinery/atmospherics/components/New()
parents = new(device_type)
Expand All @@ -16,7 +17,7 @@
..()

for(var/i in 1 to device_type)
var/datum/gas_mixture/A = new(200)
var/datum/gas_mixture/A = new(startingvolume)
airs[i] = A

// Iconnery
Expand Down
26 changes: 26 additions & 0 deletions code/modules/cargo/packs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2815,3 +2815,29 @@
cost = 7500
contains = list(/mob/living/simple_animal/friendly/mothroach)
crate_name = "mothroach crate"

/datum/supply_pack/fuel_rod_basic
name = "Uranium-235 Fuel Rods Crate"
desc = "Contains 3 Enriched Uranium Control Rods"
cost = 5000
contains = list(/obj/item/fuel_rod)
crate_name = "Uranium-235 Fuel Rods"
crate_type = /obj/structure/closet/crate/radiation

/datum/supply_pack/fuel_rod_plutonium
name = "Plutonium-239 Fuel Rods Crate"
desc = "Contains 3 Plutonium-239 Control Rods"
cost = 15000
contains = list(/obj/item/fuel_rod/plutonium)
crate_name = "Plutonium-239 Fuel Rods"
crate_type = /obj/structure/closet/crate/radiation

/datum/supply_pack/fuel_rod_bananium
name = "Bananium Fuel Rods Crate"
desc = "Contains 3 Bananium Control Rods"
cost = 15000
contraband = TRUE
contains = list(/obj/item/fuel_rod/material/bananium)
crate_name = "Bananium Fuel Rods"
crate_type = /obj/structure/closet/crate/radiation

246 changes: 246 additions & 0 deletions code/modules/power/reactor/fuel_rods.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,246 @@
/obj/item/fuel_rod
name = "Uranium-235 Fuel Rod"
desc = "A titanium sheathed rod containing a measure of enriched uranium-dioxide powder inside, and a breeding blanket of uranium-238 around it, used to kick off a fission reaction and breed plutonium fuel respectivly."
icon = 'icons/obj/control_rod.dmi'
icon_state = "irradiated"
w_class = WEIGHT_CLASS_BULKY
var/depletion = 0 //Each fuel rod will deplete in around 30 minutes.
var/fuel_power = 0.10
var/rad_strength = 500
var/half_life = 2000 // how many depletion ticks are needed to half the fuel_power (1 tick = 1 second)
var/time_created = 0
var/og_fuel_power = 0.20 //the original fuel power value
var/process = FALSE
// The depletion where depletion_final() will be called (and does something)
var/depletion_threshold = 100
// How fast this rod will deplete
var/depletion_speed_modifier = 1
var/depleted_final = FALSE // depletion_final should run only once
var/depletion_conversion_type = "plutonium"

/obj/item/fuel_rod/Initialize()
. = ..()
time_created = world.time
AddComponent(/datum/component/radioactive, rad_strength, src) // This should be temporary for it won't make rads go lower than 350
if(process)
START_PROCESSING(SSobj, src)

/obj/item/fuel_rod/Destroy()
if(process)
STOP_PROCESSING(SSobj, src)
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
if(istype(N))
N.fuel_rods -= src
. = ..()

// This proc will try to convert your fuel rod if you don't override this proc
// So, ideally, you should write an override of this for every fuel rod you want to create
/obj/item/fuel_rod/proc/depletion_final(result_rod)
if(!result_rod)
return
var/obj/machinery/atmospherics/components/trinary/nuclear_reactor/N = loc
// Rod conversion is moot when you can't find the reactor
if(istype(N))
var/obj/item/fuel_rod/R

// You can add your own depletion scheme and not override this proc if you are going to convert a fuel rod into another type
switch(result_rod)
if("plutonium")
R = new /obj/item/fuel_rod/plutonium(loc)
R.depletion = depletion
if("depleted")
if(fuel_power < 10)
fuel_power = 0
playsound(loc, 'sound/effects/supermatter.ogg', 100, TRUE)
R = new /obj/item/fuel_rod/depleted(loc)
R.depletion = depletion

// Finalization of conversion
if(istype(R))
N.fuel_rods += R
qdel(src)
else
depleted_final = FALSE // Maybe try again later?

/obj/item/fuel_rod/proc/deplete(amount=0.035)
depletion += amount * depletion_speed_modifier
if(depletion >= depletion_threshold && !depleted_final)
depleted_final = TRUE
depletion_final(depletion_conversion_type)

/obj/item/fuel_rod/plutonium
fuel_power = 0.20
name = "Plutonium-239 Fuel Rod"
desc = "A highly energetic titanium sheathed rod containing a sizeable measure of weapons grade plutonium, it's highly efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
icon_state = "inferior"
rad_strength = 1500
process = TRUE // for half life code
depletion_threshold = 300
depletion_conversion_type = "depleted"

/obj/item/fuel_rod/process()
fuel_power = og_fuel_power * 0.5**((world.time - time_created) / half_life SECONDS) // halves the fuel power every half life (33 minutes)

/obj/item/fuel_rod/depleted
fuel_power = 0.05
name = "Depleted Fuel Rod"
desc = "A highly radioactive fuel rod which has expended most of it's useful energy."
icon_state = "normal"
rad_strength = 6000 // smelly
depletion_conversion_type = null // It means that it won't turn into anything
process = TRUE

// Master type for material optional (or requiring, wyci) and/or producing rods
/obj/item/fuel_rod/material
// Whether the rod has been harvested. Should be set in expend().
var/expended = FALSE
// The material that will be inserted and then multiplied (or not). Should be some sort of /obj/item/stack
var/material_type
// The name of material that'll be used for texts
var/material_name
var/material_name_singular
var/initial_amount = 0
// The maximum amount of material the rod can hold
var/max_initial_amount = 10
var/grown_amount = 0
// The multiplier for growth. 1 for the same 2 for double etc etc
var/multiplier = 2
// After this depletion, you won't be able to add new materials
var/material_input_deadline = 25
// Material fuel rods generally don't get converted into another fuel object
depletion_conversion_type = null

// Called when the rod is fully harvested
/obj/item/fuel_rod/material/proc/expend()
expended = TRUE

// Basic checks for material rods
/obj/item/fuel_rod/material/proc/check_material_input(mob/user)
if(depletion >= material_input_deadline)
to_chat(user, "<span class='warning'>The sample slots have sealed themselves shut, it's too late to add [material_name] now!</span>") // no cheesing in crystals at 100%
return FALSE
if(expended)
to_chat(user, "<span class='warning'>\The [src]'s material slots have already been used.</span>")
return FALSE
return TRUE

// The actual growth
/obj/item/fuel_rod/material/depletion_final(result_rod)
if(result_rod)
..() // So if you put anything into depletion_conversion_type then your fuel rod will be converted (or not) and *won't grow*
else
grown_amount = initial_amount * multiplier

/obj/item/fuel_rod/material/attackby(obj/item/W, mob/user, params)
var/obj/item/stack/sheet/M = W
if(!material_type && istype(M))
material_type = M.type
if(istype(M, material_type))
if(!check_material_input(user))
return
if(initial_amount < max_initial_amount)
var/adding = min((max_initial_amount - initial_amount), M.amount)
M.amount -= adding
initial_amount += adding
if (adding == 1)
to_chat(user, "<span class='notice'>You insert [adding] [material_name_singular] into \the [src].</span>")
else
to_chat(user, "<span class='notice'>You insert [adding] [material_name] into \the [src].</span>")
M.zero_amount()
else
to_chat(user, "<span class='warning'>\The [src]'s material slots are full!</span>")
return
else
return ..()

/obj/item/fuel_rod/material/attack_self(mob/user)
if(expended)
to_chat(user, "<span class='notice'>You have already removed [material_name] from \the [src].</span>")
return

if(depleted_final)
new material_type(user.loc, grown_amount)
if (grown_amount == 1)
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name_singular] from \the [src].</span>") // Unlikely
else
to_chat(user, "<span class='notice'>You harvest [grown_amount] [material_name] from \the [src].</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
grown_amount = 0
expend()
else if(depletion)
to_chat(user, "<span class='warning'>\The [src] has not fissiled enough to fully grow the sample. The progress bar shows it is [min(depletion/depletion_threshold*100,100)]% complete.</span>")
playsound(src, 'sound/machines/buzz-sigh.ogg', 50, 0)
else if(initial_amount)
new material_type(user.loc, initial_amount)
if (initial_amount == 1)
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name_singular] from \the [src].</span>")
else
to_chat(user, "<span class='notice'>You remove [initial_amount] [material_name] from \the [src].</span>")
playsound(loc, 'sound/effects/stonedoor_openclose.ogg', 50, 1)
initial_amount = 0

/obj/item/fuel_rod/material/examine(mob/user)
. = ..()
if(material_type)
if(expended)
. += "<span class='warning'>The material slots have been slagged by the extreme heat, you can't grow [material_name] in this rod again...</span>"
return
else if(depleted_final)
. += "<span class='warning'>This fuel rod's [material_name] are now fully grown, and it currently bears [grown_amount] harvestable [material_name_singular]\s.</span>"
return
if(depletion)
. += "<span class='danger'>The sample is [min(depletion/depletion_threshold*100,100)]% fissiled.</span>"
. += "<span class='disarm'>[initial_amount]/[max_initial_amount] of the slots for [material_name] are full.</span>"
else
. += "<span class='disarm'>This rod is ready for material breeding</span>"

/obj/item/fuel_rod/material/telecrystal
name = "Telecrystal Fuel Rod"
desc = "A disguised titanium sheathed rod containing several small slots infused with uranium dioxide. Permits the insertion of telecrystals to grow more. Fissiles much faster than its standard counterpart"
icon_state = "telecrystal"
fuel_power = 0.30 // twice as powerful as a normal rod, you're going to need some engineering autism if you plan to mass produce TC
depletion_speed_modifier = 3 // headstart, otherwise it takes two hours
rad_strength = 1500
max_initial_amount = 8
multiplier = 3
material_type = /obj/item/stack/telecrystal
material_name = "telecrystals"
material_name_singular = "telecrystal"

/obj/item/fuel_rod/material/telecrystal/depletion_final(result_rod)
..()
if(result_rod)
return
fuel_power = 0.60 // thrice as powerful as plutonium, you'll want to get this one out quick!
name = "Exhausted Telecrystal Fuel Rod"
desc = "A highly energetic, disguised titanium sheathed rod containing a number of slots filled with greatly expanded telecrystals which can be removed by hand. It's extremely efficient as nuclear fuel, but will cause the reaction to get out of control if not properly utilised."
icon_state = "telecrystal_used"
AddComponent(/datum/component/radioactive, 3000, src)

/obj/item/fuel_rod/material/bananium
name = "Bananium Fuel Rod"
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than its cowardly counterparts. However, its cutting-edge cosmic clown technology allows rooms for extraordinarily exhilarating extraterrestrial element called bananium to menacingly multiply."
icon_state = "bananium"
fuel_power = 0.15
depletion_speed_modifier = 3
rad_strength = 350
max_initial_amount = 10
multiplier = 3
material_type = /obj/item/stack/sheet/mineral/bananium
material_name = "sheets of bananium"
material_name_singular = "sheet of bananium"

/obj/item/fuel_rod/material/bananium/deplete(amount=0.035)
..()
if(initial_amount == max_initial_amount && prob(10))
playsound(src, pick('sound/items/bikehorn.ogg'), 50) // HONK

/obj/item/fuel_rod/material/bananium/depletion_final(result_rod)
..()
if(result_rod)
return
fuel_power = 0.3 // Be warned
name = "Fully Grown Bananium Fuel Rod"
desc = "A hilarious heavy-duty fuel rod which fissiles a bit slower than it cowardly counterparts. Its greatly grimacing growth stage is now over, and bananium outgrowth hums as if it's blatantly honking bike horns."
icon_state = "bananium_used"
AddComponent(/datum/component/radioactive, 1250, src)
Loading