Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:NebulaSS13/Nebula into poldev
Browse files Browse the repository at this point in the history
  • Loading branch information
MistakeNot4892 committed Jan 7, 2025
2 parents f70d03b + 0a2d482 commit 0de5bd0
Show file tree
Hide file tree
Showing 595 changed files with 6,111 additions and 5,771 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
# ignore misc BYOND files
Thumbs.db
Thumbs.db:encryptable
*.log
*.int
*.rsc
Expand All @@ -22,6 +20,11 @@ atupdate
config/*
sql/test_db

# misc OS garbage
Thumbs.db
Thumbs.db:encryptable
.DS_Store

# vscode
.vscode/*
*.code-workspace
Expand Down
3 changes: 2 additions & 1 deletion code/_helpers/emissive.dm
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/proc/emissive_overlay(var/icon, var/icon_state, var/loc, var/dir, var/color)
/proc/emissive_overlay(icon, icon_state, loc, dir, color, flags)
var/image/I = image(icon, loc, icon_state, EMISSIVE_LAYER, dir)
I.plane = EMISSIVE_PLANE
I.color = color
I.appearance_flags |= flags
return I
11 changes: 10 additions & 1 deletion code/_helpers/global_lists.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,13 @@ var/global/list/bodytype_species_pairs = list() // A list of bodytypes -> specie
. = global.playable_species
/proc/get_bodytype_species_pairs()
build_species_lists()
. = global.bodytype_species_pairs
. = global.bodytype_species_pairs

// Used to avoid constantly generating new lists during movement.
var/global/list/all_stance_limbs = list(
ORGAN_CATEGORY_STANCE,
ORGAN_CATEGORY_STANCE_ROOT
)
var/global/list/child_stance_limbs = list(
ORGAN_CATEGORY_STANCE
)
2 changes: 1 addition & 1 deletion code/_helpers/time.dm
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ var/global/round_start_time = 0
out += "[seconds] second\s"
if(length(out))
return english_list(out)
return null
return "less than a second"

/proc/roundduration2text()
if(!round_start_time)
Expand Down
7 changes: 3 additions & 4 deletions code/_helpers/unsorted.dm
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,10 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 1
return 0

#if DM_VERSION < 516
/proc/sign(x)
return x!=0?x/abs(x):0
#endif

/proc/getline(atom/M,atom/N)//Ultra-Fast Bresenham Line-Drawing Algorithm
var/px=M.x //starting x
Expand Down Expand Up @@ -717,11 +719,8 @@ Turf and target are seperate in case you want to teleport some distance from a t
/obj/item/weldingtool/can_puncture()
return 1

/obj/item/screwdriver/can_puncture()
return 1

/obj/item/clothing/mask/smokable/cigarette/can_puncture()
return src.lit
return ..() || lit // in case someone has a sharp cigarette for some reason

/*
Checks if that loc and dir has a item on the wall
Expand Down
4 changes: 2 additions & 2 deletions code/_helpers/visual_filters.dm
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@
LAZYREMOVE(filter_data, filter_name)
filters -= thing
update_filters()
return FALSE
return TRUE
return TRUE
return FALSE

/// Animate a given filter on this atom. All params after the first are passed to animate().
/atom/movable/proc/animate_filter(filter_name, list/params)
Expand Down
6 changes: 3 additions & 3 deletions code/_helpers/washing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
if(!istype(washing))
return
var/mob/living/L = washing
if(L.on_fire)
if(L.is_on_fire())
L.visible_message("<span class='danger'>A cloud of steam rises up as the water hits \the [L]!</span>")
L.ExtinguishMob()
L.fire_stacks = -20 //Douse ourselves with water to avoid fire more easily
L.extinguish_fire()
L.adjust_fire_intensity(-20) //Douse ourselves with water to avoid fire more easily
washing.clean()
30 changes: 5 additions & 25 deletions code/_onclick/click.dm
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,13 @@
var/sdepth = A.storage_depth(src)
if((!isturf(A) && A == loc) || (sdepth != -1 && sdepth <= 1))
if(holding)

// AI driven mobs have a melee telegraph that needs to be handled here.
if(check_intent(I_FLAG_HARM) && istype(A) && (!do_attack_windup_checking(A) || holding != get_active_held_item()))
return TRUE

var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
holding.afterattack(A, src, 1, params) // 1 indicates adjacency
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
else
if(ismob(A)) // No instant mob attacking
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
UnarmedAttack(A, TRUE)

trigger_aiming(TARGET_CAN_CLICK)
Expand All @@ -143,18 +138,14 @@
if(A.Adjacent(src)) // see adjacent.dm
if(holding)

// AI driven mobs have a melee telegraph that needs to be handled here.
if(check_intent(I_FLAG_HARM) && istype(A) && (!do_attack_windup_checking(A) || holding != get_active_held_item()))
return TRUE

// Return 1 in attackby() to prevent afterattack() effects (when safely moving items for example)
var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
holding.afterattack(A, src, 1, params) // 1: clicking something Adjacent
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
else
if(ismob(A)) // No instant mob attacking
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
UnarmedAttack(A, TRUE)

trigger_aiming(TARGET_CAN_CLICK)
Expand Down Expand Up @@ -217,18 +208,7 @@
if(istype(G) && G.Touch(A,1))
return TRUE

// Pick up items.
if(check_dexterity(DEXTERITY_HOLD_ITEM, silent = TRUE))
return A.attack_hand(src)

// TODO: some way to check if we SHOULD be doing an attack windup here;
// corgis attacking a tree, for example, will do the windup animation despite
// having no interaction or message shown at the end of it.
// AI driven mobs have a melee telegraph that needs to be handled here.
if(check_intent(I_FLAG_HARM) && istype(A) && !do_attack_windup_checking(A))
return TRUE

return FALSE
return A.attack_hand(src)

/*
Ranged unarmed attack:
Expand Down
4 changes: 2 additions & 2 deletions code/_onclick/cyborg.dm
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
holding.afterattack(A, src, 1, params) // 1 indicates adjacency
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
return

if(!isturf(loc))
Expand All @@ -81,7 +81,7 @@
var/resolved = holding.resolve_attackby(A, src, params)
if(!resolved && A && holding)
holding.afterattack(A, src, 1, params) // 1 indicates adjacency
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
else
holding.afterattack(A, src, 0, params)
return
Expand Down
6 changes: 6 additions & 0 deletions code/_onclick/other_mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
/atom/proc/can_interact_with_storage(user, strict = FALSE)
return isliving(user)

/atom/proc/get_required_interaction_dexterity()
return DEXTERITY_NONE

/atom/proc/attack_hand(mob/user)
SHOULD_CALL_PARENT(TRUE)

if(!user.check_dexterity(get_required_interaction_dexterity(), silent = TRUE))
return FALSE

if(can_interact_with_storage(user, strict = TRUE) && storage && user.check_dexterity((DEXTERITY_HOLD_ITEM|DEXTERITY_EQUIP_ITEM), TRUE))
add_fingerprint(user)
storage.open(user)
Expand Down
2 changes: 1 addition & 1 deletion code/_onclick/rig.dm
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,6 @@
return 0
rig.selected_module.engage(A, alert_ai)
if(ismob(A)) // No instant mob attacking - though modules have their own cooldowns
setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
setClickCooldown(DEFAULT_QUICK_COOLDOWN)
return 1
return 0
7 changes: 6 additions & 1 deletion code/controllers/master.dm
Original file line number Diff line number Diff line change
Expand Up @@ -220,12 +220,17 @@ var/global/datum/controller/master/Master = new
CRASH("Attempted to set invalid runlevel: [new_runlevel]")

// Starts the mc, and sticks around to restart it if the loop ever ends.
var/global/_announced_start = FALSE
/datum/controller/master/proc/StartProcessing(delay)
set waitfor = 0
if(delay)
sleep(delay)
report_progress("Master starting processing")
SSwebhooks.send(WEBHOOK_ROUNDPREP, list("map" = station_name(), "url" = get_world_url()))

if(!global._announced_start) // Only announce roundstart once.
SSwebhooks.send(WEBHOOK_ROUNDPREP, list("map" = station_name(), "url" = get_world_url()))
global._announced_start = TRUE

var/rtn = Loop()
if (rtn > 0 || processing < 0)
return //this was suppose to happen.
Expand Down
17 changes: 15 additions & 2 deletions code/controllers/subsystems/ambience.dm
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,23 @@ SUBSYSTEM_DEF(ambience)

// Grab what we need to set ambient light from our level handler.
var/datum/level_data/level_data = SSmapping.levels_by_z[z]
var/daycycle_id = level_data.daycycle_id
// if we don't have a daycycle ourselves, and we're indoors because of a turf blocking us
// find the first daycycle above us to use
if(!outsideness && !daycycle_id && HasAbove(z))
var/turf/above = src
var/datum/level_data/above_level_data
while ((above = GetAbove(above)))
if((above.z_flags & ZM_TERMINATOR) || !HasAbove(above.z))
break
above_level_data = SSmapping.levels_by_z[above.z]
if(above_level_data.daycycle_id)
daycycle_id = above_level_data.daycycle_id
break

// Check for daycycle ambience.
if(level_data.daycycle_id)
var/datum/daycycle/daycycle = SSdaycycle.get_daycycle(level_data.daycycle_id)
if(daycycle_id)
var/datum/daycycle/daycycle = SSdaycycle.get_daycycle(daycycle_id)
var/new_power = daycycle?.current_period?.power
if(!isnull(new_power))
if(new_power > 0)
Expand Down
1 change: 1 addition & 0 deletions code/controllers/subsystems/initialization/modpacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ SUBSYSTEM_DEF(modpacks)
// Compiled modpack information.
var/list/default_submap_whitelisted_species = list()
var/list/default_submap_blacklisted_species = list(SPECIES_ALIEN, SPECIES_GOLEM)
var/list/modpack_nanoui_directories = list()

/datum/controller/subsystem/modpacks/Initialize()
var/list/all_modpacks = decls_repository.get_decls_of_subtype(/decl/modpack)
Expand Down
60 changes: 36 additions & 24 deletions code/datums/ai/aggressive.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,14 @@
return TRUE

/datum/mob_controller/aggressive/proc/attack_target()

set waitfor = FALSE

var/atom/target = get_target()
if(!istype(target))
lose_target()
return

if(isliving(target) && body.buckled_mob == target && (!body.faction || body.buckled_mob.faction != body.faction))
body.visible_message(SPAN_DANGER("\The [body] attempts to unseat \the [body.buckled_mob]!"))
body.set_dir(pick(global.cardinal))
Expand All @@ -105,11 +109,21 @@
var/mob/living/victim = target
SET_STATUS_MAX(victim, STAT_WEAK, 3)
return target
if(body.Adjacent(target))
body.set_intent(I_FLAG_HARM)
body.ClickOn(target)

if(!body.Adjacent(target))
return target

// AI-driven mobs have a melee telegraph that needs to be handled here.
if(!body.do_attack_windup_checking(target))
return target

if(QDELETED(body) || body.incapacitated() || QDELETED(target))
return target

body.set_intent(I_FLAG_HARM)
body.ClickOn(target)
return target

/datum/mob_controller/aggressive/destroy_surroundings()

if(!body.can_act())
Expand Down Expand Up @@ -172,27 +186,25 @@
if(!(. = ..()))
return

if(!only_attack_enemies)
if(source)
set_target(source)
move_to_target(move_only = TRUE)
return

var/list/allies
var/list/around = view(body, 7)
for(var/atom/movable/A in around)
if(A == body || !isliving(A))
continue
var/mob/living/M = A
if(attack_same_faction || M.faction != body.faction)
add_enemy(M)
else if(istype(M.ai))
LAZYADD(allies, M.ai)

var/list/enemies = get_enemies()
if(LAZYLEN(enemies) && LAZYLEN(allies))
for(var/datum/mob_controller/ally as anything in allies)
ally.add_enemies(enemies)
if(only_attack_enemies)
var/list/allies
var/list/around = view(body, 7)
for(var/atom/movable/A in around)
if(A == body || !isliving(A))
continue
var/mob/living/M = A
if(attack_same_faction || M.faction != body.faction)
add_enemy(M)
else if(istype(M.ai))
LAZYADD(allies, M.ai)
var/list/enemies = get_enemies()
if(LAZYLEN(enemies) && LAZYLEN(allies))
for(var/datum/mob_controller/ally as anything in allies)
ally.add_enemies(enemies)

if(source)
set_target(source)
move_to_target(move_only = TRUE)

/datum/mob_controller/aggressive/move_to_target(var/move_only = FALSE)
if(!body.can_act())
Expand Down
6 changes: 1 addition & 5 deletions code/datums/communication/dsay.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,8 @@

keyname = C.key
if(C.mob) //Most of the time this is the dead/observer mob; we can totally use him if there is no better name
var/mindname
var/mindname = C.mob.mind?.name // the mind's "original name"
var/realname = C.mob.real_name
if(C.mob.mind)
mindname = C.mob.mind.name
if(C.mob.mind.original && C.mob.mind.original.real_name)
realname = C.mob.mind.original.real_name
if(mindname && mindname != realname)
name = "[realname] died as [mindname]"
else
Expand Down
7 changes: 0 additions & 7 deletions code/datums/datum.dm
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,3 @@
*/
/datum/proc/PopulateClone(var/datum/clone)
return clone

/////////////////////////////////////////////////////////////
//Common implementations
/////////////////////////////////////////////////////////////

/image/GetCloneArgs()
return list(icon, loc, icon_state, layer, dir)
16 changes: 15 additions & 1 deletion code/datums/extensions/abilities/abilities_predator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,26 @@
return istype(user) && !user.incapacitated() && isatom(target) && target.Adjacent(user)

/datum/ability_handler/predator/do_melee_invocation(mob/user, atom/target)
// Nibbles

// Nibbles!
if(user.check_intent(I_FLAG_HARM))
if(isliving(target))
return handle_dismemberment(user, target)
if(istype(target, /obj/item/organ))
return handle_organ_destruction(user, target)

// Digging!
var/static/list/diggable_types = list(
/turf/floor,
/turf/wall,
/obj/structure/pit,
/obj/machinery/portable_atmospherics/hydroponics/soil
)
if(is_type_in_list(target, diggable_types))
var/obj/item/organ/external/paw = user.get_usable_hand_slot_organ()
if(paw)
return target.attackby(paw, user)

return FALSE

/datum/ability_handler/predator/proc/handle_organ_destruction(mob/user, obj/item/organ/chewtoy)
Expand Down
Loading

0 comments on commit 0de5bd0

Please sign in to comment.