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]