diff --git a/code/datums/diseases/advance/symptoms/sensory.dm b/code/datums/diseases/advance/symptoms/sensory.dm index 1dc5a575e36..46fc14c58e5 100644 --- a/code/datums/diseases/advance/symptoms/sensory.dm +++ b/code/datums/diseases/advance/symptoms/sensory.dm @@ -90,12 +90,12 @@ Bonus if(prob(15)) M.reagents.add_reagent("morphine",rand(5,7)) if(4) - M.reagents.add_reagent_list(list("ethanol",rand(7,15),"mindbreaker",rand(5,10))) + M.reagents.add_reagent_list(list("ethanol" = rand(7,15), "mindbreaker" = rand(5,10))) M << "u can count 2 potato!" if(prob(20)) M.reagents.add_reagent("morphine",rand(5,7)) if(5) - M.reagents.add_reagent_list(list("impedrezene",rand(5,15),"ethanol",rand(7,20),"mindbreaker",rand(5,15))) + M.reagents.add_reagent_list(list("impedrezene" = rand(5,15), "ethanol" = rand(7,20), "mindbreaker" = rand(5,15))) if(prob(25)) M.reagents.add_reagent("morphine",rand(5,7)) return diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 0f35f7577f3..d266bc878a2 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -110,13 +110,6 @@ var/phase_state = "" //icon_state when phasing var/strafe = FALSE //If we are strafing - var/static/list/armour_facings = list( - "[NORTH]" = list("[SOUTH]" = FRONT_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[NORTH]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR), - "[EAST]" = list("[SOUTH]" = SIDE_ARMOUR, "[WEST]" = FRONT_ARMOUR, "[EAST]" = BACK_ARMOUR, "[NORTH]" = SIDE_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR), - "[SOUTH]" = list("[NORTH]" = FRONT_ARMOUR, "[WEST]" = SIDE_ARMOUR, "[EAST]" = SIDE_ARMOUR, "[SOUTH]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR ), - "[WEST]" = list("[NORTH]" = SIDE_ARMOUR, "[EAST]" = FRONT_ARMOUR, "[SOUTH]" = SIDE_ARMOUR, "[WEST]" = BACK_ARMOUR, "[SOUTHEAST]" = SIDE_ARMOUR, "[NORTHEAST]" = SIDE_ARMOUR, "[SOUTHWEST]" = SIDE_ARMOUR, "[NORTHWEST]" = SIDE_ARMOUR) - ) - var/occupant_sight_flags = 0 //sight flags to give to the occupant (e.g. mech mining scanner gives meson-like vision) hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD) diff --git a/code/game/mecha/mecha_defense.dm b/code/game/mecha/mecha_defense.dm index 67d656077ae..c5660af67e7 100644 --- a/code/game/mecha/mecha_defense.dm +++ b/code/game/mecha/mecha_defense.dm @@ -1,25 +1,37 @@ -/obj/mecha/proc/get_armour_facing(srcdir,adir) - var/facing_hit = armour_facings["[srcdir]"]["[adir]"] - var/damage_modifier = facing_modifiers[facing_hit] - return damage_modifier || 1 //always return non-0 +/obj/mecha/proc/get_armour_facing(relative_dir) + switch(relative_dir) + if(0) // BACKSTAB! + return facing_modifiers[BACK_ARMOUR] + if(45, 90, 270, 315) + return facing_modifiers[SIDE_ARMOUR] + if(225, 180, 135) + return facing_modifiers[FRONT_ARMOUR] + return 1 //always return non-0 -/obj/mecha/proc/take_damage(amount, type="brute", adir = 0, booster_deflection_modifier = 1, booster_damage_modifier = 1) - var/facing_modifier = 1 - if(adir) - facing_modifier = get_armour_facing(dir,adir) - - if(prob(deflect_chance * booster_deflection_modifier * facing_modifier)) +/obj/mecha/proc/take_damage(amount, type="brute", booster_deflection_modifier = 1, booster_damage_modifier = 1) + if(prob(deflect_chance * booster_deflection_modifier)) visible_message("[src]'s armour deflects the attack!") log_append_to_last("Armor saved.") - return + return 0 if(amount) var/damage = absorbDamage(amount,type) - damage = (damage/facing_modifier) * booster_damage_modifier + damage = damage * booster_damage_modifier health -= damage update_health() occupant_message("Taking damage!") log_append_to_last("Took [damage] points of damage. Damage type: \"[type]\".",1) + return 1 + + +/obj/mecha/proc/take_directional_damage(amount, type="brute", adir = 0, booster_deflection_modifier = 1, booster_damage_modifier = 1) + var/facing_modifier = get_armour_facing(dir2angle(adir) - dir2angle(src)) + + booster_damage_modifier /= facing_modifier + booster_deflection_modifier *= facing_modifier + + return take_damage(amount, type, booster_deflection_modifier, booster_damage_modifier) + /obj/mecha/proc/absorbDamage(damage,damage_type) var/coeff = 1 @@ -36,7 +48,7 @@ /obj/mecha/attack_hulk(mob/living/carbon/human/user) ..(user, 1) - take_damage(15, "brute", user.dir) + take_directional_damage(15, "brute", get_dir(src, user)) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) user.visible_message("[user] hits [name]. The metal creaks and bends.") @@ -56,7 +68,7 @@ log_message("Attack by alien. Attacker - [user].",1) user.changeNext_move(CLICK_CD_MELEE) //Now stompy alien killer mechs are actually scary to aliens! user.do_attack_animation(src) - take_damage(15, "brute", user.dir) + take_directional_damage(15, "brute", get_dir(src, user)) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) playsound(loc, 'sound/weapons/slash.ogg', 50, 1, -1) visible_message("The [user] slashes at [name]'s armor!") @@ -69,7 +81,7 @@ else user.do_attack_animation(src) var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) - take_damage(damage, "brute", user.dir) + take_directional_damage(damage, "brute", get_dir(src, user)) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) visible_message("[user] [user.attacktext] [src]!") add_logs(user, src, "attacked") @@ -100,7 +112,7 @@ var/obj/O = A if(O.throwforce) visible_message("[name] is hit by [A].") - take_damage(O.throwforce, "brute", 0, deflection, dam_coeff) + take_directional_damage(O.throwforce, "brute", get_dir(src, A), deflection, dam_coeff) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) return @@ -116,8 +128,8 @@ break if((Proj.damage_type == BRUTE || Proj.damage_type == BURN)) - take_damage(Proj.damage*dam_coeff,Proj.flag, Proj.dir, deflection, dam_coeff) visible_message("[name] is hit by [Proj].") + take_directional_damage(Proj.damage*dam_coeff,Proj.flag, turn(Proj.dir, 180), deflection, dam_coeff) check_for_internal_damage(list(MECHA_INT_FIRE,MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST,MECHA_INT_SHORT_CIRCUIT)) Proj.on_hit(src) @@ -144,8 +156,7 @@ return /obj/mecha/blob_act(obj/effect/blob/B) - take_damage(30, "brute") - return + take_directional_damage(30, "brute", get_dir(src, B)) /obj/mecha/emp_act(severity) if(get_charge()) @@ -296,7 +307,7 @@ log_append_to_last("Armor saved.") else user.visible_message("[user] hits [src] with [I].", "You hit [src] with [I].") - take_damage(round(I.force*dam_coeff),I.damtype) + take_directional_damage(round(I.force*dam_coeff),I.damtype, get_dir(src, user)) check_for_internal_damage(list(MECHA_INT_TEMP_CONTROL,MECHA_INT_TANK_BREACH,MECHA_INT_CONTROL_LOST)) @@ -320,6 +331,6 @@ else return visible_message("[M.name] has hit [src].") - take_damage(M.force, damtype, M.dir) + take_directional_damage(M.force, damtype, get_dir(src, M)) add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])") return \ No newline at end of file diff --git a/code/game/objects/effects/portals.dm b/code/game/objects/effects/portals.dm index b1776e58c52..98579eb7473 100644 --- a/code/game/objects/effects/portals.dm +++ b/code/game/objects/effects/portals.dm @@ -15,23 +15,31 @@ var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent /obj/effect/portal/Bumped(mob/M as mob|obj) - src.teleport(M) + teleport(M) -/obj/effect/portal/New(loc, turf/target, creator, lifespan=300) +/obj/effect/portal/attack_hand(mob/user) + if(Adjacent(user)) + teleport(user) + +/obj/effect/portal/attackby(obj/item/weapon/W, mob/user, params) + if(user && Adjacent(user)) + teleport(user) + + + +/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300) + ..() portals += src - src.loc = loc src.target = target src.creator = creator - var/area/A = target.loc - if(A.noteleport) // No point in persisting if the target is unreachable. + + var/area/A = get_area(target) + if(A && A.noteleport) // No point in persisting if the target is unreachable. qdel(src) return - for(var/mob/M in src.loc) - src.teleport(M) if(lifespan > 0) spawn(lifespan) qdel(src) - return /obj/effect/portal/Destroy() portals -= src diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index eaad0d76502..7f25dbfe5e9 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -304,6 +304,11 @@ return if(cyborg && (cyborg.stat != DEAD) && on) + if(!cyborg.cell) + cyborg << "Self-repair module deactivated. Please, insert the power cell." + deactivate() + return + if(cyborg.cell.charge < powercost * 2) cyborg << "Self-repair module deactivated. Please recharge." deactivate() diff --git a/code/modules/hydroponics/grown/replicapod.dm b/code/modules/hydroponics/grown/replicapod.dm index f421032ecc2..2fc857d23c4 100644 --- a/code/modules/hydroponics/grown/replicapod.dm +++ b/code/modules/hydroponics/grown/replicapod.dm @@ -108,6 +108,6 @@ seed_count++ for(var/i=0,iYou remove the dead plant from [src]." diff --git a/code/modules/hydroponics/plant_genes.dm b/code/modules/hydroponics/plant_genes.dm index c1edd43e2c1..a946ed11e82 100644 --- a/code/modules/hydroponics/plant_genes.dm +++ b/code/modules/hydroponics/plant_genes.dm @@ -141,18 +141,19 @@ return TRUE /datum/plant_gene/trait/proc/on_new(obj/item/weapon/reagent_containers/food/snacks/grown/G, newloc) - if(origin_tech) // This ugly code segment adds RnD tech levels to resulting plants. - if(G.origin_tech) - var/list/tech = params2list(G.origin_tech) - for(var/t in origin_tech) - if(t in tech) - tech[t] = max(tech[t], origin_tech[t]) - else - tech[t] = origin_tech[t] - G.origin_tech = list2params(tech) - else - G.origin_tech = list2params(origin_tech) - return + if(!origin_tech) // This ugly code segment adds RnD tech levels to resulting plants. + return + + if(G.origin_tech) + var/list/tech = params2list(G.origin_tech) + for(var/t in origin_tech) + if(t in tech) + tech[t] = max(text2num(tech[t]), origin_tech[t]) + else + tech[t] = origin_tech[t] + G.origin_tech = list2params(tech) + else + G.origin_tech = list2params(origin_tech) /datum/plant_gene/trait/proc/on_consume(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) return @@ -171,7 +172,7 @@ // For code, see grown.dm name = "Liquid Contents" examine_line = "It has a lot of liquid contents inside." - origin_tech = list("bio" = 5) + origin_tech = list("biotech" = 5) /*/datum/plant_gene/trait/squash/on_slip(obj/item/weapon/reagent_containers/food/snacks/grown/G, mob/living/carbon/target) G.squash(target)*/ diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm index 214886607ec..e3e179721fa 100644 --- a/code/modules/mob/inventory.dm +++ b/code/modules/mob/inventory.dm @@ -109,14 +109,14 @@ //Drops the item in our left hand /mob/proc/drop_l_hand() - if(!loc.allow_drop()) + if(!loc || !loc.allow_drop()) return return unEquip(l_hand) //All needed checks are in unEquip //Drops the item in our right hand /mob/proc/drop_r_hand() - if(!loc.allow_drop()) + if(!loc || !loc.allow_drop()) return return unEquip(r_hand) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index a8e0d681084..8f1dc21f2cc 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -176,7 +176,7 @@ fire_rain() icon_state = "dragon" - if(swoop_target) + if(swoop_target && !qdeleted(swoop_target)) tturf = get_turf(swoop_target) else tturf = get_turf(src) @@ -185,18 +185,18 @@ animate(src, pixel_x = 0, pixel_z = 0, time = 10) sleep(10) playsound(src.loc, 'sound/effects/meteorimpact.ogg', 200, 1) - for(var/mob/living/L in range(1,tturf)) - if(L == src) - continue + for(var/mob/living/L in orange(1, src)) if(L.stat) visible_message("[src] slams down on [L], crushing them!") L.gib() else - var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src))) L.adjustBruteLoss(75) - L.throw_at_fast(throwtarget) - visible_message("[L] is thrown clear of [src]!") - for(var/mob/M in range(7,src)) + if(L && !qdeleted(L)) // Some mobs are deleted on death + var/throwtarget = get_edge_target_turf(src, get_dir(src, get_step_away(L, src))) + L.throw_at_fast(throwtarget) + visible_message("[L] is thrown clear of [src]!") + + for(var/mob/M in range(7, src)) shake_camera(M, 15, 1) stop_automated_movement = FALSE diff --git a/code/modules/reagents/reagent_containers/borghydro.dm b/code/modules/reagents/reagent_containers/borghydro.dm index 2fe2fb90f66..43454906259 100644 --- a/code/modules/reagents/reagent_containers/borghydro.dm +++ b/code/modules/reagents/reagent_containers/borghydro.dm @@ -98,8 +98,11 @@ Borg Hypospray if(M.reagents) var/trans = R.trans_to(M, amount_per_transfer_from_this) user << "[trans] unit\s injected. [R.total_volume] unit\s remaining." - var/contained = english_list(R) - add_logs(user, M, "injected", src, "(CHEMICALS: [contained])") + + var/list/injected = list() + for(var/datum/reagent/RG in R.reagent_list) + injected += RG.name + add_logs(user, M, "injected", src, "(CHEMICALS: [english_list(injected)])") /obj/item/weapon/reagent_containers/borghypo/attack_self(mob/user) var/chosen_reagent = modes[input(user, "What reagent do you want to dispense?") as null|anything in reagent_ids]