diff --git a/code/modules/admin/verbs/select_equipment.dm b/code/modules/admin/verbs/select_equipment.dm index 83a9cb1a06..8e6f445b87 100644 --- a/code/modules/admin/verbs/select_equipment.dm +++ b/code/modules/admin/verbs/select_equipment.dm @@ -131,7 +131,7 @@ arm_equipment(M, dresscode, FALSE, count_participant) if(!no_logs) message_admins("[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].") - return + return TRUE /client/proc/cmd_admin_dress_all() set category = "Debug" diff --git a/code/modules/mob/living/carbon/human/ai/ai_equipment.dm b/code/modules/mob/living/carbon/human/ai/ai_equipment.dm index be27f6be54..23b88c4858 100644 --- a/code/modules/mob/living/carbon/human/ai/ai_equipment.dm +++ b/code/modules/mob/living/carbon/human/ai/ai_equipment.dm @@ -16,6 +16,15 @@ //new_human.equip_to_slot_or_del(new /obj/item/storage/belt/shotgun/full/random(new_human), WEAR_WAIST) //new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/shotgun/pump/dual_tube/cmb(new_human), WEAR_BACK) + + //new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/general_belt(new_human), WEAR_WAIST) + //new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/flamer_tank(new_human), WEAR_IN_BELT) + //new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/flamer(new_human), WEAR_BACK) + + //new_human.equip_to_slot_or_del(new /obj/item/storage/backpack/general_belt(new_human), WEAR_WAIST) + //new_human.equip_to_slot_or_del(new /obj/item/ammo_magazine/rocket/anti_tank(new_human), WEAR_IN_BELT) + //new_human.equip_to_slot_or_del(new /obj/item/weapon/gun/launcher/rocket/anti_tank(new_human), WEAR_R_HAND) + new_human.equip_to_slot_or_del(new /obj/item/storage/belt/marine(new_human), WEAR_WAIST) if(prob(50)) spawn_rebel_smg(new_human) @@ -23,3 +32,7 @@ spawn_rebel_rifle(new_human) new_human.equip_to_slot_or_del(new /obj/item/device/radio/headset/distress/CLF(new_human), WEAR_L_EAR) + +/datum/equipment_preset/clf/soldier/ai/load_preset(mob/living/carbon/human/new_human, randomise, count_participant, client/mob_client, show_job_gear) + . = ..() + new_human.ai_brain?.appraise_inventory() diff --git a/code/modules/mob/living/carbon/human/ai/ai_management_menu.dm b/code/modules/mob/living/carbon/human/ai/ai_management_menu.dm index c6ed91af77..72370982df 100644 --- a/code/modules/mob/living/carbon/human/ai/ai_management_menu.dm +++ b/code/modules/mob/living/carbon/human/ai/ai_management_menu.dm @@ -135,5 +135,7 @@ return var/mob/living/carbon/human/ai/ai_human = new() - cmd_admin_dress_human(ai_human) + if(!cmd_admin_dress_human(ai_human)) + qdel(ai_human) + return ai_human.forceMove(get_turf(mob)) diff --git a/code/modules/mob/living/carbon/human/ai/brain/ai_brain.dm b/code/modules/mob/living/carbon/human/ai/brain/ai_brain.dm index 2e791e7c53..b77429dd3a 100644 --- a/code/modules/mob/living/carbon/human/ai/brain/ai_brain.dm +++ b/code/modules/mob/living/carbon/human/ai/brain/ai_brain.dm @@ -92,9 +92,11 @@ GLOBAL_LIST_EMPTY(human_ai_brains) if(!currently_busy && primary_weapon && current_target && !currently_firing && COOLDOWN_FINISHED(src, fire_overload_cooldown) && primary_weapon.has_ammunition()) currently_busy = TRUE - if(get_dist(tied_human, current_target) > gun_data.maximum_range) + var/target_futile = current_target.is_mob_incapacitated() + if(get_dist(tied_human, current_target) > gun_data.optimal_range || target_futile) if(!has_ongoing_action(/datum/ongoing_action/approach_target) && !in_cover) - ADD_ONGOING_ACTION(src, /datum/ongoing_action/approach_target, current_target, gun_data.maximum_range) + var/walk_distance = target_futile ? gun_data.minimum_range : gun_data.optimal_range + ADD_ONGOING_ACTION(src, /datum/ongoing_action/approach_target, current_target, walk_distance) attack_target() if(!currently_busy && healing_start_check()) @@ -294,6 +296,8 @@ GLOBAL_LIST_EMPTY(human_ai_brains) if(firer?.faction in neutral_factions) on_neutral_faction_betray(firer.faction) + if(!faction_check(firer)) + current_target = firer /datum/human_ai_brain/proc/on_neutral_faction_betray(faction) if(!tied_human.faction) diff --git a/code/modules/mob/living/carbon/human/ai/brain/ai_brain_items.dm b/code/modules/mob/living/carbon/human/ai/brain/ai_brain_items.dm index 2cddf0a4d7..c6af584f79 100644 --- a/code/modules/mob/living/carbon/human/ai/brain/ai_brain_items.dm +++ b/code/modules/mob/living/carbon/human/ai/brain/ai_brain_items.dm @@ -116,7 +116,7 @@ tried_reload = FALSE // We don't really need to do this in a smart way if(belt) - if(!istype(tied_human.belt, /obj/item/storage/belt)) + if(!istype(tied_human.belt, /obj/item/storage)) // belts can be backpacks, don't ask return for(var/id in equipment_map) diff --git a/code/modules/mob/living/carbon/human/ai/brain/ai_brain_targeting.dm b/code/modules/mob/living/carbon/human/ai/brain/ai_brain_targeting.dm index 4b09ccb904..81d654bde7 100644 --- a/code/modules/mob/living/carbon/human/ai/brain/ai_brain_targeting.dm +++ b/code/modules/mob/living/carbon/human/ai/brain/ai_brain_targeting.dm @@ -140,32 +140,21 @@ primary_weapon.wield_time = world.time primary_weapon.pull_time = world.time + tied_human.face_atom(current_target) + if(get_dist(tied_human, current_target) > gun_data.maximum_range) currently_busy = FALSE return primary_weapon.set_target(current_target) - ensure_primary_hand(primary_weapon) - if(primary_weapon.flags_item & TWOHANDED && !(primary_weapon.flags_item & WIELDED)) - primary_weapon.wield(tied_human) - sleep(max(primary_weapon.wield_delay, short_action_delay * action_delay_mult)) - if(istype(primary_weapon, /obj/item/weapon/gun/shotgun/pump) && !primary_weapon.in_chamber) - var/obj/item/weapon/gun/shotgun/pump/shotgun = primary_weapon - shotgun.pump_shotgun(tied_human) - shotgun.recent_pump = world.time - else if(istype(primary_weapon, /obj/item/weapon/gun/boltaction) && !primary_weapon.in_chamber) - var/obj/item/weapon/gun/boltaction/bolt = primary_weapon - bolt.unique_action(tied_human) - bolt.recent_cycle = world.time - bolt.unique_action(tied_human) - bolt.recent_cycle = world.time - if(!primary_weapon.in_chamber || !friendly_check()) + gun_data.before_fire(primary_weapon, tied_human, src) + if(!primary_weapon.current_mag || !primary_weapon.current_mag.current_rounds || !friendly_check()) end_gun_fire() return currently_firing = TRUE enter_combat() - RegisterSignal(tied_human, COMSIG_MOB_FIRED_GUN, PROC_REF(on_gun_fire)) + RegisterSignal(tied_human, COMSIG_MOB_FIRED_GUN, PROC_REF(on_gun_fire), TRUE) primary_weapon.start_fire(object = current_target, bypass_checks = TRUE) /datum/human_ai_brain/proc/friendly_check() @@ -216,7 +205,7 @@ end_gun_fire() return - if(primary_weapon.current_mag?.current_rounds <= 0) + if(primary_weapon.current_mag?.current_rounds <= 1) // bullet removal comes after comsig is triggered end_gun_fire() return @@ -244,6 +233,7 @@ addtimer(CALLBACK(primary_weapon, TYPE_PROC_REF(/obj/item/weapon/gun, start_fire), null, current_target, null, null, null, TRUE), primary_weapon.get_fire_delay()) target_floor = get_turf(current_target) + tied_human.face_atom(target_floor) /datum/human_ai_brain/proc/end_gun_fire() primary_weapon?.set_target(null) diff --git a/code/modules/mob/living/carbon/human/ai/firearm_appraisal.dm b/code/modules/mob/living/carbon/human/ai/firearm_appraisal.dm index 85caacba45..5d484c8902 100644 --- a/code/modules/mob/living/carbon/human/ai/firearm_appraisal.dm +++ b/code/modules/mob/living/carbon/human/ai/firearm_appraisal.dm @@ -8,14 +8,24 @@ GLOBAL_LIST_INIT_TYPED(firearm_appraisals, /datum/firearm_appraisal, build_firea /datum/firearm_appraisal /// Minimum engagement range with weapon type - var/minimum_range = 0 - /// Maximum engagement range - var/maximum_range = 7 + var/minimum_range = 1 + /// Optimal engagement range, try to approach if further than this + var/optimal_range = 6 + /// Maximum engagement range, stop firing at this distance + var/maximum_range = 9 /// How many rounds to fire in 1 burst at most var/burst_amount_max = 8 /// List of types that set the human AI to this appraisal type var/list/gun_types = list() +/// List of things we do before our next fire based on weapon type +/datum/firearm_appraisal/proc/before_fire(obj/item/weapon/gun/firearm, mob/living/carbon/user, datum/human_ai_brain/AI) + SHOULD_CALL_PARENT(TRUE) // Every weapon can be twohanded + AI.ensure_primary_hand(firearm) + if((firearm.flags_item & TWOHANDED) && !(firearm.flags_item & WIELDED)) + firearm.wield(user) + sleep(max(firearm.wield_delay, AI.short_action_delay * AI.action_delay_mult)) + /datum/firearm_appraisal/rifle burst_amount_max = 8 gun_types = list( @@ -24,14 +34,59 @@ GLOBAL_LIST_INIT_TYPED(firearm_appraisals, /datum/firearm_appraisal, build_firea /datum/firearm_appraisal/smg burst_amount_max = 10 - maximum_range = 6 + optimal_range = 5 + maximum_range = 7 gun_types = list( /obj/item/weapon/gun/smg, ) /datum/firearm_appraisal/shotgun burst_amount_max = 2 + optimal_range = 1 // point-blank our beloved maximum_range = 3 gun_types = list( /obj/item/weapon/gun/shotgun, ) + +/datum/firearm_appraisal/shotgun/before_fire(obj/item/weapon/gun/shotgun/pump/firearm, mob/living/carbon/user, datum/human_ai_brain/AI) + . = ..() + if(firearm.in_chamber) + return + firearm.unique_action(user) + firearm.recent_pump = world.time + +/datum/firearm_appraisal/boltaction + gun_types = list( + /obj/item/weapon/gun/boltaction, + ) + +/datum/firearm_appraisal/boltaction/before_fire(obj/item/weapon/gun/boltaction/firearm, mob/living/carbon/user, datum/human_ai_brain/AI) + . = ..() + if(firearm.in_chamber) + return + firearm.unique_action(user) + firearm.recent_cycle = world.time + firearm.unique_action(user) + firearm.recent_cycle = world.time + +/datum/firearm_appraisal/flamer + burst_amount_max = 1 + minimum_range = 5 // To not try and walk into our flames in tight spaces + optimal_range = 5 + maximum_range = 5 + gun_types = list( + /obj/item/weapon/gun/flamer, + ) + +/datum/firearm_appraisal/flamer/before_fire(obj/item/weapon/gun/flamer/firearm, mob/living/carbon/user, datum/human_ai_brain/AI) + . = ..() + if(firearm.flags_gun_features & GUN_TRIGGER_SAFETY) + firearm.flags_gun_features ^= GUN_TRIGGER_SAFETY + firearm.gun_safety_handle(user) + +/datum/firearm_appraisal/rpg + minimum_range = 5 + optimal_range = 6 + gun_types = list( + /obj/item/weapon/gun/launcher/rocket, + ) diff --git a/code/modules/projectiles/guns/flamer/flamer.dm b/code/modules/projectiles/guns/flamer/flamer.dm index 634807805a..d9574c70b3 100644 --- a/code/modules/projectiles/guns/flamer/flamer.dm +++ b/code/modules/projectiles/guns/flamer/flamer.dm @@ -143,6 +143,8 @@ else user.track_shot(initial(name)) unleash_flame(target, user) + current_mag.current_rounds = current_mag.get_ammo_percent() + SEND_SIGNAL(user, COMSIG_MOB_FIRED_GUN, src) return AUTOFIRE_CONTINUE return NONE