diff --git a/code/_onclick/item_attack.dm b/code/_onclick/item_attack.dm index 4c0eeccf1d..de1dfdbf67 100644 --- a/code/_onclick/item_attack.dm +++ b/code/_onclick/item_attack.dm @@ -44,8 +44,8 @@ else if(hitsound) playsound(loc, hitsound, get_clamped_volume(), 1, -1) - user.lastattacked = M - M.lastattacker = user + M.lastattacker = user.real_name + M.lastattackerckey = user.ckey user.do_attack_animation(M) M.attacked_by(src, user) diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index 56238d5b85..fe7cf33070 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -191,12 +191,8 @@ SUBSYSTEM_DEF(blackbox) var/sqljob = sanitizeSQL(L.mind.assigned_role) var/sqlspecial = sanitizeSQL(L.mind.special_role) var/sqlpod = sanitizeSQL(placeofdeath.name) - var/laname - var/lakey - if(L.lastattacker && ismob(L.lastattacker)) - var/mob/LA = L.lastattacker - laname = sanitizeSQL(LA.real_name) - lakey = sanitizeSQL(LA.key) + var/laname = sanitizeSQL(L.lastattacker) + var/lakey = sanitizeSQL(L.lastattackerckey) var/sqlbrute = sanitizeSQL(L.getBruteLoss()) var/sqlfire = sanitizeSQL(L.getFireLoss()) var/sqlbrain = sanitizeSQL(L.getBrainLoss()) diff --git a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm index e1c2f43c0f..3a7f99bc8a 100644 --- a/code/game/gamemodes/miniantags/abduction/abduction_gear.dm +++ b/code/game/gamemodes/miniantags/abduction/abduction_gear.dm @@ -417,8 +417,9 @@ Congratulations! You are now trained for invasive xenobiology research!"} toggle(user) /obj/item/abductor_baton/proc/StunAttack(mob/living/L,mob/living/user) - user.lastattacked = L - L.lastattacker = user + + L.lastattacker = user.real_name + L.lastattackerckey = user.ckey L.Knockdown(140) L.apply_effect(STUTTER, 7) diff --git a/code/game/objects/items/stunbaton.dm b/code/game/objects/items/stunbaton.dm index ef2af5381b..92d00d9e2d 100644 --- a/code/game/objects/items/stunbaton.dm +++ b/code/game/objects/items/stunbaton.dm @@ -1,202 +1,202 @@ -/obj/item/melee/baton - name = "stunbaton" - desc = "A stun baton for incapacitating people with." - icon_state = "stunbaton" - item_state = "baton" - lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' - righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' - slot_flags = SLOT_BELT - force = 10 - throwforce = 7 - w_class = WEIGHT_CLASS_NORMAL - origin_tech = "combat=2" - attack_verb = list("beaten") - armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 80, acid = 80) - - var/stunforce = 140 - var/status = 0 - var/obj/item/stock_parts/cell/high/cell - var/hitcost = 1000 - var/throw_hit_chance = 35 - -/obj/item/melee/baton/get_cell() - return cell - -/obj/item/melee/baton/suicide_act(mob/user) - user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!") - return (FIRELOSS) - -/obj/item/melee/baton/Initialize() - . = ..() - update_icon() - -/obj/item/melee/baton/throw_impact(atom/hit_atom) - ..() - //Only mob/living types have stun handling - if(status && prob(throw_hit_chance) && iscarbon(hit_atom)) - baton_stun(hit_atom) - -/obj/item/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed. - cell = new(src) - update_icon() - . = ..() - -/obj/item/melee/baton/proc/deductcharge(chrgdeductamt) - if(cell) - //Note this value returned is significant, as it will determine - //if a stun is applied or not - . = cell.use(chrgdeductamt) - if(status && cell.charge < hitcost) - //we're below minimum, turn off - status = 0 - update_icon() - playsound(loc, "sparks", 75, 1, -1) - - -/obj/item/melee/baton/update_icon() - if(status) - icon_state = "[initial(name)]_active" - else if(!cell) - icon_state = "[initial(name)]_nocell" - else - icon_state = "[initial(name)]" - -/obj/item/melee/baton/examine(mob/user) - ..() - if(cell) - to_chat(user, "The baton is [round(cell.percent())]% charged.") - else - to_chat(user, "The baton does not have a power source installed.") - -/obj/item/melee/baton/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/stock_parts/cell)) - var/obj/item/stock_parts/cell/C = W - if(cell) - to_chat(user, "[src] already has a cell.") - else - if(C.maxcharge < hitcost) - to_chat(user, "[src] requires a higher capacity cell.") - return - if(!user.transferItemToLoc(W, src)) - return - cell = W - to_chat(user, "You install a cell in [src].") - update_icon() - - else if(istype(W, /obj/item/screwdriver)) - if(cell) - cell.update_icon() - cell.forceMove(get_turf(src)) - cell = null - to_chat(user, "You remove the cell from [src].") - status = 0 - update_icon() - else - return ..() - -/obj/item/melee/baton/attack_self(mob/user) - if(cell && cell.charge > hitcost) - status = !status - to_chat(user, "[src] is now [status ? "on" : "off"].") - playsound(loc, "sparks", 75, 1, -1) - else - status = 0 - if(!cell) - to_chat(user, "[src] does not have a power source!") - else - to_chat(user, "[src] is out of charge.") - update_icon() - add_fingerprint(user) - -/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user) - if(status && user.disabilities & CLUMSY && prob(50)) - user.visible_message("[user] accidentally hits themself with [src]!", \ - "You accidentally hit yourself with [src]!") - user.Knockdown(stunforce*3) - deductcharge(hitcost) - return - - if(iscyborg(M)) - ..() - return - - - if(ishuman(M)) - var/mob/living/carbon/human/L = M - if(check_martial_counter(L, user)) - return - - if(user.a_intent != INTENT_HARM) - if(status) - if(baton_stun(M, user)) - user.do_attack_animation(M) - return - else - M.visible_message("[user] has prodded [M] with [src]. Luckily it was off.", \ - "[user] has prodded you with [src]. Luckily it was off") - else - if(status) - baton_stun(M, user) - ..() - - -/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user) - if(ishuman(L)) - var/mob/living/carbon/human/H = L - if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that - playsound(L, 'sound/weapons/genhit.ogg', 50, 1) - return 0 - if(iscyborg(loc)) - var/mob/living/silicon/robot/R = loc - if(!R || !R.cell || !R.cell.use(hitcost)) - return 0 - else - if(!deductcharge(hitcost)) - return 0 - - L.Knockdown(stunforce) - L.apply_effect(STUTTER, stunforce) - if(user) - user.lastattacked = L - L.lastattacker = user - L.visible_message("[user] has stunned [L] with [src]!", \ - "[user] has stunned you with [src]!") - add_logs(user, L, "stunned") - - playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) - - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.forcesay(GLOB.hit_appends) - - - return 1 - -/obj/item/melee/baton/emp_act(severity) - deductcharge(1000 / severity) - ..() - -//Makeshift stun baton. Replacement for stun gloves. -/obj/item/melee/baton/cattleprod - name = "stunprod" - desc = "An improvised stun baton." - icon_state = "stunprod_nocell" - item_state = "prod" - lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' - righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' - w_class = WEIGHT_CLASS_BULKY - force = 3 - throwforce = 5 - stunforce = 100 - hitcost = 2000 - throw_hit_chance = 10 - slot_flags = SLOT_BACK - var/obj/item/device/assembly/igniter/sparkler = 0 - -/obj/item/melee/baton/cattleprod/Initialize() - . = ..() - sparkler = new (src) - -/obj/item/melee/baton/cattleprod/baton_stun() - if(sparkler.activate()) - ..() +/obj/item/melee/baton + name = "stunbaton" + desc = "A stun baton for incapacitating people with." + icon_state = "stunbaton" + item_state = "baton" + lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi' + slot_flags = SLOT_BELT + force = 10 + throwforce = 7 + w_class = WEIGHT_CLASS_NORMAL + origin_tech = "combat=2" + attack_verb = list("beaten") + armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 50, bio = 0, rad = 0, fire = 80, acid = 80) + + var/stunforce = 140 + var/status = 0 + var/obj/item/stock_parts/cell/high/cell + var/hitcost = 1000 + var/throw_hit_chance = 35 + +/obj/item/melee/baton/get_cell() + return cell + +/obj/item/melee/baton/suicide_act(mob/user) + user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!") + return (FIRELOSS) + +/obj/item/melee/baton/Initialize() + . = ..() + update_icon() + +/obj/item/melee/baton/throw_impact(atom/hit_atom) + ..() + //Only mob/living types have stun handling + if(status && prob(throw_hit_chance) && iscarbon(hit_atom)) + baton_stun(hit_atom) + +/obj/item/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed. + cell = new(src) + update_icon() + . = ..() + +/obj/item/melee/baton/proc/deductcharge(chrgdeductamt) + if(cell) + //Note this value returned is significant, as it will determine + //if a stun is applied or not + . = cell.use(chrgdeductamt) + if(status && cell.charge < hitcost) + //we're below minimum, turn off + status = 0 + update_icon() + playsound(loc, "sparks", 75, 1, -1) + + +/obj/item/melee/baton/update_icon() + if(status) + icon_state = "[initial(name)]_active" + else if(!cell) + icon_state = "[initial(name)]_nocell" + else + icon_state = "[initial(name)]" + +/obj/item/melee/baton/examine(mob/user) + ..() + if(cell) + to_chat(user, "The baton is [round(cell.percent())]% charged.") + else + to_chat(user, "The baton does not have a power source installed.") + +/obj/item/melee/baton/attackby(obj/item/W, mob/user, params) + if(istype(W, /obj/item/stock_parts/cell)) + var/obj/item/stock_parts/cell/C = W + if(cell) + to_chat(user, "[src] already has a cell.") + else + if(C.maxcharge < hitcost) + to_chat(user, "[src] requires a higher capacity cell.") + return + if(!user.transferItemToLoc(W, src)) + return + cell = W + to_chat(user, "You install a cell in [src].") + update_icon() + + else if(istype(W, /obj/item/screwdriver)) + if(cell) + cell.update_icon() + cell.forceMove(get_turf(src)) + cell = null + to_chat(user, "You remove the cell from [src].") + status = 0 + update_icon() + else + return ..() + +/obj/item/melee/baton/attack_self(mob/user) + if(cell && cell.charge > hitcost) + status = !status + to_chat(user, "[src] is now [status ? "on" : "off"].") + playsound(loc, "sparks", 75, 1, -1) + else + status = 0 + if(!cell) + to_chat(user, "[src] does not have a power source!") + else + to_chat(user, "[src] is out of charge.") + update_icon() + add_fingerprint(user) + +/obj/item/melee/baton/attack(mob/M, mob/living/carbon/human/user) + if(status && user.disabilities & CLUMSY && prob(50)) + user.visible_message("[user] accidentally hits themself with [src]!", \ + "You accidentally hit yourself with [src]!") + user.Knockdown(stunforce*3) + deductcharge(hitcost) + return + + if(iscyborg(M)) + ..() + return + + + if(ishuman(M)) + var/mob/living/carbon/human/L = M + if(check_martial_counter(L, user)) + return + + if(user.a_intent != INTENT_HARM) + if(status) + if(baton_stun(M, user)) + user.do_attack_animation(M) + return + else + M.visible_message("[user] has prodded [M] with [src]. Luckily it was off.", \ + "[user] has prodded you with [src]. Luckily it was off") + else + if(status) + baton_stun(M, user) + ..() + + +/obj/item/melee/baton/proc/baton_stun(mob/living/L, mob/user) + if(ishuman(L)) + var/mob/living/carbon/human/H = L + if(H.check_shields(src, 0, "[user]'s [name]", MELEE_ATTACK)) //No message; check_shields() handles that + playsound(L, 'sound/weapons/genhit.ogg', 50, 1) + return 0 + if(iscyborg(loc)) + var/mob/living/silicon/robot/R = loc + if(!R || !R.cell || !R.cell.use(hitcost)) + return 0 + else + if(!deductcharge(hitcost)) + return 0 + + L.Knockdown(stunforce) + L.apply_effect(STUTTER, stunforce) + if(user) + L.lastattacker = user.real_name + L.lastattackerckey = user.ckey + L.visible_message("[user] has stunned [L] with [src]!", \ + "[user] has stunned you with [src]!") + add_logs(user, L, "stunned") + + playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1) + + if(ishuman(L)) + var/mob/living/carbon/human/H = L + H.forcesay(GLOB.hit_appends) + + + return 1 + +/obj/item/melee/baton/emp_act(severity) + deductcharge(1000 / severity) + ..() + +//Makeshift stun baton. Replacement for stun gloves. +/obj/item/melee/baton/cattleprod + name = "stunprod" + desc = "An improvised stun baton." + icon_state = "stunprod_nocell" + item_state = "prod" + lefthand_file = 'icons/mob/inhands/weapons/melee_lefthand.dmi' + righthand_file = 'icons/mob/inhands/weapons/melee_righthand.dmi' + w_class = WEIGHT_CLASS_BULKY + force = 3 + throwforce = 5 + stunforce = 100 + hitcost = 2000 + throw_hit_chance = 10 + slot_flags = SLOT_BACK + var/obj/item/device/assembly/igniter/sparkler = 0 + +/obj/item/melee/baton/cattleprod/Initialize() + . = ..() + sparkler = new (src) + +/obj/item/melee/baton/cattleprod/baton_stun() + if(sparkler.activate()) + ..() diff --git a/code/game/objects/structures/manned_turret.dm b/code/game/objects/structures/manned_turret.dm index 70176ede53..669abb792a 100644 --- a/code/game/objects/structures/manned_turret.dm +++ b/code/game/objects/structures/manned_turret.dm @@ -201,8 +201,8 @@ O.attacked_by(src, user) /obj/item/gun_control/attack(mob/living/M, mob/living/user) - user.lastattacked = M - M.lastattacker = user + M.lastattacker = user.real_name + M.lastattackerckey = user.ckey M.attacked_by(src, user) add_fingerprint(user) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 6becdb3ddd..6d9630cb56 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -27,8 +27,9 @@ var/damageoverlaytemp = 0 var/computer_id = null var/lastattacker = null - var/lastattacked = null - var/list/logging = list(INDIVIDUAL_ATTACK_LOG, INDIVIDUAL_SAY_LOG, INDIVIDUAL_EMOTE_LOG, INDIVIDUAL_OOC_LOG, INDIVIDUAL_LOOC_LOG) + var/lastattackerckey = null + var/list/logging = list(INDIVIDUAL_ATTACK_LOG, INDIVIDUAL_SAY_LOG, INDIVIDUAL_EMOTE_LOG, INDIVIDUAL_OOC_LOG) + var/obj/machinery/machine = null var/other_mobs = null var/disabilities = 0 //Carbon