Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xeno Backpacks #1274

Merged
merged 20 commits into from
Dec 17, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7ae1fe6
Initial support adding runner and praetorian backpack support
Drulikar Oct 16, 2022
90246f1
Added shake verb for xenos and humans
Drulikar Oct 16, 2022
3d23a77
Fix no sfx for unequipping a backpack
Drulikar Oct 16, 2022
3164cf6
Update prae sprites and add regular pack support for praes
Drulikar Oct 16, 2022
7537a5e
Added the ability to bag fruit
Drulikar Oct 16, 2022
de038dc
Set engie packs to use marinepack sprite for now
Drulikar Oct 16, 2022
6694908
Refactoring
Drulikar Oct 16, 2022
d252954
Added tailswipes to the head when not allied
Drulikar Oct 16, 2022
21626c8
Added sprites for runner regular, warrior regular/medical (needs twea…
Drulikar Oct 31, 2022
7b7b73a
Remove unintended backpack types from being allowed as xeno packs.
Drulikar Oct 31, 2022
d1de3fd
Refactor xeno packs to use atom/moveable/vis_obj instead (only creati…
Drulikar Oct 31, 2022
22761eb
More vis_obj refactoring: No need to create a dir change signal if th…
Drulikar Oct 31, 2022
b6e2e01
Update resting sprites for defender and warrior
Drulikar Nov 2, 2022
966030d
Blocked strapping backpacks onto xenoids via trait (since they don't …
Drulikar Nov 16, 2022
2701127
Fix xeno packs inheriting hive color
Drulikar Nov 20, 2022
d1f2334
More comments for gitactions breaking.
Drulikar Nov 20, 2022
c884cfd
Merge branch 'master' into Drathek_XenoBackpacks
Drulikar Nov 22, 2022
319f428
Move onmob files to new xeno icon directory.
Drulikar Nov 27, 2022
c51d826
Sprite update for east facing defender, prae, and warrior medical packs
Drulikar Dec 9, 2022
428e47c
More tweaks to warrior, sentinel, runner, prae, and defender sprites.
Drulikar Dec 13, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,11 @@ var/list/default_onmob_icons = list(
WEAR_ACCESSORIES = 'icons/mob/humans/onmob/ties.dmi'
)

var/list/default_xeno_onmob_icons = list(
/mob/living/carbon/Xenomorph/Runner = 'icons/mob/hostiles/onmob/runner.dmi',
/mob/living/carbon/Xenomorph/Praetorian = 'icons/mob/hostiles/onmob/praetorian.dmi'
)

// species names
#define SPECIES_HUMAN "Human"
#define SPECIES_YAUTJA "Yautja"
Expand Down
3 changes: 3 additions & 0 deletions code/_onclick/adjacent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ Quick adjacency (to turf):
if(recurse > 0)
return loc.Adjacent(neighbor, recurse - 1)
return FALSE
else if(isXeno(loc)) //Xenos don't count as storage depth.
return loc.Adjacent(neighbor, recurse)
return ..()

/*
Special case: This allows you to reach a door when it is visally on top of,
but technically behind, a fire door
Expand Down
23 changes: 23 additions & 0 deletions code/_onclick/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,29 @@
if(user != src)
return . = ..()

if(isXeno(dropping))
var/mob/xeno = dropping
if(xeno.back)
var/obj/item/back_item = xeno.back
if(user.get_active_hand())
to_chat(user, SPAN_WARNING("You can't unstrap \the [back_item] from [xeno] with your hands full."))
return
user.visible_message(SPAN_NOTICE("\The [user] starts unstrapping \the [back_item] from [xeno]"), \
SPAN_NOTICE("You start unstrapping \the [back_item] from [xeno]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(!do_after(user, HUMAN_STRIP_DELAY * user.get_skill_duration_multiplier(), INTERRUPT_ALL, BUSY_ICON_GENERIC, xeno, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
to_chat(user, SPAN_WARNING("You were interrupted!"))
return

if(user.get_active_hand())
return
if(!user.Adjacent(xeno))
return
xeno.drop_inv_item_on_ground(back_item)
if(!back_item || QDELETED(back_item)) //Might be self-deleted?
return
user.put_in_active_hand(back_item)
return

if(pulling != dropping || grab_level != GRAB_AGGRESSIVE || !ishuman(dropping) || !(a_intent & INTENT_GRAB))
return . = ..()

Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items.dm
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@

var/mob/living/carbon/human/locked_to_mob = null // If the item uses flag MOB_LOCK_ON_PICKUP, this is the mob owner reference.

var/list/equip_sounds//Sounds played when this item is equipped
var/list/equip_sounds //Sounds played when this item is equipped
var/list/unequip_sounds //Same but when unequipped

///Vision impairing effect if worn on head/mask/glasses.
Expand Down
55 changes: 54 additions & 1 deletion code/game/objects/items/storage/backpack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
var/obj/item/card/id/locking_id = null
var/is_id_lockable = FALSE
var/lock_overridable = TRUE
var/xeno_icon_state = null
var/list/xeno_types = null

/obj/item/storage/backpack/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/card/id/) && is_id_lockable && ishuman(user))
Expand All @@ -27,6 +29,46 @@
if (..() && use_sound)
playsound(loc, use_sound, 15, TRUE, 6)

/obj/item/storage/backpack/attack(mob/living/target_mob, mob/living/user)
if(!xeno_icon_state)
return ..()
if(!isXeno(target_mob))
return ..()
if(target_mob.back)
return ..()
if(user.a_intent != INTENT_HELP)
return ..()
if(!xeno_types || !(target_mob.type in xeno_types))
return ..()

user.visible_message(SPAN_NOTICE("\The [user] starts strapping \the [src] onto [target_mob]."), \
SPAN_NOTICE("You start strapping \the [src] onto [target_mob]."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(!do_after(user, HUMAN_STRIP_DELAY * user.get_skill_duration_multiplier(), INTERRUPT_ALL, BUSY_ICON_GENERIC, target_mob, INTERRUPT_MOVED, BUSY_ICON_GENERIC))
to_chat(user, SPAN_WARNING("You were interrupted!"))
return FALSE

if(src != user.get_active_hand())
return FALSE
if(!user.Adjacent(target_mob))
return FALSE
user.drop_inv_item_on_ground(src)
if(!src || QDELETED(src)) //Might be self-deleted?
return FALSE
target_mob.put_in_back(src)
return FALSE

/obj/item/storage/backpack/get_mob_overlay(mob/user_mob, slot, state_modifier = "")
if(slot != WEAR_BACK)
return ..()

if(xeno_icon_state)
var/mob_icon = default_xeno_onmob_icons[user_mob.type]
if(!mob_icon)
return ..()
return overlay_image(mob_icon, xeno_icon_state + state_modifier, color, RESET_COLOR)

return ..()

/obj/item/storage/backpack/proc/toggle_lock(obj/item/card/id/card, mob/living/carbon/human/H)
if(QDELETED(locking_id))
to_chat(H, SPAN_NOTICE("You lock \the [src]!"))
Expand All @@ -48,6 +90,12 @@
storage_close(user)
..()

/obj/item/storage/unequipped(mob/user, slot, silent)
if(slot == WEAR_BACK)
if(use_sound && !silent)
playsound(loc, use_sound, 15, TRUE, 6)
..()

/obj/item/storage/backpack/dropped(mob/user)
mouse_opacity = initial(mouse_opacity)
..()
Expand Down Expand Up @@ -312,18 +360,24 @@ obj/item/storage/backpack/proc/compare_id(var/mob/living/carbon/human/H)
icon_state = "marinepack"
item_state = "marinepack"
has_gamemode_skin = TRUE //replace this with the atom_flag NO_SNOW_TYPE at some point, just rename it to like, NO_MAP_VARIANT_SKIN
xeno_icon_state = "marinepack"
xeno_types = list(/mob/living/carbon/Xenomorph/Praetorian)

/obj/item/storage/backpack/marine/medic
name = "\improper USCM corpsman backpack"
desc = "A standard-issue backpack worn by USCM medics."
icon_state = "marinepack_medic"
item_state = "marinepack_medic"
xeno_icon_state = "medicpack"
xeno_types = list(/mob/living/carbon/Xenomorph/Runner, /mob/living/carbon/Xenomorph/Praetorian)

/obj/item/storage/backpack/marine/tech
name = "\improper USCM technician backpack"
desc = "A standard-issue backpack worn by USCM technicians."
icon_state = "marinepack_techi"
item_state = "marinepack_techi"
xeno_icon_state = "marinepack"
xeno_types = list(/mob/living/carbon/Xenomorph/Praetorian)

/obj/item/storage/backpack/marine/satchel/intel
name = "\improper USCM lightweight expedition pack"
Expand All @@ -347,7 +401,6 @@ obj/item/storage/backpack/proc/compare_id(var/mob/living/carbon/human/H)
storage_slots = null
max_storage_space = 21 //backpack size


/obj/item/storage/backpack/marine/satchel/medic
name = "\improper USCM corpsman satchel"
desc = "A heavy-duty satchel used by USCM medics. It sacrifices capacity for usability. A small patch is sewn to the top flap."
Expand Down
66 changes: 66 additions & 0 deletions code/game/objects/items/storage/storage.dm
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,16 @@ W is always an item. stop_warning prevents messaging. user may be null.**/

return attempt_item_insertion(W, FALSE, user)

/obj/item/storage/equipped(mob/user, slot, silent)
if ((storage_flags & STORAGE_ALLOW_EMPTY))
if(!isXeno(user))
verbs |= /obj/item/storage/verb/empty_verb
verbs |= /obj/item/storage/verb/toggle_click_empty
else
verbs -= /obj/item/storage/verb/empty_verb
verbs -= /obj/item/storage/verb/toggle_click_empty
..()

/obj/item/storage/proc/attempt_item_insertion(obj/item/W as obj, prevent_warning = FALSE, mob/user as mob)
if(!can_be_inserted(W))
return
Expand Down Expand Up @@ -608,6 +618,61 @@ W is always an item. stop_warning prevents messaging. user may be null.**/
remove_from_storage(I, T)
user.visible_message(SPAN_NOTICE("[user] empties \the [src]."),
SPAN_NOTICE("You empty \the [src]."))
if (use_sound)
playsound(loc, use_sound, 25, TRUE, 3)

/obj/item/storage/verb/shake_verb()
set name = "Shake"
set category = "Object"
set src in usr
var/mob/user_mob = usr
shake(user_mob, get_turf(user_mob))

/obj/item/storage/proc/shake(var/mob/user, var/turf/tile)
if(!(storage_flags & STORAGE_ALLOW_EMPTY))
return

if(user.l_hand != src && user.r_hand != src && user.back != src)
return

if(user.is_mob_incapacitated())
return

if (!isturf(tile) || get_dist(src, tile) > 1)
tile = get_turf(src)

if (use_sound)
playsound(loc, use_sound, 25, TRUE, 3)

if(!length(contents))
if(prob(25) && isXeno(user))
user.drop_inv_item_to_loc(src, tile)
user.visible_message(SPAN_NOTICE("[user] shakes \the [src] off."),
SPAN_NOTICE("You shake \the [src] off."))
else
user.visible_message(SPAN_NOTICE("[user] shakes \the [src] but nothing falls out."),
SPAN_NOTICE("You shake \the [src] but nothing falls out. It feels empty."))
return

if(!allowed(user))
user.visible_message(SPAN_NOTICE("[user] shakes \the [src] but nothing falls out."),
SPAN_NOTICE("You shake \the [src] but nothing falls out. Access denied."))
return

if(!prob(75))
user.visible_message(SPAN_NOTICE("[user] shakes \the [src] but nothing falls out."),
SPAN_NOTICE("You shake \the [src] but nothing falls out."))
return

storage_close(user)
var/obj/item/item_obj
if(storage_flags & STORAGE_USING_FIFO_DRAWING)
item_obj = contents[1]
else
item_obj = contents[contents.len]
remove_from_storage(item_obj, tile)
user.visible_message(SPAN_NOTICE("[user] shakes \the [src] and \a [item_obj] falls out."),
SPAN_NOTICE("You shake \the [src] and \a [item_obj] falls out."))

/obj/item/storage/proc/dump_ammo_to(obj/item/ammo_magazine/ammo_dumping, mob/user, var/amount_to_dump = 5) //amount_to_dump should never actually need to be used as default value
if(user.action_busy)
Expand Down Expand Up @@ -674,6 +739,7 @@ W is always an item. stop_warning prevents messaging. user may be null.**/
if (!(storage_flags & STORAGE_ALLOW_EMPTY))
verbs -= /obj/item/storage/verb/empty_verb
verbs -= /obj/item/storage/verb/toggle_click_empty
verbs -= /obj/item/storage/verb/shake_verb

boxes = new
boxes.name = "storage"
Expand Down
3 changes: 2 additions & 1 deletion code/modules/cm_aliens/structures/fruit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,8 @@
desc = "A strange fruit that you could eat.. if you REALLY wanted to. Its roots seem to twitch every so often."
icon = 'icons/mob/hostiles/fruits.dmi'
icon_state = "fruit_lesser_item"
w_class = SIZE_LARGE
w_class = SIZE_MEDIUM
storage_cost = SIZE_LARGE
bitesize = 2
var/mob/living/carbon/Xenomorph/bound_xeno //Drone linked to this fruit
var/fruit_type = /obj/effect/alien/resin/fruit
Expand Down
23 changes: 21 additions & 2 deletions code/modules/mob/inventory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
if(hand) return put_in_r_hand(W)
else return put_in_l_hand(W)

//Puts the item our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
//Puts the item into our active hand if possible. Failing that it tries our inactive hand. Returns 1 on success.
//If both fail it drops it on the floor and returns 0.
//This is probably the main one you need to know :)
/mob/proc/put_in_hands(var/obj/item/W)
Expand All @@ -76,7 +76,24 @@
W.dropped(src)
return FALSE


//Puts the item into our back if possible. Returns 1 on success.
/mob/proc/put_in_back(var/obj/item/item)
if(!item)
return FALSE
if(!istype(item))
return FALSE
if(back)
return FALSE
if(item.loc == src && !(item.flags_item & DELONDROP))
item.dropped(src)
item.pickup(src)
item.forceMove(src)
back = item
item.layer = ABOVE_HUD_LAYER
item.plane = ABOVE_HUD_PLANE
item.equipped(src, WEAR_BACK)
update_inv_back()
return TRUE

/mob/proc/drop_item_v() //this is dumb.
if(stat == CONSCIOUS && isturf(loc))
Expand Down Expand Up @@ -366,3 +383,5 @@
return WEAR_L_HAND
if(I == r_hand)
return WEAR_R_HAND
if(I == back)
return WEAR_BACK
14 changes: 14 additions & 0 deletions code/modules/mob/living/carbon/xenomorph/XenoAttacks.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@
switch(M.a_intent)

if(INTENT_HELP)
if(back && Adjacent(M))
back.add_fingerprint(M)
var/obj/item/storage/backpack = back
if(backpack && !M.action_busy)
M.visible_message(SPAN_NOTICE("\The [M] starts opening \the [backpack] on [src]"), \
SPAN_NOTICE("You begin to open \the [backpack] on [src], so you can check its contents."), null, 5, CHAT_TYPE_FLUFF_ACTION)
if(!do_after(M, 1 SECONDS, INTERRUPT_NO_NEEDHAND, BUSY_ICON_GENERIC, src, INTERRUPT_MOVED, BUSY_ICON_GENERIC)) //Timed opening.
to_chat(M, SPAN_WARNING("You were interrupted!"))
return FALSE
if(!Adjacent(M))
to_chat(M, SPAN_WARNING("You were interrupted!"))
return FALSE
backpack.open(M)
return
if(stat == DEAD)
M.visible_message(SPAN_WARNING("\The [M] pokes \the [src], but nothing happens."), \
SPAN_WARNING("You poke \the [src], but nothing happens."), null, 5, CHAT_TYPE_FLUFF_ACTION)
Expand Down
Loading