diff --git a/.github/workflows/autochangelog.yml b/.github/workflows/autochangelog.yml index 7732426718..7953929ce5 100644 --- a/.github/workflows/autochangelog.yml +++ b/.github/workflows/autochangelog.yml @@ -1,6 +1,6 @@ name: Autochangelog on: - pull_request: + pull_request_target: types: closed branches: - master @@ -15,6 +15,10 @@ jobs: if: github.event.pull_request.merged == true steps: - uses: /actions/checkout@v2 + with: + ref: master + - name: Update repository to master + run: git pull "origin" master - name: Ensure +x on CI directory run: | chmod -R +x ./tools/ci diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm index 23cdf8b171..524dd23ff4 100644 --- a/code/_helpers/global_lists.dm +++ b/code/_helpers/global_lists.dm @@ -93,7 +93,6 @@ var/global/list/string_slot_flags = list( "holster" = SLOT_HOLSTER ) -//CHOMP Edit: This fix is taken from citadel station pr #2779. Fixes a "pretty horrific memory leak" that is called any time someone opens character creator. GLOBAL_LIST_EMPTY(mannequins) /proc/get_mannequin(var/ckey = "NULL") var/mob/living/carbon/human/dummy/mannequin/M = GLOB.mannequins[ckey] diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index bf5fc0ab18..510b8bf762 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -134,7 +134,7 @@ for(var/i in loc) var/atom/movable/thing = i // We don't call parent so we are calling this for byond - thing.Crossed(src) + thing.Crossed(src, oldloc) // We're a multi-tile object (multiple locs) else if(. && newloc) diff --git a/code/modules/client/preference_setup/vore/02_size.dm b/code/modules/client/preference_setup/vore/02_size.dm index 774bdede17..a1149821d2 100644 --- a/code/modules/client/preference_setup/vore/02_size.dm +++ b/code/modules/client/preference_setup/vore/02_size.dm @@ -45,7 +45,6 @@ character.weight_gain = pref.weight_gain character.weight_loss = pref.weight_loss character.fuzzy = pref.fuzzy - character.appearance_flags -= pref.fuzzy*PIXEL_SCALE character.resize(pref.size_multiplier, animate = FALSE) /datum/category_item/player_setup_item/vore/size/content(var/mob/user) @@ -70,7 +69,7 @@ else if(href_list["toggle_fuzzy"]) pref.fuzzy = pref.fuzzy ? 0 : 1; - return TOPIC_REFRESH + return TOPIC_REFRESH_UPDATE_PREVIEW else if(href_list["weight"]) var/new_weight = input(user, "Choose your character's relative body weight.\n\ diff --git a/code/modules/mob/living/carbon/human/emote_vr.dm b/code/modules/mob/living/carbon/human/emote_vr.dm index bd9e2dae7f..6361d34ab4 100644 --- a/code/modules/mob/living/carbon/human/emote_vr.dm +++ b/code/modules/mob/living/carbon/human/emote_vr.dm @@ -193,8 +193,12 @@ handle_flip_vr() message = "does a flip!" m_type = 1 + if("roarbark") //Roarbark is CHOMP Addition + message = "lets out a roar-bark!" + m_type = 2 //Also full disclosure this sounds AWFUL with the normal pitch shifting + playsound(loc, 'sound/voice/roarbark.ogg', 50, 0, preference = /datum/client_preference/emote_noises) if("vhelp") //Help for Virgo-specific emotes. - to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, howl, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, gao, cackle, nsay, nme, flip") //CHOMP Addition: adds howl to list since YW didn't + to_chat(src, "vwag, vflap, mlem, blep, awoo, awoo2, growl, nya, peep, chirp, hoot, weh, merp, myarp, bark, bork, mrow, mrowl, hypno, howl, hiss, rattle, squeak, geck, baa, baa2, mar, wurble, snort, meow, moo, croak, gao, cackle, nsay, nme, flip, roarbark") //CHOMP Addition: adds howl to list since YW didn't return TRUE if(message) diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index da4e871c1e..ed7935e871 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -141,6 +141,9 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon() var/desired_scale_y = size_multiplier * icon_scale_y desired_scale_x *= species.icon_scale_x desired_scale_y *= species.icon_scale_y + appearance_flags |= PIXEL_SCALE + if(fuzzy) + appearance_flags &= ~PIXEL_SCALE //VOREStation Edit End // Regular stuff again. diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 5e61c1d016..2197d7ff1d 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -74,214 +74,6 @@ usr.visible_message("[src] points to [A]") return 1 -/*one proc, four uses -swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive -default behaviour is: - - non-passive mob passes the passive version - - passive mob checks to see if its mob_bump_flag is in the non-passive's mob_bump_flags - - if si, the proc returns -*/ -/mob/living/proc/can_move_mob(var/mob/living/swapped, swapping = 0, passive = 0) - if(!swapped) - return 1 - if(!passive) - return swapped.can_move_mob(src, swapping, 1) - else - var/context_flags = 0 - if(swapping) - context_flags = swapped.mob_swap_flags - else - context_flags = swapped.mob_push_flags - if(!mob_bump_flag) //nothing defined, go wild - return 1 - if(mob_bump_flag & context_flags) - return 1 - return 0 - -/mob/living/Bump(atom/movable/AM) - if(now_pushing || !loc || buckled == AM) - return - now_pushing = 1 - if (istype(AM, /mob/living)) - var/mob/living/tmob = AM - - //Even if we don't push/swap places, we "touched" them, so spread fire - spread_fire(tmob) - - for(var/mob/living/M in range(tmob, 1)) - if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) - if ( !(world.time % 5) ) - to_chat(src, "[tmob] is restrained, you cannot push past") - now_pushing = 0 - return - if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) - if ( !(world.time % 5) ) - to_chat(src, "[tmob] is restraining [M], you cannot push past") - now_pushing = 0 - return - - //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller - var/can_swap = 1 - if(loc.density || tmob.loc.density) - can_swap = 0 - if(can_swap) - for(var/atom/movable/A in loc) - if(A == src) - continue - if(!A.CanPass(tmob, loc)) - can_swap = 0 - if(!can_swap) break - if(can_swap) - for(var/atom/movable/A in tmob.loc) - if(A == tmob) - continue - if(!A.CanPass(src, tmob.loc)) - can_swap = 0 - if(!can_swap) break - - //Leaping mobs just land on the tile, no pushing, no anything. - if(status_flags & LEAPING) - loc = tmob.loc - status_flags &= ~LEAPING - now_pushing = 0 - return - - if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && can_swap && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! - var/turf/oldloc = loc - //VOREstation Edit - Begin - - //check bumpnom chance, if it's a simplemob that's doing the bumping - var/mob/living/simple_mob/srcsimp = src - if(istype(srcsimp)) - if(srcsimp.tryBumpNom(tmob)) - now_pushing = 0 - return - - //if it's a simplemob being bumped, and the above didn't make them start getting bumpnommed, they get a chance to bumpnom - var/mob/living/simple_mob/tmobsimp = tmob - if(istype(tmobsimp)) - if(tmobsimp.tryBumpNom(src)) - now_pushing = 0 - return - - //VOREstation Edit - End - forceMove(tmob.loc) - //VOREstation Edit - Begin - // In case of micros, we don't swap positions; instead occupying the same square! - if (handle_micro_bump_helping(tmob)) - now_pushing = 0 - return - // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below. - // VOREStation Edit - End - tmob.forceMove(oldloc) - now_pushing = 0 - return - //VOREStation Edit - Begin - else if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && canmove && can_swap && handle_micro_bump_helping(tmob)) - forceMove(tmob.loc) - now_pushing = 0 - return - //VOREStation Edit - End - - if(!can_move_mob(tmob, 0, 0)) - now_pushing = 0 - return - if(a_intent == I_HELP || src.restrained()) - now_pushing = 0 - return - // VOREStation Edit - Begin - // Plow that nerd. - if(ishuman(tmob)) - var/mob/living/carbon/human/H = tmob - if(H.species.lightweight == 1 && prob(50)) - H.visible_message("[src] bumps into [H], knocking them off balance!") - H.Weaken(5) - now_pushing = 0 - return - // Handle grabbing, stomping, and such of micros! - if(handle_micro_bump_other(tmob)) return - // VOREStation Edit - End - if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) - if(prob(40) && !(FAT in src.mutations)) - to_chat(src, "You fail to push [tmob]'s fat ass out of the way.") - now_pushing = 0 - return - if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - - if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) - if(prob(99)) - now_pushing = 0 - return - if(!(tmob.status_flags & CANPUSH)) - now_pushing = 0 - return - - tmob.LAssailant = src - - now_pushing = 0 - . = ..() - if (!istype(AM, /atom/movable) || AM.anchored) - //VOREStation Edit - object-specific proc for running into things - if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying) - AM.stumble_into(src) - //VOREStation Edit End - /* VOREStation Removal - See above - if(confused && prob(50) && m_intent=="run") - Weaken(2) - playsound(loc, "punch", 25, 1, -1) - visible_message("[src] [pick("ran", "slammed")] into \the [AM]!") - src.apply_damage(5, BRUTE) - to_chat(src, "You just [pick("ran", "slammed")] into \the [AM]!") - */ // VOREStation Removal End - return - if (!now_pushing) - if(isobj(AM)) - var/obj/I = AM - if(!can_pull_size || can_pull_size < I.w_class) - return - now_pushing = 1 - - var/t = get_dir(src, AM) - if (istype(AM, /obj/structure/window)) - for(var/obj/structure/window/win in get_step(AM,t)) - now_pushing = 0 - return - var/turf/T = AM.loc - var/turf/T2 = get_step(AM,t) - if(!T2) // Map edge - now_pushing = 0 - return - var/move_time = movement_delay(loc, t) - move_time = DS2NEARESTTICK(move_time) - if(AM.Move(T2, t, move_time)) - Move(T, t, move_time) - if(ishuman(AM) && AM:grabbed_by) - for(var/obj/item/weapon/grab/G in AM:grabbed_by) - step(G:assailant, get_dir(G:assailant, AM)) - G.adjust_position() - now_pushing = 0 - -/mob/living/CanPass(atom/movable/mover, turf/target) - if(istype(mover, /obj/structure/blob) && faction == "blob") //Blobs should ignore things on their faction. - return TRUE - return ..() - -// Called when something steps onto us. This allows for mulebots and vehicles to run things over. <3 -/mob/living/Crossed(var/atom/movable/AM) // Transplanting this from /mob/living/carbon/human/Crossed() - if(AM == src || AM.is_incorporeal()) // We're not going to run over ourselves or ghosts - return - - if(istype(AM, /mob/living/bot/mulebot)) - var/mob/living/bot/mulebot/MB = AM - MB.runOver(src) - - if(istype(AM, /obj/vehicle)) - var/obj/vehicle/V = AM - V.RunOver(src) - /mob/living/verb/succumb() set hidden = 1 if ((src.health < 0 && src.health > (5-src.getMaxHealth()))) // Health below Zero but above 5-away-from-death, as before, but variable @@ -682,36 +474,6 @@ default behaviour is: // ++++ROCKDTBEN++++ MOB PROCS //END -// Applies direct "cold" damage while checking protection against the cold. -/mob/living/proc/inflict_cold_damage(amount) - amount *= 1 - get_cold_protection(50) // Within spacesuit protection. - if(amount > 0) - adjustFireLoss(amount) - -// Ditto, but for "heat". -/mob/living/proc/inflict_heat_damage(amount) - amount *= 1 - get_heat_protection(10000) // Within firesuit protection. - if(amount > 0) - adjustFireLoss(amount) - -// and one for electricity because why not -/mob/living/proc/inflict_shock_damage(amount) - electrocute_act(amount, null, 1 - get_shock_protection(), pick(BP_HEAD, BP_TORSO, BP_GROIN)) - -// also one for water (most things resist it entirely, except for slimes) -/mob/living/proc/inflict_water_damage(amount) - amount *= 1 - get_water_protection() - if(amount > 0) - adjustToxLoss(amount) - -// one for abstracted away ""poison"" (mostly because simplemobs shouldn't handle reagents) -/mob/living/proc/inflict_poison_damage(amount) - if(isSynthetic()) - return - amount *= 1 - get_poison_protection() - if(amount > 0) - adjustToxLoss(amount) - /mob/proc/get_contents() @@ -762,50 +524,6 @@ default behaviour is: return 1 return 0 - -/mob/living/proc/can_inject() - return 1 - -/mob/living/proc/get_organ_target() - var/mob/shooter = src - var/t = shooter:zone_sel.selecting - if ((t in list( O_EYES, O_MOUTH ))) - t = BP_HEAD - var/obj/item/organ/external/def_zone = ran_zone(t) - return def_zone - - -// heal ONE external organ, organ gets randomly selected from damaged ones. -/mob/living/proc/heal_organ_damage(var/brute, var/burn) - adjustBruteLoss(-brute) - adjustFireLoss(-burn) - src.updatehealth() - -// damage ONE external organ, organ gets randomly selected from damaged ones. -/mob/living/proc/take_organ_damage(var/brute, var/burn, var/emp=0) - if(status_flags & GODMODE) return 0 //godmode - adjustBruteLoss(brute) - adjustFireLoss(burn) - src.updatehealth() - -// heal MANY external organs, in random order -/mob/living/proc/heal_overall_damage(var/brute, var/burn) - adjustBruteLoss(-brute) - adjustFireLoss(-burn) - src.updatehealth() - -// damage MANY external organs, in random order -/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null) - if(status_flags & GODMODE) return 0 //godmode - adjustBruteLoss(brute) - adjustFireLoss(burn) - src.updatehealth() - -/mob/living/proc/restore_all_organs() - return - - - /mob/living/proc/revive() rejuvenate() if(buckled) @@ -903,104 +621,6 @@ default behaviour is: return -// Almost all of this handles pulling movables behind us -/mob/living/Move(atom/newloc, direct, movetime) - if(buckled && buckled.loc != newloc) //not updating position - if(!buckled.anchored && buckled.buckle_movable) - return buckled.Move(newloc, direct) - else - return 0 - - var/atom/movable/pullee = pulling - // Prior to our move it's already too far away - if(pullee && get_dist(src, pullee) > 1) - stop_pulling() - // Shenanigans! Pullee closed into locker for eg. - if(pullee && !isturf(pullee.loc) && pullee.loc != loc) - stop_pulling() - // Can't pull with no hands - if(restrained()) - stop_pulling() - - // Will move our mob (probably) - . = ..() // Moved() called at this point if successful - - if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //seperated from our puller and not in the middle of a diagonal move - pulledby.stop_pulling() - - if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much. - s_active.close(src) - -/mob/living/proc/dragged(var/mob/living/dragger, var/oldloc) - var/area/A = get_area(src) - if(lying && !buckled && pull_damage() && A.has_gravity && (prob(getBruteLoss() * 200 / maxHealth))) - adjustBruteLoss(2) - visible_message("\The [src]'s [isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!") - -/mob/living/Moved(var/atom/oldloc, direct, forced, movetime) - . = ..() - handle_footstep(loc) - // Begin VOREstation edit - if(is_shifted) - is_shifted = FALSE - pixel_x = default_pixel_x - pixel_y = default_pixel_y - // End VOREstation edit - - if(pulling) // we were pulling a thing and didn't lose it during our move. - var/pull_dir = get_dir(src, pulling) - - if(pulling.anchored || !isturf(pulling.loc)) - stop_pulling() - - else if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position - // If it is too far away or across z-levels from old location, stop pulling. - if(get_dist(pulling.loc, oldloc) > 1 || pulling.loc.z != oldloc?.z) - stop_pulling() - return - - // living might take damage from drags - if(isliving(pulling)) - var/mob/living/M = pulling - M.dragged(src, oldloc) - - pulling.Move(oldloc, 0, movetime) // the pullee tries to reach our previous position - if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up - stop_pulling() - - if(!isturf(loc)) - return - else if(lastarea?.has_gravity == 0) - inertial_drift() - //VOREStation Edit Start - else if(flying) - inertial_drift() - make_floating(1) - //VOREStation Edit End - else if(!isspace(loc)) - inertia_dir = 0 - make_floating(0) - -/mob/living/proc/inertial_drift() - if(x > 1 && x < (world.maxx) && y > 1 && y < (world.maxy)) - if(Process_Spacemove(1)) - inertia_dir = 0 - return - - var/locthen = loc - spawn(5) - if(!anchored && !pulledby && loc == locthen) - var/stepdir = inertia_dir ? inertia_dir : last_move - if(!stepdir) - return - var/turf/T = get_step(src, stepdir) - if(!T) - return - Move(T, stepdir, 5) - -/mob/living/proc/handle_footstep(turf/T) - return FALSE - /mob/living/verb/resist() set name = "Resist" set category = "IC" diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 11158d89a1..eca22436bf 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -571,4 +571,74 @@ if(confused) accuracy_penalty += 45 - return accuracy_penalty \ No newline at end of file + return accuracy_penalty + +// Applies direct "cold" damage while checking protection against the cold. +/mob/living/proc/inflict_cold_damage(amount) + amount *= 1 - get_cold_protection(50) // Within spacesuit protection. + if(amount > 0) + adjustFireLoss(amount) + +// Ditto, but for "heat". +/mob/living/proc/inflict_heat_damage(amount) + amount *= 1 - get_heat_protection(10000) // Within firesuit protection. + if(amount > 0) + adjustFireLoss(amount) + +// and one for electricity because why not +/mob/living/proc/inflict_shock_damage(amount) + electrocute_act(amount, null, 1 - get_shock_protection(), pick(BP_HEAD, BP_TORSO, BP_GROIN)) + +// also one for water (most things resist it entirely, except for slimes) +/mob/living/proc/inflict_water_damage(amount) + amount *= 1 - get_water_protection() + if(amount > 0) + adjustToxLoss(amount) + +// one for abstracted away ""poison"" (mostly because simplemobs shouldn't handle reagents) +/mob/living/proc/inflict_poison_damage(amount) + if(isSynthetic()) + return + amount *= 1 - get_poison_protection() + if(amount > 0) + adjustToxLoss(amount) + +/mob/living/proc/can_inject() + return 1 + +/mob/living/proc/get_organ_target() + var/mob/shooter = src + var/t = shooter:zone_sel.selecting + if ((t in list( O_EYES, O_MOUTH ))) + t = BP_HEAD + var/obj/item/organ/external/def_zone = ran_zone(t) + return def_zone + +// heal ONE external organ, organ gets randomly selected from damaged ones. +/mob/living/proc/heal_organ_damage(var/brute, var/burn) + adjustBruteLoss(-brute) + adjustFireLoss(-burn) + src.updatehealth() + +// damage ONE external organ, organ gets randomly selected from damaged ones. +/mob/living/proc/take_organ_damage(var/brute, var/burn, var/emp=0) + if(status_flags & GODMODE) return 0 //godmode + adjustBruteLoss(brute) + adjustFireLoss(burn) + src.updatehealth() + +// heal MANY external organs, in random order +/mob/living/proc/heal_overall_damage(var/brute, var/burn) + adjustBruteLoss(-brute) + adjustFireLoss(-burn) + src.updatehealth() + +// damage MANY external organs, in random order +/mob/living/proc/take_overall_damage(var/brute, var/burn, var/used_weapon = null) + if(status_flags & GODMODE) return 0 //godmode + adjustBruteLoss(brute) + adjustFireLoss(burn) + src.updatehealth() + +/mob/living/proc/restore_all_organs() + return diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index 9407a7cb18..20d2c4a207 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -18,4 +18,302 @@ if(!n.is_safe_to_enter(src)) to_chat(src, span("warning", "\The [n] is dangerous to move into.")) return FALSE // In case any code wants to know if movement happened. - return ..() // Parent call should make the mob move. \ No newline at end of file + return ..() // Parent call should make the mob move. + +/*one proc, four uses +swapping: if it's 1, the mobs are trying to switch, if 0, non-passive is pushing passive +default behaviour is: + - non-passive mob passes the passive version + - passive mob checks to see if its mob_bump_flag is in the non-passive's mob_bump_flags + - if si, the proc returns +*/ +/mob/living/proc/can_move_mob(var/mob/living/swapped, swapping = 0, passive = 0) + if(!swapped) + return 1 + if(!passive) + return swapped.can_move_mob(src, swapping, 1) + else + var/context_flags = 0 + if(swapping) + context_flags = swapped.mob_swap_flags + else + context_flags = swapped.mob_push_flags + if(!mob_bump_flag) //nothing defined, go wild + return 1 + if(mob_bump_flag & context_flags) + return 1 + return 0 + +/mob/living/Bump(atom/movable/AM) + if(now_pushing || !loc || buckled == AM) + return + now_pushing = 1 + if (istype(AM, /mob/living)) + var/mob/living/tmob = AM + + //Even if we don't push/swap places, we "touched" them, so spread fire + spread_fire(tmob) + + for(var/mob/living/M in range(tmob, 1)) + if(tmob.pinned.len || ((M.pulling == tmob && ( tmob.restrained() && !( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, tmob.grabbed_by.len)) ) + if ( !(world.time % 5) ) + to_chat(src, "[tmob] is restrained, you cannot push past") + now_pushing = 0 + return + if( tmob.pulling == M && ( M.restrained() && !( tmob.restrained() ) && tmob.stat == 0) ) + if ( !(world.time % 5) ) + to_chat(src, "[tmob] is restraining [M], you cannot push past") + now_pushing = 0 + return + + //BubbleWrap: people in handcuffs are always switched around as if they were on 'help' intent to prevent a person being pulled from being seperated from their puller + var/can_swap = 1 + if(loc.density || tmob.loc.density) + can_swap = 0 + if(can_swap) + for(var/atom/movable/A in loc) + if(A == src) + continue + if(!A.CanPass(tmob, loc)) + can_swap = 0 + if(!can_swap) break + if(can_swap) + for(var/atom/movable/A in tmob.loc) + if(A == tmob) + continue + if(!A.CanPass(src, tmob.loc)) + can_swap = 0 + if(!can_swap) break + + //Leaping mobs just land on the tile, no pushing, no anything. + if(status_flags & LEAPING) + loc = tmob.loc + status_flags &= ~LEAPING + now_pushing = 0 + return + + if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && tmob.canmove && canmove && !tmob.buckled && !buckled && can_swap && can_move_mob(tmob, 1, 0)) // mutual brohugs all around! + var/turf/oldloc = loc + //VOREstation Edit - Begin + + //check bumpnom chance, if it's a simplemob that's doing the bumping + var/mob/living/simple_mob/srcsimp = src + if(istype(srcsimp)) + if(srcsimp.tryBumpNom(tmob)) + now_pushing = 0 + return + + //if it's a simplemob being bumped, and the above didn't make them start getting bumpnommed, they get a chance to bumpnom + var/mob/living/simple_mob/tmobsimp = tmob + if(istype(tmobsimp)) + if(tmobsimp.tryBumpNom(src)) + now_pushing = 0 + return + + //VOREstation Edit - End + forceMove(tmob.loc) + //VOREstation Edit - Begin + // In case of micros, we don't swap positions; instead occupying the same square! + if (handle_micro_bump_helping(tmob)) + now_pushing = 0 + return + // TODO - Check if we need to do something about the slime.UpdateFeed() we are skipping below. + // VOREStation Edit - End + tmob.forceMove(oldloc) + now_pushing = 0 + return + //VOREStation Edit - Begin + else if((tmob.mob_always_swap || (tmob.a_intent == I_HELP || tmob.restrained()) && (a_intent == I_HELP || src.restrained())) && canmove && can_swap && handle_micro_bump_helping(tmob)) + forceMove(tmob.loc) + now_pushing = 0 + return + //VOREStation Edit - End + + if(!can_move_mob(tmob, 0, 0)) + now_pushing = 0 + return + if(a_intent == I_HELP || src.restrained()) + now_pushing = 0 + return + // VOREStation Edit - Begin + // Plow that nerd. + if(ishuman(tmob)) + var/mob/living/carbon/human/H = tmob + if(H.species.lightweight == 1 && prob(50)) + H.visible_message("[src] bumps into [H], knocking them off balance!") + H.Weaken(5) + now_pushing = 0 + return + // Handle grabbing, stomping, and such of micros! + if(handle_micro_bump_other(tmob)) return + // VOREStation Edit - End + if(istype(tmob, /mob/living/carbon/human) && (FAT in tmob.mutations)) + if(prob(40) && !(FAT in src.mutations)) + to_chat(src, "You fail to push [tmob]'s fat ass out of the way.") + now_pushing = 0 + return + if(tmob.r_hand && istype(tmob.r_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(tmob.l_hand && istype(tmob.l_hand, /obj/item/weapon/shield/riot)) + if(prob(99)) + now_pushing = 0 + return + if(!(tmob.status_flags & CANPUSH)) + now_pushing = 0 + return + + tmob.LAssailant = src + + now_pushing = 0 + . = ..() + if (!istype(AM, /atom/movable) || AM.anchored) + //VOREStation Edit - object-specific proc for running into things + if(((confused || is_blind()) && stat == CONSCIOUS && prob(50) && m_intent=="run") || flying) + AM.stumble_into(src) + //VOREStation Edit End + /* VOREStation Removal - See above + if(confused && prob(50) && m_intent=="run") + Weaken(2) + playsound(src, "punch", 25, 1, -1) + visible_message("[src] [pick("ran", "slammed")] into \the [AM]!") + src.apply_damage(5, BRUTE) + to_chat(src, "You just [pick("ran", "slammed")] into \the [AM]!") + */ // VOREStation Removal End + return + if (!now_pushing) + if(isobj(AM)) + var/obj/I = AM + if(!can_pull_size || can_pull_size < I.w_class) + return + now_pushing = 1 + + var/t = get_dir(src, AM) + if (istype(AM, /obj/structure/window)) + for(var/obj/structure/window/win in get_step(AM,t)) + now_pushing = 0 + return + + step(AM, t) + + if(ishuman(AM) && AM:grabbed_by) + for(var/obj/item/weapon/grab/G in AM:grabbed_by) + step(G:assailant, get_dir(G:assailant, AM)) + G.adjust_position() + now_pushing = 0 + +/mob/living/CanPass(atom/movable/mover, turf/target) + if(istype(mover, /obj/structure/blob) && faction == "blob") //Blobs should ignore things on their faction. + return TRUE + return ..() + +// Called when something steps onto us. This allows for mulebots and vehicles to run things over. <3 +/mob/living/Crossed(var/atom/movable/AM) // Transplanting this from /mob/living/carbon/human/Crossed() + if(AM == src || AM.is_incorporeal()) // We're not going to run over ourselves or ghosts + return + + if(istype(AM, /mob/living/bot/mulebot)) + var/mob/living/bot/mulebot/MB = AM + MB.runOver(src) + + if(istype(AM, /obj/vehicle)) + var/obj/vehicle/V = AM + V.RunOver(src) + +// Almost all of this handles pulling movables behind us +/mob/living/Move(atom/newloc, direct, movetime) + if(buckled && buckled.loc != newloc) //not updating position + if(!buckled.anchored && buckled.buckle_movable) + return buckled.Move(newloc, direct) + else + return 0 + + var/atom/movable/pullee = pulling + // Prior to our move it's already too far away + if(pullee && get_dist(src, pullee) > 1) + stop_pulling() + // Shenanigans! Pullee closed into locker for eg. + if(pullee && !isturf(pullee.loc) && pullee.loc != loc) + stop_pulling() + // Can't pull with no hands + if(restrained()) + stop_pulling() + + // Will move our mob (probably) + . = ..() // Moved() called at this point if successful + + if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //seperated from our puller and not in the middle of a diagonal move + pulledby.stop_pulling() + + if(s_active && !(s_active in contents) && get_turf(s_active) != get_turf(src)) //check !( s_active in contents ) first so we hopefully don't have to call get_turf() so much. + s_active.close(src) + +/mob/living/proc/dragged(var/mob/living/dragger, var/oldloc) + var/area/A = get_area(src) + if(lying && !buckled && pull_damage() && A.has_gravity() && (prob(getBruteLoss() * 200 / maxHealth))) + adjustBruteLoss(2) + visible_message("\The [src]'s [isSynthetic() ? "state" : "wounds"] worsen terribly from being dragged!") + +/mob/living/Moved(var/atom/oldloc, direct, forced, movetime) + . = ..() + handle_footstep(loc) + // Begin VOREstation edit + if(is_shifted) + is_shifted = FALSE + pixel_x = default_pixel_x + pixel_y = default_pixel_y + // End VOREstation edit + + if(pulling) // we were pulling a thing and didn't lose it during our move. + var/pull_dir = get_dir(src, pulling) + + if(pulling.anchored || !isturf(pulling.loc)) + stop_pulling() + + else if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir))) // puller and pullee more than one tile away or in diagonal position + // If it is too far away or across z-levels from old location, stop pulling. + if(get_dist(pulling.loc, oldloc) > 1 || pulling.loc.z != oldloc?.z) + stop_pulling() + + // living might take damage from drags + else if(isliving(pulling)) + var/mob/living/M = pulling + M.dragged(src, oldloc) + + pulling.Move(oldloc, 0, movetime) // the pullee tries to reach our previous position + if(pulling && get_dist(src, pulling) > 1) // the pullee couldn't keep up + stop_pulling() + + if(!isturf(loc)) + return + else if(lastarea?.has_gravity == 0) + inertial_drift() + //VOREStation Edit Start + else if(flying) + inertial_drift() + make_floating(1) + //VOREStation Edit End + else if(!isspace(loc)) + inertia_dir = 0 + make_floating(0) + +/mob/living/proc/inertial_drift() + if(x > 1 && x < (world.maxx) && y > 1 && y < (world.maxy)) + if(Process_Spacemove(1)) + inertia_dir = 0 + return + + var/locthen = loc + spawn(5) + if(!anchored && !pulledby && loc == locthen) + var/stepdir = inertia_dir ? inertia_dir : last_move + if(!stepdir) + return + var/turf/T = get_step(src, stepdir) + if(!T) + return + Move(T, stepdir, 5) + +/mob/living/proc/handle_footstep(turf/T) + return FALSE diff --git a/code/modules/mob/new_player/sprite_accessories_ch.dm b/code/modules/mob/new_player/sprite_accessories_ch.dm index dd63dfdda2..a77f3081b1 100644 --- a/code/modules/mob/new_player/sprite_accessories_ch.dm +++ b/code/modules/mob/new_player/sprite_accessories_ch.dm @@ -118,6 +118,18 @@ color_blend_mode = ICON_MULTIPLY body_parts = list(BP_HEAD) + manedwolf1 + name = "Maned Wolf Primary Markings" + icon_state = "manedwolf1" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD,BP_TORSO,BP_R_ARM,BP_L_ARM,BP_R_HAND,BP_L_HAND,BP_R_LEG,BP_L_LEG,BP_R_FOOT,BP_L_FOOT) + + manedwolf2 + name = "Maned Wolf Secondary Markings" + icon_state = "manedwolf2" + color_blend_mode = ICON_MULTIPLY + body_parts = list(BP_HEAD,BP_TORSO,BP_GROIN) + /datum/sprite_accessory/tail/special/orca_tail name = "Orca Tail" desc = "" diff --git a/code/modules/multiz/structures.dm b/code/modules/multiz/ladders.dm similarity index 68% rename from code/modules/multiz/structures.dm rename to code/modules/multiz/ladders.dm index bf7f3c0865..cca3019543 100644 --- a/code/modules/multiz/structures.dm +++ b/code/modules/multiz/ladders.dm @@ -1,12 +1,8 @@ -////////////////////////////// -//Contents: Ladders, Stairs.// -////////////////////////////// - /obj/structure/ladder name = "ladder" desc = "A ladder. You can climb it up and down." icon_state = "ladder01" - icon = 'icons/obj/structures.dmi' + icon = 'icons/obj/structures/multiz.dmi' density = 0 opacity = 0 anchored = 1 @@ -125,65 +121,3 @@ /obj/structure/ladder/updown allowed_directions = UP|DOWN icon_state = "ladder11" - -/obj/structure/stairs - name = "Stairs" - desc = "Stairs leading to another deck. Not too useful if the gravity goes out." - icon = 'icons/obj/stairs.dmi' - density = 0 - opacity = 0 - anchored = 1 - flags = ON_BORDER - layer = STAIRS_LAYER - -/obj/structure/stairs/Initialize() - . = ..() - for(var/turf/turf in locs) - var/turf/simulated/open/above = GetAbove(turf) - if(!above) - warning("Stair created without level above: ([loc.x], [loc.y], [loc.z])") - return qdel(src) - if(!istype(above)) - above.ChangeTurf(/turf/simulated/open) - -/obj/structure/stairs/CheckExit(atom/movable/mover as mob|obj, turf/target as turf) - if(get_dir(loc, target) == dir && upperStep(mover.loc)) - return FALSE - . = ..() - -/obj/structure/stairs/Bumped(atom/movable/A) - // This is hackish but whatever. - var/turf/target = get_step(GetAbove(A), dir) - if(target.Enter(A, src)) // Pass src to be ignored to avoid infinate loop - A.forceMove(target) - if(isliving(A)) - var/mob/living/L = A - if(L.pulling && !L.pulling.anchored) - L.pulling.forceMove(target) - -/obj/structure/stairs/proc/upperStep(var/turf/T) - return (T == loc) - -/obj/structure/stairs/CanPass(obj/mover, turf/source, height, airflow) - return airflow || !density - -// type paths to make mapping easier. -/obj/structure/stairs/north - dir = NORTH - bound_height = 64 - bound_y = -32 - pixel_y = -32 - -/obj/structure/stairs/south - dir = SOUTH - bound_height = 64 - -/obj/structure/stairs/east - dir = EAST - bound_width = 64 - bound_x = -32 - pixel_x = -32 - -/obj/structure/stairs/west - dir = WEST - bound_width = 64 diff --git a/code/modules/multiz/structures_vr.dm b/code/modules/multiz/ladders_vr.dm similarity index 100% rename from code/modules/multiz/structures_vr.dm rename to code/modules/multiz/ladders_vr.dm diff --git a/code/modules/multiz/movement.dm b/code/modules/multiz/movement.dm index 8aa649b75f..e6fa59b2f8 100644 --- a/code/modules/multiz/movement.dm +++ b/code/modules/multiz/movement.dm @@ -358,24 +358,16 @@ for(var/atom/A in landing) if(!A.CanPass(src, src.loc, 1, 0)) return FALSE - // TODO - Stairs should operate thru a different mechanism, not falling, to allow side-bumping. // Now lets move there! if(!Move(landing)) return 1 // Detect if we made a silent landing. - if(locate(/obj/structure/stairs) in landing) - if(isliving(src)) - var/mob/living/L = src - if(L.pulling) - L.pulling.forceMove(landing) - return 1 - else - var/atom/A = find_fall_target(oldloc, landing) - if(special_fall_handle(A) || !A || !A.check_impact(src)) - return - fall_impact(A) + var/atom/A = find_fall_target(oldloc, landing) + if(special_fall_handle(A) || !A || !A.check_impact(src)) + return + fall_impact(A) /atom/movable/proc/special_fall_handle(var/atom/A) return FALSE @@ -446,14 +438,6 @@ /turf/space/check_impact(var/atom/movable/falling_atom) return FALSE -// We return 1 without calling fall_impact in order to provide a soft landing. So nice. -// Note this really should never even get this far -/obj/structure/stairs/CheckFall(var/atom/movable/falling_atom) - return TRUE - -/obj/structure/stairs/check_impact(var/atom/movable/falling_atom) - return FALSE - // Can't fall onto ghosts /mob/observer/dead/CheckFall() return FALSE diff --git a/code/modules/multiz/turf.dm b/code/modules/multiz/turf.dm index 652e86d464..360e16f4e1 100644 --- a/code/modules/multiz/turf.dm +++ b/code/modules/multiz/turf.dm @@ -55,8 +55,16 @@ GLOB.turf_entered_event.register(T, src, .proc/BelowOpenUpdated) GLOB.turf_exited_event.register(T, src, .proc/BelowOpenUpdated) -/turf/simulated/open/Entered(var/atom/movable/mover) + +/turf/simulated/open/Entered(var/atom/movable/mover, var/atom/oldloc) . = ..() + + // Going down stairs from the topstair piece + var/obj/structure/stairs/top/T = locate(/obj/structure/stairs/top) in oldloc + if(T && mover.dir == turn(T.dir, 180) && T.check_integrity()) + T.use_stairs(mover, oldloc) + return + mover.fall() /turf/simulated/open/proc/BelowOpenUpdated(turf/T, atom/movable/AM, old_loc) @@ -187,6 +195,4 @@ for(var/obj/O in contents) if(!O.CanFallThru(L, GetBelow(src))) return TRUE // Can't fall through this, like lattice or catwalk. - if(!locate(/obj/structure/stairs) in GetBelow(src)) - return FALSE // Falling on stairs is safe. - return ..() \ No newline at end of file + return ..() diff --git a/html/changelog.html b/html/changelog.html index 65e16e9e00..859fe38b43 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -53,6 +53,21 @@ -->
+

27 February 2021

+

Atermonera updated:

+ +

CHOMPStationBot updated:

+ +

19 February 2021

Woodrat updated: