Skip to content

Commit

Permalink
Merge branch 'master' into EFTPOS-Scamer
Browse files Browse the repository at this point in the history
  • Loading branch information
Drsmail authored Dec 30, 2024
2 parents e89c915 + d99c9b2 commit e31c512
Show file tree
Hide file tree
Showing 38 changed files with 355 additions and 289 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
'/datum/map/cerestation',
'/datum/map/emeraldstation',
]
byondtype: ['STABLE']
byondtype: ['STABLE', 'BETA']
services:
mariadb:
image: mariadb:latest
Expand Down
4 changes: 2 additions & 2 deletions _build_dependencies.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ export STABLE_BYOND_MAJOR=515
# Stable Byond Minor
export STABLE_BYOND_MINOR=1633
# Beta Byond Major - Uncomment and update if beta cycle active
#export BETA_BYOND_MAJOR=515
export BETA_BYOND_MAJOR=516
# Beta Byond Minor - Uncomment and update if beta cycle active
#export BETA_BYOND_MINOR=1633
export BETA_BYOND_MINOR=1648
# Python version for mapmerge and other tools
export PYTHON_VERSION=3.11.6
# RUSTG version
Expand Down
2 changes: 1 addition & 1 deletion _maps/map_files/stations/metastation.dmm
Original file line number Diff line number Diff line change
Expand Up @@ -27328,7 +27328,7 @@
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
dir = 4
},
/obj/machinery/alarm/directional/north,
/obj/machinery/alarm/server/directional/north,
/turf/simulated/floor/plasteel/dark/telecomms,
/area/station/science/server/coldroom)
"cbi" = (
Expand Down
4 changes: 2 additions & 2 deletions code/__DEFINES/antag_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ GLOBAL_LIST(contractors)

#define ORG_PROB_HUNTER 10
#define ORG_PROB_MILD 20
#define ORG_PROB_AVERAGE 60
#define ORG_PROB_HIJACK 10
#define ORG_PROB_AVERAGE 65
#define ORG_PROB_HIJACK 5

// Chance that a traitor will receive a 'You are being targeted by another syndicate agent' notification regardless of being an actual target
#define ORG_PROB_PARANOIA 5
Expand Down
6 changes: 6 additions & 0 deletions code/__DEFINES/atmospherics_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,9 @@
#define ENVIRONMENT_TEMPERATE "temperate"
/// Cold environment: Normal atmosphere, -93 C.
#define ENVIRONMENT_COLD "cold"

// Vent pump modes
/// Don't go over the external pressure
#define ONLY_CHECK_EXT_PRESSURE 1
/// Only release until we reach this pressure
#define ONLY_CHECK_INT_PRESSURE 2
8 changes: 8 additions & 0 deletions code/__HELPERS/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,14 @@ Returns 1 if the chain up to the area contains the given typepath
var/y_pos
var/z_pos

/datum/coords/New(x_pos_, y_pos_, z_pos_)
x_pos = x_pos_
y_pos = y_pos_
z_pos = z_pos_

/datum/coords/proc/to_string(z = null)
return "([x_pos],[y_pos],[z ? z : z_pos])"

/area/proc/move_contents_to(area/A, turf_to_leave, direction) // someone rewrite this function i beg of you
//Takes: Area. Optional: turf type to leave behind.
//Returns: Nothing.
Expand Down
11 changes: 10 additions & 1 deletion code/datums/helper_datums/map_template.dm
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@
stack_trace(" The file of [src] appears to be empty/non-existent.")

/datum/map_template/proc/get_affected_turfs(turf/T, centered = 0)
var/list/coordinate_bounds = get_coordinate_bounds(T, centered)
var/datum/coords/bottom_left = coordinate_bounds["bottom_left"]
var/datum/coords/top_right = coordinate_bounds["top_right"]
return block(max(bottom_left.x_pos, 1), max(bottom_left.y_pos, 1), T.z, min(top_right.x_pos, world.maxx), min(top_right.y_pos, world.maxy), T.z)

/datum/map_template/proc/get_coordinate_bounds(turf/T, centered = FALSE)
var/turf/placement = T
var/min_x = placement.x
var/min_y = placement.y
Expand All @@ -93,7 +99,10 @@

var/max_x = min_x + width-1
var/max_y = min_y + height-1
return block(max(min_x, 1), max(min_y, 1), placement.z, min(max_x, world.maxx), min(max_y, world.maxy), placement.z)

var/datum/coords/bottom_left = new(min_x, min_y, 1)
var/datum/coords/top_right = new(max_x, max_y, 1)
return list("bottom_left" = bottom_left, "top_right" = top_right)

/datum/map_template/proc/fits_in_map_bounds(turf/T, centered = 0)
var/turf/placement = T
Expand Down
129 changes: 112 additions & 17 deletions code/datums/ruins/ruin_placer.dm
Original file line number Diff line number Diff line change
@@ -1,7 +1,107 @@
#define DEFAULT_PADDING 32

/datum/ruin_placement
var/datum/map_template/ruin/ruin
var/base_padding
var/padding

/datum/ruin_placement/New(datum/map_template/ruin/ruin_, padding_ = DEFAULT_PADDING, base_padding_ = 0)
. = ..()
ruin = ruin_
base_padding = base_padding_
padding = padding_

/datum/ruin_placement/proc/reduce_padding()
padding = max(floor(padding / 2) - 1, -1)

/datum/ruin_placement/proc/try_to_place(zlist_or_zlevel, area_whitelist)
var/list/z_levels = islist(zlist_or_zlevel) ? zlist_or_zlevel : list(zlist_or_zlevel)

// Our goal is to maximize padding, so we'll perform some number of attempts
// on one z-level, then the next, until we reach some limit, then reduce the
// padding and start again.
padding = DEFAULT_PADDING
while(padding >= 0)
var/width_border = base_padding + round(ruin.width / 2) + padding
var/height_border = base_padding + round(ruin.height / 2) + padding

for(var/z_level in z_levels)
var/placement_tries = PLACEMENT_TRIES
while(placement_tries > 0)
placement_tries--

var/turf/central_turf = locate(
rand(width_border, world.maxx - width_border),
rand(height_border, world.maxy - height_border),
z_level
)
var/valid = TRUE

if(!central_turf)
continue

// Expand the original bounds of the ruin with our padding and call
// that our list of affected turfs.
var/list/bounds = ruin.get_coordinate_bounds(central_turf, centered = TRUE)
var/datum/coords/bottom_left = bounds["bottom_left"]
var/datum/coords/top_right = bounds["top_right"]
bottom_left.x_pos -= padding
bottom_left.y_pos -= padding
top_right.x_pos += padding
top_right.y_pos += padding
var/list/affected_turfs = block(bottom_left.x_pos, bottom_left.y_pos, z_level, top_right.x_pos, top_right.y_pos, z_level)

// One sanity check just in case
if(!ruin.fits_in_map_bounds(central_turf, centered = TRUE))
valid = FALSE

for(var/turf/check in affected_turfs)
var/area/new_area = get_area(check)
if(!(istype(new_area, area_whitelist)) || check.flags & NO_RUINS)
valid = FALSE
break

if(!valid)
continue

for(var/turf/T in affected_turfs)
for(var/obj/structure/spawner/nest in T)
qdel(nest)
for(var/mob/living/simple_animal/monster in T)
qdel(monster)
for(var/obj/structure/flora/ash/plant in T)
qdel(plant)

ruin.load(central_turf, centered = TRUE)
for(var/turf/T in ruin.get_affected_turfs(central_turf, centered = TRUE)) // Just flag the actual ruin turfs!
T.flags |= NO_RUINS
new /obj/effect/landmark/ruin(central_turf, ruin)
ruin.loaded++

log_world("Ruin \"[ruin.name]\" placed at ([central_turf.x], [central_turf.y], [central_turf.z])")

var/map_filename = splittext(ruin.mappath, "/")
map_filename = map_filename[length(map_filename)]
SSblackbox.record_feedback("associative", "ruin_placement", 1, list(
"map" = map_filename,
"coords" = "[central_turf.x],[central_turf.y],[central_turf.z]"
))

return TRUE

// Ran out of placement tries for this z-level/padding, move to the next z-level

// Ran out of z-levels to try with this padding, cut it and start again
reduce_padding()

// Ran out of z-levels, we got nowhere to place it
return FALSE

/datum/ruin_placer
var/ruin_budget
var/area_whitelist
var/list/templates
var/base_padding

/datum/ruin_placer/proc/place_ruins(z_levels)
if(!z_levels || !length(z_levels))
Expand Down Expand Up @@ -44,30 +144,16 @@
else //Otherwise just pick random one
current_pick = pickweight(ruins_availible)

var/placement_tries = PLACEMENT_TRIES
var/failed_to_place = TRUE
var/z_placed = 0
while(placement_tries > 0)
placement_tries--
z_placed = pick(z_levels)
if(!current_pick.try_to_place(forced_z ? forced_z : z_placed, area_whitelist))
continue
else
failed_to_place = FALSE
break
var/datum/ruin_placement/placement = new(current_pick, base_padding_ = base_padding)
var/placement_success = placement.try_to_place(forced_z ? forced_z : z_levels, area_whitelist)

//That's done remove from priority even if it failed
if(forced)
//TODO : handle forced ruins with multiple variants
forced_ruins -= current_pick
forced = FALSE

if(failed_to_place)
for(var/datum/map_template/ruin/R in ruins_availible)
if(R.id == current_pick.id)
ruins_availible -= R
log_world("Failed to place [current_pick.name] ruin.")
else
if(placement_success)
ruin_budget -= current_pick.get_cost()
if(!current_pick.allow_duplicates)
for(var/datum/map_template/ruin/R in ruins_availible)
Expand All @@ -78,6 +164,12 @@
for(var/possible_exclusion in ruins_availible)
if(istype(possible_exclusion,blacklisted_type))
ruins_availible -= possible_exclusion
else
for(var/datum/map_template/ruin/R in ruins_availible)
if(R.id == current_pick.id)
ruins_availible -= R
log_world("Failed to place [current_pick.name] ruin.")

forced_z = 0

//Update the availible list
Expand All @@ -87,8 +179,11 @@

log_world("Ruin loader finished with [ruin_budget] left to spend.")

#undef DEFAULT_PADDING

/datum/ruin_placer/space
area_whitelist = /area/space
base_padding = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD

/datum/ruin_placer/space/New()
ruin_budget = rand(
Expand Down
8 changes: 1 addition & 7 deletions code/datums/spell.dm
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,6 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
var/should_recharge_after_cast = TRUE
var/still_recharging_msg = "<span class='notice'>The spell is still recharging.</span>"

var/holder_var_type = "bruteloss" //only used if charge_type equals to "holder_var"
var/holder_var_amount = 20 //same. The amount adjusted with the mob's var when the spell is used
var/active = FALSE //Used by toggle based abilities.
var/ranged_mousepointer
var/mob/ranged_ability_user
Expand All @@ -97,9 +95,6 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
var/overlay_icon_state = "spell"
var/overlay_lifespan = 0

var/sparks_spread = FALSE
var/sparks_amt = 0

///Determines if the spell has smoke, and if so what effect the smoke has. See spell defines.
var/smoke_type = SMOKE_NONE
var/smoke_amt = 0
Expand Down Expand Up @@ -389,8 +384,7 @@ GLOBAL_LIST_INIT(spells, typesof(/datum/spell))
location = target
if(isliving(target) && message)
to_chat(target, "[message]")
if(sparks_spread)
do_sparks(sparks_amt, 0, location)

if(smoke_type)
var/datum/effect_system/smoke_spread/smoke
switch(smoke_type)
Expand Down
20 changes: 17 additions & 3 deletions code/game/gamemodes/miniantags/pulsedemon/pulsedemon.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
gender = NEUTER
speak_chance = 20

damage_coeff = list(BRUTE = 0, BURN = 0, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) // Pulse demons take damage from nothing
damage_coeff = list(BRUTE = 0, BURN = 0.5, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) // Pulse demons take damage from nothing except some from lasers

emote_hear = list("vibrates", "sizzles")
speak_emote = list("modulates")
Expand Down Expand Up @@ -781,9 +781,11 @@
return FALSE

/mob/living/simple_animal/demon/pulse_demon/bullet_act(obj/item/projectile/proj)
if(istype(proj, /obj/item/projectile/ion))
if(proj.damage_type == BURN)
regen_lock = max(regen_lock, 1)
return ..()
visible_message("<span class='warning'>[proj] goes right through [src]!</span>")
else
visible_message("<span class='warning'>[proj] goes right through [src]!</span>")

/mob/living/simple_animal/demon/pulse_demon/electrocute_act(shock_damage, source, siemens_coeff, flags)
return
Expand Down Expand Up @@ -826,6 +828,18 @@
return FALSE
return TRUE

/mob/living/simple_animal/demon/pulse_demon/adjustHealth(amount, updating_health)
if(amount > 0) // This damages the pulse demon
return ..()

if(!ismachinery(loc))
if(health >= (maxHealth / 2))
amount = 0
else
amount = clamp(amount, -((maxHealth / 2) - health), 0)
amount = round(amount, 1)
return ..()

/obj/item/organ/internal/heart/demon/pulse
name = "perpetual pacemaker"
desc = "It still beats furiously, thousands of bright lights shine within it."
Expand Down
2 changes: 1 addition & 1 deletion code/game/mecha/mecha_construction_paths.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@
holder.icon_state = "phazon16"
else
user.visible_message("[user] removes the bluespace crystal from the [holder].", "You remove the bluespace crystal from the [holder].")
new /obj/item/stack/ore/bluespace_crystal(get_turf(holder), new_amount = 5)
new /obj/item/stack/ore/bluespace_crystal(get_turf(holder), 5)
holder.icon_state = "phazon14"
if(8)
if(diff==CONSTRUCTION_PATH_FORWARDS)
Expand Down
5 changes: 4 additions & 1 deletion code/game/objects/items/robot/cyborg_gripper.dm
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@
if(!gripped_item)
to_chat(user, "<span class='warning'>[src] is empty.</span>")
return
gripped_item.attack_self__legacy__attackchain(user)
if(gripped_item.new_attack_chain)
gripped_item.activate_self(user)
else
gripped_item.attack_self__legacy__attackchain(user)

// This is required to ensure that the forceMove checks on some objects don't rip the gripper out of the borg's inventory and toss it on the floor. That would hurt, a lot!
/obj/item/gripper/forceMove(atom/destination)
Expand Down
5 changes: 2 additions & 3 deletions code/game/objects/items/stacks/rods.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,9 @@ GLOBAL_LIST_INIT(rod_recipes, list (
/obj/item/stack/rods/fifty
amount = 50

/obj/item/stack/rods/New(loc, amount=null)
..()
/obj/item/stack/rods/Initialize(mapload, new_amount, merge)
. = ..()
recipes = GLOB.rod_recipes
update_icon(UPDATE_ICON_STATE)

/obj/item/stack/rods/update_icon_state()
var/amount = get_amount()
Expand Down
Loading

0 comments on commit e31c512

Please sign in to comment.