Some more mirrors again (#27366)

* Ports additional Felinid ears from Orbstation (#82066)

Adds 5 new ear options from Orbstation, originally PRed in
lizardqueenlexi/orbstation#360. Sprites by @Or-Fi-S.

Big:

![image](https://github.com/tgstation/tgstation/assets/7019927/5f847130-e5f5-44cc-adb4-c740c4c4f69b)

Coeurl (FFXIV Miqo'te style):

![image](https://github.com/tgstation/tgstation/assets/7019927/34448bee-d6af-4d3c-b796-384ec9904368)

Fold:

![image](https://github.com/tgstation/tgstation/assets/7019927/a7dafd05-f652-460e-9386-f7fcbef696e9)

Lynx:

![image](https://github.com/tgstation/tgstation/assets/7019927/174ff630-6eb8-4bb9-8f4f-791b70356c58)

Round:

![image](https://github.com/tgstation/tgstation/assets/7019927/b3a24d1b-66fa-4883-8c27-871ae8966d6c)

Also makes it so the code guarantees that custom ears on a felinid
actually count as felinid ears and not human ones, as the code wasn't
checking properly when preferences were applied. There's probably a
cleaner, more permanent way to do this and a refactor is needed
somewhere down the line (man that sprite accessories file is getting
long huh) but I'll leave that to a more competent coder.

More customization options are good also Cobby said I could

![image](https://github.com/tgstation/tgstation/assets/7019927/56bbe285-068f-41a1-92cc-9f3861875090)

🆑
add: Added 5 new Felinid ear options, ported from Orbstation! (Sprites
by Or-Fi-S)
/🆑

---------

Co-authored-by: _0Steven <jaydondegenerschool@gmail.com>

* Standardizes object deconstruction  throughout the codebase.  (#82280)

When it comes to deconstructing an object we have `proc/deconstruct()` &
`NO_DECONSTRUCT`

Lets talk about the flag first.

**Problems with `NO_DECONSTRUCTION`**
I know what the comment says on what it should do

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/__DEFINES/obj_flags.dm#L18

But everywhere people have decided to give their own meaning/definition
to this flag. Here are some examples on how this flag is used

**1. Make the object just disappear(not drop anything) when
deconstructed**
This is by far the largest use case everywhere. If an object is
deconstructed(either via tools or smashed apart) then if it has this
flag it should not drop any of its contents but just disappear. You have
seen this code pattern used everywhere

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/game/machinery/constructable_frame.dm#L26-L31

This behaviour is then leveraged by 2 important components.

When an object is frozen, if it is deconstructed it should just
disappear without leaving any traces behind

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/datums/elements/frozen.dm#L66-L67

By hologram objects. Obviously if you destroy an hologram nothing real
should drop out

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/modules/holodeck/computer.dm#L301-L304

And there are other use cases as well but we won't go into them as they
aren't as significant as these.

**2. To stop an object from being wrenched ??**
Yeah this one is weird. Like why? I understand in some instances (chair,
table, rack etc) a wrench can be used to deconstruct a object so using
the flag there to stop it from happening makes sense but why can't we
even anchor an object just because of this flag?

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/game/objects/objs.dm#L368-L369
This is one of those instances where somebody just decided this
behaviour for their own convenience just like the above example with no
explanation as to why

**3. To stop using tools to deconstruct the object**
This was the original intent of the flag but it is enforced in few
places far & between. One example is when deconstructing the a machine
via crowbar.

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/game/machinery/_machinery.dm#L811

But machines are a special dual use case for this flag. Because if you
look at its deconstruct proc the flag also prevents the machine from
spawning a frame.

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/game/machinery/_machinery.dm#L820-L822

How can 1 flag serve 2 purposes within the same type?

**4. Simply forget to check for this flag altogether**
Yup if you find this flag not doing its job for some objects don't be
surprised. People & sometimes even maintainers just forget that it even
exists

https://github.com/tgstation/tgstation/blob/b5593bc6930cb60803214869a7b94c84e7baa02c/code/game/objects/items/piggy_bank.dm#L66-L67

**Solution**
These are the main examples i found. As you can see the same flag can
perform 2 different functions within the same type and do something else
in a different object & in some instances don't even work cause people
just forget, etc.

In order to bring consistency to this flag we need to move it to the
atom level where it means the same thing everywhere. Where in the atom
you may ask? .Well, I'll just post what MrMelbert said in
https://github.com/tgstation/tgstation/pull/81656#discussion_r1503086862

> ...Ideally the .deconstruct call would handle NO_DECONSTRUCTION
handling as it wants,

Yup that's the ideal case now. This flag is checked directly in
`deconstruct()`. Now like i said we want to give a universal definition
to this flag and as you have seen from my examples it is used in 3 cases
1) Make an object disappear(doesn't dropping anything) when
deconstructed
2) Stop it from being wrenched
3) Stop it from being deconstructed via tools

We can't enforce points 2 & 3 inside `deconstruct()` which leaves us
with only case 1) i.e. make the object disappear. And that's what i have
done. Therefore after more than a decade or since this flag got
introduced `NO_DECONSTRUCT` now has a new definition as of 2024

_"Make an object disappear(don't dropping anything) when deconstructed
either via tools or forcefully smashed apart"_

Now i very well understand this will open up bugs in places where cases
2 & 3 are required but its worth it. In fact they could even be qol
changes for all we know so who knows it might even benefit us but for
now we need to give a universal definition to this flag to bring some
consistency & that's what this PR does.

**Problem with deconstruct()**
This proc actually sends out a signal which is currently used by the
material container but could be used by other objects later on.

https://github.com/tgstation/tgstation/blob/3e84c3e6dad33c831ac259f52f2f023680e4899b/code/game/objects/obj_defense.dm#L160

So objects that override this proc should call its parent. Sadly that
isn't the case in many instances like such

https://github.com/tgstation/tgstation/blob/3e84c3e6dad33c831ac259f52f2f023680e4899b/code/game/machinery/deployable.dm#L20-L23

Instead of `return ..()` which would delete the object & send the signal
it deletes the object directly thus the signal never gets sent.

**Solution**
Make this proc non overridable. For objects to add their own custom
deconstruction behaviour a new proc has been introduced
`atom_deconstruct()` Subtypes should now override this proc to handle
object deconstruction.

If objects have certain important stuff inside them (like mobs in
machines for example) they want to drop by handling `NO_DECONSTRUCT`
flag in a more carefully customized way they can do this by overriding
`handle_deconstruct()` which by default delegates to
`atom_deconstruct()` if the `NO_DECONSTRUCT` flag is absent. This proc
will allow you to handle the flag in a more customized way if you ever
need to.

1) I'm goanna post the full comment from MrMelbert
https://github.com/tgstation/tgstation/pull/81656#discussion_r1503086862

> ...Ideally the .deconstruct call would handle NO_DECONSTRUCTION
handling as it wants, but there's a shocking lack of consistency around
NO_DECONSTRUCTION, where some objects treat it as "allow deconstruction,
but make it drop no parts" and others simply "disallow deconstruction at
all"

This PR now makes `NO_DECONSTRUCTION` handled by `deconstruct()` & gives
this flag the consistency it deserves. Not to mention as shown in case 4
there are objects that simply forgot to check for this flag. Now it
applies for those missing instances as well.

2) No more copying pasting the most overused code pattern in this code
base history `if(obj_flags & NO_DECONSTRUCTION)`. Just makes code
cleaner everywhere

3) All objects now send the `COMSIG_OBJ_DECONSTRUCT` signal on object
deconstruction which is now available for use should you need it

🆑
refactor: refactors how objects are deconstructed in relation to the
`NO_DECONSTRUCTION` flag. Certain objects & machinery may display
different tool interactions & behaviours when destroyed/deconstructed.
Report these changes if you feel like they are bugs
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>

* Makes attempting to refresh the logs not just throw a runtime error (#82432)

## About The Pull Request

Really all this seems to be is a mismatch between the tgui and dm side
of the menu.

https://github.com/tgstation/tgstation/blob/3c71b14df0957749f31fb2e678130daf4cfb3250/tgui/packages/tgui/interfaces/LogViewer.tsx#L71

https://github.com/tgstation/tgstation/blob/3c71b14df0957749f31fb2e678130daf4cfb3250/code/modules/logging/log_holder.dm#L110-L113
Making these line up by renaming `re-render` to `refresh` seems to make
it work just fine, and not just throw an error.
## Why It's Good For The Game

Life tends to be better when refreshing to see new runtimes doesn't just
add its own lovely little runtimes.

![image](https://github.com/tgstation/tgstation/assets/42909981/79bee3db-5c28-409b-9ff5-3a315fb4ed1c)

![image](https://github.com/tgstation/tgstation/assets/42909981/82a25038-ba7a-430a-bb79-f59d5f4b262b)
And then not show them til you re-open the window cause it doesn't
refresh.
## Changelog
🆑
admin: Refresh button on the View Round Logs menu actually works,
instead of just adding a runtime to the logs (and not updating them).
/🆑

* Creates a "busy" animation for players (#82416)

Little indicator above a player when they're currently doing something.

<details>
<summary>vids</summary>

Perspective: You are the moth

![dreamseeker_b2LA4PpPAr](https://github.com/tgstation/tgstation/assets/42397676/3a38dd3c-23f2-430f-acf4-444ad5c478d3)

Hides under runechat

![dreamseeker_ZgkCWTGqDz](https://github.com/tgstation/tgstation/assets/42397676/ec1d9665-4ff0-47f7-85b6-65998c31b9be)

</details>

Todo:

- [x] Feedback?
- [x] Sneaky params so it doesn't spoil your stealth run
- [x] Possible refactor
- [x] Probably missed some "sneaky" actions
- [x] coggers

<details>
<summary>sound on:</summary>

https://github.com/tgstation/tgstation/assets/42397676/ad71c567-0202-4158-ba50-c2946375f988

</details>

🆑 jlsnow301, infraredbaron
add: Added a new UI element over players that are interacting, building,
etc.
/🆑

---------

Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: san7890 <the@san7890.com>

* New operative reinforcement option: Intelligence Overwatch Agent (#82307)

## About The Pull Request

Introducing a new Nuclear Operative reinforcement option: The Overwatch
Intelligence Agent.

Equipped with multi-hudglasses, they have an advanced camera console,
station alerts, and bodycams of every operative! If something can be
known, they will know about it.

They can also remotely pilot your ship. Finally, everyone can ride in
the Steel Rain without getting stuck on the station!

This role spawns in the formerly unused outpost just north of the nukie
base. With a few shelves of supplies and some tools in the back room,
they can set up their workplace however they like. This also gives them
something to work on while they wait for the operatives to gear up.


![image](https://github.com/tgstation/tgstation/assets/28870487/4a39ec5f-0578-4825-8c6b-cc4db47bf726)

As you can see, it's rather cramped and the lights are quite dim in the
backroom. Set it up however you like, this is how I did mine:


![image](https://github.com/tgstation/tgstation/assets/28870487/f80b65fa-dcd1-425e-a6ce-c0ed94a8a3a5)

Total price? 12 TC per agent. It might get a bit cramped, but you could
buy a second to make sure the first guy doesn't get lonely!

This turned into a 30-commit ugly because the bodycams were originally
meant to be accomplished via a refactoring of the spyglass kit. Big
mistake that made me shelve the project -- until Melbert's simple
bodycam component conveniently did exactly what I needed in a much
simpler way.
## Why It's Good For The Game

Having a "guy in the chair" for your kickass murder operator squad
enables more brainy strategizing, and is thematically sound. Also,
nukies have the opportunity to bring in another player to participate in
the fun!
## Changelog
🆑 Rhials
add: Nuclear Operatives now purchase an Intelligence Agent, who can
watch cameras and bodycams, move the shuttle, and provide radio support.
Only 12 Telecrystals!
/🆑

* re-adds list of components for admins to remove (#82461)

## About The Pull Request

The list of components on a mob when admins try to remove one didn't
actually show them, now it does.

![image](https://github.com/tgstation/tgstation/assets/53777086/a6102c3a-df30-4e9c-b7fd-29a4d8ddaa89)

## Why It's Good For The Game

Messing with components/elements on mobs are such a pain, in this case
was broken entirely.

![admin-toolings](https://github.com/tgstation/tgstation/assets/53777086/3d190c66-34e4-4424-824b-37f95e88b003)

## Changelog

🆑
admin: Removing components button now lists components to remove
/🆑

* Reboots the CNS Rebooter Implant. (#82441)

## About The Pull Request
The CNS Rebooter Implant will now pull you out of stuns and stamcrit,
while granting you a few seconds of stun immunity, comes with a 60
seconds cooldown
## Why It's Good For The Game
The CNS Rebooter Implant is a strong candidate for the absolute worst
implant in the game, it caps your stuns at 4 seconds
(which is plenty of time to get murdered) and does nothing to prevent
stamina damage, for something accessible in one of the latest research
nodes and in the nukie uplink it should perform better than it does now.
Besides, the game is in dire need for more tools to keep the stun meta
at bay, and this is a good place to start.

This PR makes it so the rebooter will bail you out stamcrit every 60
seconds, along with giving you a few seconds of immunity to run away or
get a couple of hits in.
## Changelog
🆑
balance: CNS Rebooter Implant will now pull you out of stamcrit and
grant you a few seconds of stun immunity
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>

* Fix "Aheal" for ears deafness (#82448)

## About The Pull Request
Make the admin button "Aheal" and Magic Wand of Healing (resurrection)
actually full heal carbon's Ears.

File _ears.dm contains timer variable "deaf" that should be updated to 0
after complete healing.

But I think this must be properly code-refactored because looks like
it's just duplicates(?) standart variable "damage" for organ type.

## Why It's Good For The Game
Aheal - means FULLY HEAL.

## Changelog

🆑
fix: aheal now properly heals ears deafness
/🆑

---------

Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>

* Medipens can't have reagents removed from them anymore. (#82451)

## About The Pull Request

This will be needed for
https://github.com/tgstation/tgstation/pull/82449 because this removes
the machine's ability to make infinite chems.
Basically in https://github.com/tgstation/tgstation/pull/29139 they
removed medipen's ability to have reagents injected into them, but never
removed the ability to take reagents out.
You could take a syringe, remove all chemicals from a medipen, put the
main ingredient in a medipen refiller, then refill. You could do this
right now on live servers with an epipen for infinite formaldehyde.

This doesn't affect the hypospray.

## Why It's Good For The Game

Removes a way of infinitely making reagents with a medipen refiller and
also removes a dumb mechanic.
You could take all chemicals out of an EHMS autoinjector, which removes
the visual and feedback tell to the target that they've been injected,
and even with 0 chemicals they get the disease anyways.
You could buy medipens as a miner, take the chemicals out, and put them
in a syringe or pill that you can inject yourself instantly with.
You can take otherwise hard-to-get chemicals like fungal TB's 2-use cure
injector, and make 40 cure pills instead.

## Changelog

🆑
fix: You can no longer take chemicals out of medipens with a syringe.
/🆑

* Search string in catalogs in char prefs (#82423)

* actually just removes stamina damage and knockdown from punches (#82400)

removes punch knockdowns and stamina damage from them

knockdown punches were also around the time disarm could just hardstun
you to RNG
this is dumb so we remove that
also watermelon supposedly wanted to remove stamina damage from punches
so idk about that

anyway so this is a problem because you could be randomly floored by
sheer luck through thick plates of metal and is overall not a very fun
thing to play against especially with northstar gloves

resolves unfun RNG by removing knockdowns and does something watermelon
wanted by removing stam damage from it

🆑
balance: punches no longer knock down or deal stamina damage
/🆑

* Fix slime `check_item_passthrough` effect (#82484)

## About The Pull Request

This proc expects a user but is not passed one. 

## Changelog

🆑 Melbert
fix: Items will properly pass through slime on occasion
/🆑

* Basic mobs now use z-level turnoff instead of simple (#82469)

## About The Pull Request

On one compile of MetaStation, I saw that there's 45 basic mobs on the
station, 256 on lavaland (the number growing from tendrils), and 59 in
all other z levels combined.

While we do expect Lavaland to be visited every round, at least it won't
be running during the times when no one is there, but even more
importantly, space exploration is something not done every round, so we
don't have any reason to waste our resources on AIs that will never be
interacted with.

Simple animals had an easy solution to this:
If no one is on the Z level, their AI turns off
If someone is on the Z level, they are idle unless needed.

The last simple animals that exists right now are bots, megafauna,
geese, gondolas, and some minor ones like mimic, zombie, dark wizard,
soulscythe, etc.
Point is, we're very much nearly done going through all simple animals,
so this code is being wasted just to ensure things like cleanbots won't
work if no one is on the z level, something I doubt happens often, so I
took their code and made it work for basic mobs instead. I could've done
both but I thought it would look very bad, and maybe this is a good
incentivize to get more basic mob conversions.

There's one major change here and it's that we're missing the "Idle"
mode, some basic mobs like the Lavaland village seems to be made with
intent that they'll be running even if players aren't around, so this
sets up a future PR that makes idle AI easier to add, and I want to make
sure those cases are taken into account.

## Why It's Good For The Game

We don't need to always be processing these basic mobs, and sets us in
the future to hopefully also implement idle AIs.

## Changelog

🆑
balance: Basic mob AIs with no mobs on the Z level now stop.
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>

* adds preferences to transhumanist (#82435)

## About The Pull Request
You may remember this, that's because I accidentally deleted it before
while trying to change things. Anyways!
Adds drop-down selections and new options to transhumanist. also fixes a
minor typo
Previously, you could choose your replaced limb by taking prosthetic
limb, setting what you want changed, and then switching to
transhumanist, since they used the same preference previously.

## Why It's Good For The Game

Transhumanist felt strange because it was hypothetically a voluntary
operation, but the augmentation clinic just spun the wheel on what you
got replaced. From a role-playing perspective, being unable to choose is
uninteresting and confusing. Also it always says your limb being was
being replaced with a robotic arm and that annoyed me. Now that you are
able to select your replacement part, I've added two new options, the
robotic voice box, good for a more prominent change then a limb that
will be hidden for most of a round, and flashlight eyes, for when you
are truly committed to being rushed directly to robotics seeing the
bright future ahead of humanity!

## Changelog
🆑
add: Transhumanist now allows you to select your augmentation
add: Transhumanist can now provide a robotic voice box, or flashlight
eyes
spellcheck: Transhumanist's roundstart text has been re-written to not
be wrong
/🆑

---------

Co-authored-by: san7890 <the@san7890.com>

* Watcher wreaths; Normal and Icewing varieties (#82457)

Adds Watcher Wreaths. An item that makes it look like you have a
slightly floating thorn crown that you can make from some of their
material parts (and the icewing crusher trophy for the icewing variant).

The wreath has emissives. They don't do anything mechanically, they're
just for show.

![wreath](https://github.com/tgstation/tgstation/assets/40847847/84b7cf89-2087-4c5c-85c1-d911c2e7ea13)

![image](https://github.com/tgstation/tgstation/assets/40847847/77bcda12-e29f-45f0-ad4a-8f25de12c0ef)

![image](https://github.com/tgstation/tgstation/assets/40847847/da3321bb-b24d-4e60-8648-455483e955d6)

I really like the whole thing with turning lavaland monsters into
trophies and cosmetics. Going down and coming back up looking like
someone who just crawled through a horror movie and took some souvenirs
is great. Stuff like the trophy accessories, bone and drake armor and
many of the various lavaland items have this quality, and it always
amuses me when a tech sees a dressed up miner and just goes 'holy shit,
where did you get that'?

Drip is the ultimate reward for playing miner. Nobody can tell me
otherwise. this is the endgame every miner craves. And I crave a goddamn
crown made from the broken remains of my enemies.

🆑
add: Watcher wreaths. Made from the mangled remains of a watcher, now a
handsome accessory for you to wear a few inches behind your head. Comes
in Normal and Icewing variants.
add: Some bounties for the two variants of watcher wreaths.
/🆑

* CHEAP_HYPOTENUSE() no longer makes the differences between the coordinates absolute. (#82468)

## About The Pull Request
CHEAP_HYPOTENUSE() no longer absolutes the differences between the
coordinates.
## Why It's Good For The Game
It gets squared so it doesn't need to be done.

* Neutered symptoms no longer activate (#82467)

## About The Pull Request

Stops activation of all neutered symptoms in a advanced disease.

## Why It's Good For The Game

Closes https://github.com/tgstation/tgstation/issues/68944

## Changelog

🆑
fix: Narcolepsy is no longer activated while neutered.
/🆑

* Fixes the color matrix editor (#82478)

## About The Pull Request

It was sending back stringified numbers as inputs. This came from a
typescript cleanup pr from sync (#82000) and was ultimately caused by
a... I think misunderstanding of how the color list works (#67967)

## Why It's Good For The Game

Works like a charm now, which is good cause I use it a lot

## Changelog
🆑
fix: The color matrix editor now works properly again
/🆑

* Hats no longer cover mouths (#82498)

* Fixes banned/days remaining preferences display for non-dynamic ruleset antagonists. (#82506)

* Reverts reversion: tgui will 516 or else (#82527)

## About The Pull Request
Context: #82522

Apparently you cant just stuff the byond helper functions into an
external js file, but if you do, byond won't even let you know its a
problem until the servers crash and you have to run `bin/clean` just to
unbork your entire repo

This reimplements the changes from #82473 without:
- moving the byond helper functions externally
- causing a tooltip render issue in panel

## Why It's Good For The Game
516 prep (again this time)

* Final Objective: Battle Royale (#82258)

## About The Pull Request

Adds a new final objective option with a classic premise; the forced
battle to the death.
The concept is that the Syndicate will provide you with an implanter
tool you can use on an arbitrary number of crew members. Once you have
at least 6 (though there is no ceiling) you can activate the implants to
start the Battle Royale and broadcast the perspectives of everyone you
implanted live to the entertainment monitor.

After activation these implants cause you to explode upon death. If at
the end of 10 minutes, more than one person remains unexploded then all
of the remaining implants will detonate simultaneously.
Additionally, one of the station's departments (Medbay, Cargo, Science,
or Engineering) will be chosen as the arena. If after 5 minutes pass
you're not within that department (or if you leave it after that time
has passed) then you will be killed.

The Syndicate plan on both using the recorded footage to study
Nanotrasen technology, and also to sell it as an underground blood
sport, and so have employed a pirate broadcasting station to provide
colour commentary.

The implantation is silent, however it requires you and your target to
be adjacent and stood still for one and a half seconds.
Once implanted, it will occasionally itch and eventually signal to the
implantee that something is up, so once you start implanting someone
you're on a soft timer until you are given away. You can also implant
yourself if you want to do that for some reason.

Removing an implant from someone has a 70% chance of setting it off
instantly, but it _is_ possible. If the implant is exposed to EMP, this
value is randomised between 0 and 100%. You could also try doing surgery
while the patient is wearing a bomb suit or something, that puzzle is
for you to solve and I'm not going to tell you the answers. I'm sure
you'll think of ones I haven't.

## Why It's Good For The Game

Adds a somewhat more down-to-earth but still hopefully exciting and
threatening option which should let people mess around with the sandbox.
The mutual death element provides some roleplaying prompts; nothing
actually _forces_ you to fight apart from fear of death and it may be
possible to find other ways to survive, or perform some kind of
solidarity behaviour with your fellow contestants. Maybe you'll try that
but one of your fellow contestants just wants to be the last survivor
anyway. Maybe you'll pretend you're setting up some kind of mutual
survivorship thing in order to make sure you're the sole survivor.
Gives some people to watch on the bar TV channel.
The crew apparently love playing Deathmatch while dead so we might as
well enable doing it while alive.

Also I'm going to follow this up with a separate PR to remove the Space
Dragon objective and it felt like it'd be a good idea to do one out one
in

## Changelog

🆑
add: Adds a new Final Objective where you force your fellow crew to
fight to the death on pain of... death.
/🆑

---------

Co-authored-by: _0Steven <jaydondegenerschool@gmail.com>
Co-authored-by: san7890 <the@san7890.com>
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
Co-authored-by: Zephyr <12817816+ZephyrTFA@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: EnterTheJake <102721711+EnterTheJake@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Artemchik542 <32270644+Artemchik542@users.noreply.github.com>
Co-authored-by: Yaroslav Nurkov <78199449+AnywayFarus@users.noreply.github.com>
Co-authored-by: jimmyl <70376633+mc-oofert@users.noreply.github.com>
Co-authored-by: Skeleton-In-Disguise <49223093+Skeleton-In-Disguise@users.noreply.github.com>
Co-authored-by: necromanceranne <40847847+necromanceranne@users.noreply.github.com>
Co-authored-by: Pickle-Coding <58013024+Pickle-Coding@users.noreply.github.com>
Co-authored-by: Bilbo367 <163439532+Bilbo367@users.noreply.github.com>
Co-authored-by: FlufflesTheDog <piecopresident@gmail.com>
Co-authored-by: AnturK <AnturK@users.noreply.github.com>
Co-authored-by: Jacquerel <hnevard@gmail.com>
This commit is contained in:
Useroth
2024-04-17 22:59:33 -04:00
committed by GitHub
co-authored by _0Steven san7890 _0Steven Jeremiah Zephyr LemonInTheDark Rhials John Willard EnterTheJake MrMelbert Artemchik542 Yaroslav Nurkov jimmyl Skeleton-In-Disguise necromanceranne Pickle-Coding Bilbo367 FlufflesTheDog AnturK Jacquerel
parent fa175dbddc
commit 20c0599ce6
233 changed files with 2249 additions and 1214 deletions
+1 -2
View File
@@ -380,7 +380,7 @@
icon_state = "ai-empty"
return ..()
/obj/structure/ai_core/deconstruct(disassembled = TRUE)
/obj/structure/ai_core/atom_deconstruct(disassembled = TRUE)
if(state >= GLASS_CORE)
new /obj/item/stack/sheet/rglass(loc, 2)
if(state >= CABLED_CORE)
@@ -389,7 +389,6 @@
circuit.forceMove(loc)
circuit = null
new /obj/item/stack/sheet/plasteel(loc, 4)
qdel(src)
/// Quick proc to call to see if the brainmob inside of us has suicided. Returns TRUE if we have, FALSE in any other scenario.
/obj/structure/ai_core/proc/suicide_check()
+4 -7
View File
@@ -41,10 +41,8 @@
icon = 'icons/obj/fluff/general.dmi'
icon_state = "gelmound"
/obj/structure/alien/gelpod/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/effect/mob_spawn/corpse/human/damaged(get_turf(src))
qdel(src)
/obj/structure/alien/gelpod/atom_deconstruct(disassembled = TRUE)
new /obj/effect/mob_spawn/corpse/human/damaged(get_turf(src))
/*
* Resin
@@ -446,9 +444,8 @@
/obj/structure/alien/egg/atom_break(damage_flag)
. = ..()
if(!(obj_flags & NO_DECONSTRUCTION))
if(status != BURST)
Burst(kill=TRUE)
if(status != BURST)
Burst(kill=TRUE)
/obj/structure/alien/egg/HasProximity(atom/movable/AM)
if(status == GROWN)
@@ -12,10 +12,18 @@
smoothing_groups = SMOOTH_GROUP_ALIEN_NEST
canSmoothWith = SMOOTH_GROUP_ALIEN_NEST
build_stack_type = null
obj_flags = parent_type::obj_flags | NO_DECONSTRUCTION
elevation = 0
var/static/mutable_appearance/nest_overlay = mutable_appearance('icons/mob/nonhuman-player/alien.dmi', "nestoverlay", LYING_MOB_LAYER)
/obj/structure/bed/nest/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(held_item?.tool_behaviour == TOOL_WRENCH)
return NONE
return ..()
/obj/structure/bed/nest/wrench_act_secondary(mob/living/user, obj/item/weapon)
return ITEM_INTERACT_BLOCKING
/obj/structure/bed/nest/user_unbuckle_mob(mob/living/buckled_mob, mob/living/user)
if(has_buckled_mobs())
for(var/buck in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore
@@ -34,12 +34,11 @@
/obj/structure/bed/examine(mob/user)
. = ..()
if(!(obj_flags & NO_DECONSTRUCTION))
. += span_notice("It's held together by a couple of <b>bolts</b>.")
. += span_notice("It's held together by a couple of <b>bolts</b>.")
/obj/structure/bed/add_context(atom/source, list/context, obj/item/held_item, mob/living/user)
if(held_item)
if(held_item.tool_behaviour != TOOL_WRENCH || obj_flags & NO_DECONSTRUCTION)
if(held_item.tool_behaviour != TOOL_WRENCH)
return
context[SCREENTIP_CONTEXT_RMB] = "Dismantle"
@@ -49,19 +48,14 @@
context[SCREENTIP_CONTEXT_LMB] = "Unbuckle"
return CONTEXTUAL_SCREENTIP_SET
/obj/structure/bed/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(build_stack_type)
new build_stack_type(loc, build_stack_amount)
..()
/obj/structure/bed/atom_deconstruct(disassembled = TRUE)
if(build_stack_type)
new build_stack_type(loc, build_stack_amount)
/obj/structure/bed/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
/obj/structure/bed/wrench_act_secondary(mob/living/user, obj/item/weapon)
if(obj_flags & NO_DECONSTRUCTION)
return TRUE
..()
weapon.play_tool_sound(src)
deconstruct(disassembled = TRUE)
@@ -36,16 +36,12 @@
SSjob.latejoin_trackers -= src //These may be here due to the arrivals shuttle
return ..()
/obj/structure/chair/deconstruct(disassembled)
// If we have materials, and don't have the NOCONSTRUCT flag
if(!(obj_flags & NO_DECONSTRUCTION))
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
else
for(var/i in custom_materials)
var/datum/material/M = i
new M.sheet_type(loc, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
..()
/obj/structure/chair/atom_deconstruct(disassembled)
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
else
for(var/datum/material/mat as anything in custom_materials)
new mat.sheet_type(loc, FLOOR(custom_materials[mat] / SHEET_MATERIAL_AMOUNT, 1))
/obj/structure/chair/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
@@ -56,8 +52,6 @@
qdel(src)
/obj/structure/chair/attackby(obj/item/W, mob/user, params)
if(obj_flags & NO_DECONSTRUCTION)
return . = ..()
if(istype(W, /obj/item/assembly/shock_kit) && !HAS_TRAIT(src, TRAIT_ELECTRIFIED_BUCKLE))
electrify_self(W, user)
return
@@ -85,8 +79,6 @@
/obj/structure/chair/wrench_act_secondary(mob/living/user, obj/item/weapon)
if(obj_flags & NO_DECONSTRUCTION)
return TRUE
..()
weapon.play_tool_sound(src)
deconstruct(disassembled = TRUE)
@@ -279,7 +271,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool, 0)
/obj/structure/chair/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr && Adjacent(usr))
if(!item_chair || has_buckled_mobs() || src.obj_flags & NO_DECONSTRUCTION)
if(!item_chair || has_buckled_mobs())
return
if(!usr.can_perform_action(src, NEED_DEXTERITY|NEED_HANDS))
return
@@ -495,6 +487,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/chair/stool/bar, 0)
obj_flags = parent_type::obj_flags | NO_DECONSTRUCTION
alpha = 0
/obj/structure/chair/mime/wrench_act_secondary(mob/living/user, obj/item/weapon)
return ITEM_INTERACT_BLOCKING
/obj/structure/chair/mime/post_buckle_mob(mob/living/M)
M.pixel_y += 5
@@ -609,8 +609,6 @@ LINEN BINS
..()
/obj/structure/bedsheetbin/screwdriver_act(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION)
return FALSE
if(amount)
to_chat(user, span_warning("The [src] must be empty first!"))
return ITEM_INTERACT_SUCCESS
@@ -581,25 +581,23 @@ GLOBAL_LIST_EMPTY(roundstart_station_closets)
else
return open(user)
/obj/structure/closet/deconstruct(disassembled = TRUE)
if (!(obj_flags & NO_DECONSTRUCTION))
if(ispath(material_drop) && material_drop_amount)
new material_drop(loc, material_drop_amount)
if (secure)
var/obj/item/electronics/airlock/electronics = new(drop_location())
if(length(req_one_access))
electronics.one_access = TRUE
electronics.accesses = req_one_access
else
electronics.accesses = req_access
if(card_reader_installed)
new /obj/item/stock_parts/card_reader(drop_location())
/obj/structure/closet/atom_deconstruct(disassembled = TRUE)
if(ispath(material_drop) && material_drop_amount)
new material_drop(loc, material_drop_amount)
if (secure)
var/obj/item/electronics/airlock/electronics = new(drop_location())
if(length(req_one_access))
electronics.one_access = TRUE
electronics.accesses = req_one_access
else
electronics.accesses = req_access
if(card_reader_installed)
new /obj/item/stock_parts/card_reader(drop_location())
dump_contents()
qdel(src)
/obj/structure/closet/atom_break(damage_flag)
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
bust_open()
/obj/structure/closet/CheckParts(list/parts_list)
@@ -36,10 +36,8 @@
flags_1 &= ~PREVENT_CONTENTS_EXPLOSION_1
return FALSE
/obj/structure/closet/secure_closet/freezer/deconstruct(disassembled)
if (!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/assembly/igniter/condenser(drop_location())
. = ..()
/obj/structure/closet/secure_closet/freezer/atom_deconstruct(disassembled)
new /obj/item/assembly/igniter/condenser(drop_location())
/obj/structure/closet/secure_closet/freezer/empty
name = "freezer"
@@ -4,16 +4,13 @@
var/break_sound = 'sound/magic/clockwork/invoke_general.ogg' //The sound played when a structure breaks
var/list/debris = null //Parts left behind when a structure breaks, takes the form of list(path = amount_to_spawn)
/obj/structure/destructible/deconstruct(disassembled = TRUE)
/obj/structure/destructible/atom_deconstruct(disassembled = TRUE)
if(!disassembled)
if(!(obj_flags & NO_DECONSTRUCTION))
if(islist(debris))
for(var/I in debris)
for(var/i in 1 to debris[I])
new I (get_turf(src))
if(break_message)
visible_message(break_message)
if(break_sound)
playsound(src, break_sound, 50, TRUE)
qdel(src)
return 1
if(islist(debris))
for(var/I in debris)
for(var/i in 1 to debris[I])
new I (get_turf(src))
if(break_message)
visible_message(break_message)
if(break_sound)
playsound(src, break_sound, 50, TRUE)
+7 -9
View File
@@ -81,17 +81,15 @@
if(BURN)
playsound(src, 'sound/items/welder.ogg', 100, TRUE)
/obj/structure/displaycase/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
dump()
if(!disassembled)
new /obj/item/shard(drop_location())
trigger_alarm()
qdel(src)
/obj/structure/displaycase/atom_deconstruct(disassembled = TRUE)
dump()
if(!disassembled)
new /obj/item/shard(drop_location())
trigger_alarm()
/obj/structure/displaycase/atom_break(damage_flag)
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
set_density(FALSE)
broken = TRUE
new /obj/item/shard(drop_location())
@@ -673,7 +671,7 @@
/obj/structure/displaycase/forsale/atom_break(damage_flag)
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
broken = TRUE
playsound(src, SFX_SHATTER, 70, TRUE)
update_appearance()
+15 -18
View File
@@ -363,25 +363,22 @@
target.update_name()
qdel(source)
/obj/structure/door_assembly/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
var/turf/T = get_turf(src)
if(!disassembled)
material_amt = rand(2,4)
new material_type(T, material_amt)
if(glass)
if(disassembled)
if(heat_proof_finished)
new /obj/item/stack/sheet/rglass(T)
else
new /obj/item/stack/sheet/glass(T)
/obj/structure/door_assembly/atom_deconstruct(disassembled = TRUE)
var/turf/target_turf = get_turf(src)
if(!disassembled)
material_amt = rand(2,4)
new material_type(target_turf, material_amt)
if(glass)
if(disassembled)
if(heat_proof_finished)
new /obj/item/stack/sheet/rglass(target_turf)
else
new /obj/item/shard(T)
if(mineral)
var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]")
new mineral_path(T, 2)
qdel(src)
new /obj/item/stack/sheet/glass(target_turf)
else
new /obj/item/shard(target_turf)
if(mineral)
var/obj/item/stack/sheet/mineral/mineral_path = text2path("/obj/item/stack/sheet/mineral/[mineral]")
new mineral_path(target_turf, 2)
/obj/structure/door_assembly/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(the_rcd.mode == RCD_DECONSTRUCT)
@@ -271,24 +271,21 @@
name = "large public airlock assembly"
base_name = "large public airlock"
/obj/structure/door_assembly/door_assembly_material/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
var/turf/T = get_turf(src)
for(var/material in custom_materials)
var/datum/material/material_datum = material
var/material_count = FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1)
if(!disassembled)
material_count = rand(FLOOR(material_count/2, 1), material_count)
new material_datum.sheet_type(T, material_count)
if(glass)
if(disassembled)
if(heat_proof_finished)
new /obj/item/stack/sheet/rglass(T)
else
new /obj/item/stack/sheet/glass(T)
/obj/structure/door_assembly/door_assembly_material/atom_deconstruct(disassembled = TRUE)
var/turf/target_turf = get_turf(src)
for(var/datum/material/material_datum as anything in custom_materials)
var/material_count = FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1)
if(!disassembled)
material_count = rand(FLOOR(material_count/2, 1), material_count)
new material_datum.sheet_type(target_turf, material_count)
if(glass)
if(disassembled)
if(heat_proof_finished)
new /obj/item/stack/sheet/rglass(target_turf)
else
new /obj/item/shard(T)
qdel(src)
new /obj/item/stack/sheet/glass(target_turf)
else
new /obj/item/shard(target_turf)
/obj/structure/door_assembly/door_assembly_material/finish_door()
var/obj/machinery/door/airlock/door = ..()
+2 -4
View File
@@ -18,10 +18,8 @@
else
return ..()
/obj/structure/dresser/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
qdel(src)
/obj/structure/dresser/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)
/obj/structure/dresser/attack_hand(mob/user, list/modifiers)
. = ..()
+9 -11
View File
@@ -164,7 +164,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
/obj/structure/extinguisher_cabinet/atom_break(damage_flag)
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
broken = 1
opened = 1
if(stored_extinguisher)
@@ -173,16 +173,14 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/extinguisher_cabinet, 29)
update_appearance(UPDATE_ICON)
/obj/structure/extinguisher_cabinet/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(disassembled)
new /obj/item/wallframe/extinguisher_cabinet(loc)
else
new /obj/item/stack/sheet/iron (loc, 2)
if(stored_extinguisher)
stored_extinguisher.forceMove(loc)
stored_extinguisher = null
qdel(src)
/obj/structure/extinguisher_cabinet/atom_deconstruct(disassembled = TRUE)
if(disassembled)
new /obj/item/wallframe/extinguisher_cabinet(loc)
else
new /obj/item/stack/sheet/iron (loc, 2)
if(stored_extinguisher)
stored_extinguisher.forceMove(loc)
stored_extinguisher = null
/obj/item/wallframe/extinguisher_cabinet
name = "extinguisher cabinet frame"
+12 -16
View File
@@ -133,14 +133,12 @@
playsound(src, 'sound/items/welder.ogg', 100, TRUE)
deconstruct(disassembled)
/obj/structure/falsewall/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(disassembled)
new girder_type(loc)
if(mineral_amount)
for(var/i in 1 to mineral_amount)
new mineral(loc)
qdel(src)
/obj/structure/falsewall/atom_deconstruct(disassembled = TRUE)
if(disassembled)
new girder_type(loc)
if(mineral_amount)
for(var/i in 1 to mineral_amount)
new mineral(loc)
/obj/structure/falsewall/get_dumping_location()
return null
@@ -387,14 +385,12 @@
canSmoothWith = SMOOTH_GROUP_MATERIAL_WALLS
material_flags = MATERIAL_EFFECTS | MATERIAL_ADD_PREFIX | MATERIAL_COLOR | MATERIAL_AFFECT_STATISTICS
/obj/structure/falsewall/material/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(disassembled)
new girder_type(loc)
for(var/material in custom_materials)
var/datum/material/material_datum = material
new material_datum.sheet_type(loc, FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1))
qdel(src)
/obj/structure/falsewall/material/atom_deconstruct(disassembled = TRUE)
if(disassembled)
new girder_type(loc)
for(var/material in custom_materials)
var/datum/material/material_datum = material
new material_datum.sheet_type(loc, FLOOR(custom_materials[material_datum] / SHEET_MATERIAL_AMOUNT, 1))
/obj/structure/falsewall/material/mat_update_desc(mat)
desc = "A huge chunk of [mat] used to separate rooms."
+4 -10
View File
@@ -10,21 +10,15 @@
var/buildstackamount = 5
can_atmos_pass = ATMOS_PASS_NO
/obj/structure/fans/deconstruct()
if(!(obj_flags & NO_DECONSTRUCTION))
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
qdel(src)
/obj/structure/fans/atom_deconstruct(disassembled = TRUE)
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
/obj/structure/fans/wrench_act(mob/living/user, obj/item/I)
..()
if(obj_flags & NO_DECONSTRUCTION)
return TRUE
user.visible_message(span_warning("[user] disassembles [src]."),
span_notice("You start to disassemble [src]..."), span_hear("You hear clanking and banging noises."))
if(I.use_tool(src, user, 20, volume=50))
deconstruct()
deconstruct(TRUE)
return TRUE
/obj/structure/fans/tiny
+9 -13
View File
@@ -108,19 +108,17 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet, 32)
/obj/structure/fireaxecabinet/atom_break(damage_flag)
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
update_appearance()
broken = TRUE
playsound(src, 'sound/effects/glassbr3.ogg', 100, TRUE)
new /obj/item/shard(loc)
new /obj/item/shard(loc)
/obj/structure/fireaxecabinet/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(held_item && loc)
held_item.forceMove(loc)
new /obj/item/wallframe/fireaxecabinet(loc)
qdel(src)
/obj/structure/fireaxecabinet/atom_deconstruct(disassembled = TRUE)
if(held_item && loc)
held_item.forceMove(loc)
new /obj/item/wallframe/fireaxecabinet(loc)
/obj/structure/fireaxecabinet/blob_act(obj/structure/blob/B)
if(held_item)
@@ -230,12 +228,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet/empty, 32)
MAPPING_DIRECTIONAL_HELPERS(/obj/structure/fireaxecabinet/mechremoval, 32)
/obj/structure/fireaxecabinet/mechremoval/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(held_item && loc)
held_item.forceMove(loc)
new /obj/item/wallframe/fireaxecabinet/mechremoval(loc)
qdel(src)
/obj/structure/fireaxecabinet/mechremoval/atom_deconstruct(disassembled = TRUE)
if(held_item && loc)
held_item.forceMove(loc)
new /obj/item/wallframe/fireaxecabinet/mechremoval(loc)
/obj/structure/fireaxecabinet/mechremoval/empty
populate_contents = FALSE
+4 -6
View File
@@ -263,13 +263,11 @@
var/matrix/M = matrix(transform)
transform = M.Turn(-previous_rotation)
/obj/structure/flora/deconstruct()
if(!(obj_flags & NO_DECONSTRUCTION))
if(harvested)
return ..()
/obj/structure/flora/atom_deconstruct(disassembled = TRUE)
if(harvested)
return ..()
harvest(product_amount_multiplier = 0.6)
. = ..()
harvest(product_amount_multiplier = 0.6)
/*********
* Trees *
+5 -9
View File
@@ -383,11 +383,9 @@
return TRUE
return FALSE
/obj/structure/girder/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
var/remains = pick(/obj/item/stack/rods, /obj/item/stack/sheet/iron)
new remains(loc)
qdel(src)
/obj/structure/girder/atom_deconstruct(disassembled = TRUE)
var/remains = pick(/obj/item/stack/rods, /obj/item/stack/sheet/iron)
new remains(loc)
/obj/structure/girder/narsie_act()
new /obj/structure/girder/cult(loc)
@@ -460,10 +458,8 @@
/obj/structure/girder/cult/narsie_act()
return
/obj/structure/girder/cult/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
qdel(src)
/obj/structure/girder/cult/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/runed_metal(drop_location(), 1)
/obj/structure/girder/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
switch(the_rcd.mode)
+5 -16
View File
@@ -52,8 +52,6 @@
/obj/structure/grille/examine(mob/user)
. = ..()
if(obj_flags & NO_DECONSTRUCTION)
return
if(anchored)
. += span_notice("It's secured in place with <b>screws</b>. The rods look like they could be <b>cut</b> through.")
@@ -200,10 +198,8 @@
add_fingerprint(user)
if(shock(user, 100))
return
if(obj_flags & NO_DECONSTRUCTION)
return FALSE
tool.play_tool_sound(src, 100)
deconstruct()
deconstruct(TRUE)
return ITEM_INTERACT_SUCCESS
/obj/structure/grille/screwdriver_act(mob/living/user, obj/item/tool)
@@ -212,8 +208,6 @@
add_fingerprint(user)
if(shock(user, 90))
return FALSE
if(obj_flags & NO_DECONSTRUCTION)
return FALSE
if(!tool.use_tool(src, user, 0, volume=100))
return FALSE
set_anchored(!anchored)
@@ -296,18 +290,13 @@
playsound(src, 'sound/items/welder.ogg', 80, TRUE)
/obj/structure/grille/deconstruct(disassembled = TRUE)
if(!loc) //if already qdel'd somehow, we do nothing
return
if(!(obj_flags & NO_DECONSTRUCTION))
var/obj/R = new rods_type(drop_location(), rods_amount)
transfer_fingerprints_to(R)
qdel(src)
..()
/obj/structure/grille/atom_deconstruct(disassembled = TRUE)
var/obj/rods = new rods_type(drop_location(), rods_amount)
transfer_fingerprints_to(rods)
/obj/structure/grille/atom_break()
. = ..()
if(!broken && !(obj_flags & NO_DECONSTRUCTION))
if(!broken)
icon_state = "brokengrille"
set_density(FALSE)
atom_integrity = 20
+1 -2
View File
@@ -64,7 +64,7 @@
if(!QDELETED(src))
deconstruct(TRUE)
/obj/structure/headpike/deconstruct(disassembled)
/obj/structure/headpike/atom_deconstruct(disassembled)
var/obj/item/bodypart/head/our_head = victim
var/obj/item/spear/our_spear = spear
victim = null
@@ -73,7 +73,6 @@
if(!disassembled)
return ..()
our_spear?.forceMove(drop_location())
return ..()
/obj/structure/headpike/attack_hand(mob/user, list/modifiers)
. = ..()
@@ -40,10 +40,9 @@ GLOBAL_LIST_INIT(ore_probability, list(
var/turf/closed/mineral/clearable = potential
clearable.ScrapeAway(flags = CHANGETURF_IGNORE_AIR)
/obj/structure/spawner/ice_moon/deconstruct(disassembled)
/obj/structure/spawner/ice_moon/atom_deconstruct(disassembled)
destroy_effect()
drop_loot()
return ..()
/**
* Effects and messages created when the spawner is destroyed
@@ -159,13 +159,12 @@
buckled_mob.pixel_y = buckled_mob.base_pixel_y + PIXEL_Y_OFFSET_LYING
REMOVE_TRAIT(buckled_mob, TRAIT_MOVE_UPSIDE_DOWN, REF(src))
/obj/structure/kitchenspike/deconstruct(disassembled = TRUE)
/obj/structure/kitchenspike/atom_deconstruct(disassembled = TRUE)
if(disassembled)
var/obj/structure/meatspike_frame = new /obj/structure/kitchenspike_frame(src.loc)
transfer_fingerprints_to(meatspike_frame)
else
new /obj/item/stack/sheet/iron(src.loc, 4)
new /obj/item/stack/rods(loc, MEATSPIKE_IRONROD_REQUIREMENT)
qdel(src)
#undef MEATSPIKE_IRONROD_REQUIREMENT
+3 -6
View File
@@ -57,10 +57,8 @@
var/turf/T = get_turf(src)
return T.attackby(C, user) //hand this off to the turf instead (for building plating, catwalks, etc)
/obj/structure/lattice/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new build_material(get_turf(src), number_of_mats)
qdel(src)
/obj/structure/lattice/atom_deconstruct(disassembled = TRUE)
new build_material(get_turf(src), number_of_mats)
/obj/structure/lattice/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(the_rcd.mode == RCD_TURF)
@@ -113,11 +111,10 @@
C.deconstruct()
..()
/obj/structure/lattice/catwalk/deconstruct()
/obj/structure/lattice/catwalk/atom_deconstruct(disassembled = TRUE)
var/turf/T = loc
for(var/obj/structure/cable/C in T)
C.deconstruct()
..()
/obj/structure/lattice/catwalk/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(the_rcd.mode == RCD_DECONSTRUCT)
@@ -42,9 +42,8 @@ GLOBAL_LIST_INIT(tendrils, list())
AddComponent(/datum/component/gps, "Eerie Signal")
GLOB.tendrils += src
/obj/structure/spawner/lavaland/deconstruct(disassembled)
/obj/structure/spawner/lavaland/atom_deconstruct(disassembled)
new /obj/effect/collapse(loc)
return ..()
/obj/structure/spawner/lavaland/examine(mob/user)
var/list/examine_messages = ..()
+3 -5
View File
@@ -303,11 +303,9 @@ at the cost of risking a vicious bite.**/
deconstruct()
return TRUE
/obj/structure/steam_vent/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/iron(loc, 1)
new /obj/item/stock_parts/water_recycler(loc, 1)
qdel(src)
/obj/structure/steam_vent/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/iron(loc, 1)
new /obj/item/stock_parts/water_recycler(loc, 1)
/**
* Creates "steam" smoke, and determines when the vent needs to block line of sight via reset_opacity.
@@ -204,14 +204,12 @@
/////////////////////// END TOOL OVERRIDES ///////////////////////
/obj/structure/mineral_door/deconstruct(disassembled = TRUE)
/obj/structure/mineral_door/atom_deconstruct(disassembled = TRUE)
var/turf/T = get_turf(src)
if(disassembled)
new sheetType(T, sheetAmount)
else
new sheetType(T, max(sheetAmount - 2, 1))
qdel(src)
/obj/structure/mineral_door/iron
name = "iron door"
+6 -8
View File
@@ -260,7 +260,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
/obj/structure/mirror/atom_break(damage_flag, mapload)
. = ..()
if(broken || (obj_flags & NO_DECONSTRUCTION))
if(broken)
return
icon_state = "mirror_broke"
if(!mapload)
@@ -269,13 +269,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/mirror/broken, 28)
desc = "Oh no, seven years of bad luck!"
broken = TRUE
/obj/structure/mirror/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(!disassembled)
new /obj/item/shard(loc)
else
new /obj/item/wallframe/mirror(loc)
qdel(src)
/obj/structure/mirror/atom_deconstruct(disassembled = TRUE)
if(!disassembled)
new /obj/item/shard(loc)
else
new /obj/item/wallframe/mirror(loc)
/obj/structure/mirror/welder_act(mob/living/user, obj/item/I)
..()
+3 -6
View File
@@ -104,10 +104,8 @@ GLOBAL_LIST_EMPTY(bodycontainers) //Let them act as spawnpoints for revenants an
return
return attack_hand(user)
/obj/structure/bodycontainer/deconstruct(disassembled = TRUE)
if (!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/iron(loc, 5)
qdel(src)
/obj/structure/bodycontainer/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/iron(loc, 5)
/obj/structure/bodycontainer/container_resist_act(mob/living/user)
if(!locked)
@@ -477,9 +475,8 @@ GLOBAL_LIST_EMPTY(crematoriums)
connected = null
return ..()
/obj/structure/tray/deconstruct(disassembled = TRUE)
/obj/structure/tray/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/iron (loc, 2)
qdel(src)
/obj/structure/tray/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
+5 -7
View File
@@ -110,15 +110,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/noticeboard, 32)
notices--
update_appearance(UPDATE_ICON)
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
if(!disassembled)
new /obj/item/stack/sheet/mineral/wood(loc)
else
new /obj/item/wallframe/noticeboard(loc)
/obj/structure/noticeboard/atom_deconstruct(disassembled = TRUE)
if(!disassembled)
new /obj/item/stack/sheet/mineral/wood(loc)
else
new /obj/item/wallframe/noticeboard(loc)
for(var/obj/item/content in contents)
remove_item(content)
qdel(src)
/obj/item/wallframe/noticeboard
name = "notice board"
@@ -73,7 +73,7 @@
petrified_mob.forceMove(loc)
return ..()
/obj/structure/statue/petrified/deconstruct(disassembled = TRUE)
/obj/structure/statue/petrified/atom_deconstruct(disassembled = TRUE)
var/destruction_message = "[src] shatters!"
if(!disassembled)
if(petrified_mob)
@@ -89,7 +89,6 @@
destruction_message = "[src] shatters, a solid brain tumbling out!"
petrified_mob.dust()
visible_message(span_danger(destruction_message))
qdel(src)
/obj/structure/statue/petrified/animate_atom_living(mob/living/owner)
if(isnull(petrified_mob))
+2 -3
View File
@@ -41,9 +41,8 @@
if(BURN)
playsound(src, 'sound/items/welder.ogg', 100, TRUE)
/obj/structure/pinata/deconstruct(disassembled)
/obj/structure/pinata/atom_deconstruct(disassembled)
new debris(get_turf(src))
return ..()
///An item that when used inhand spawns an immovable pinata
/obj/item/pinata
@@ -72,7 +71,7 @@
base_icon_state = "pinata_syndie_placed"
destruction_loot = 2
debris = /obj/effect/decal/cleanable/wrapping/pinata/syndie
candy_options = list(
candy_options = list(
/obj/item/food/bubblegum,
/obj/item/food/candy,
/obj/item/food/chocolatebar,
+2 -4
View File
@@ -124,10 +124,8 @@
return FALSE //If you're not laying down, or a small creature, or a ventcrawler, then no pass.
/obj/structure/plasticflaps/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/plastic/five(loc)
qdel(src)
/obj/structure/plasticflaps/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/plastic/five(loc)
/obj/structure/plasticflaps/Initialize(mapload)
. = ..()
+1 -6
View File
@@ -98,19 +98,14 @@
deconstruct()
return TRUE
/obj/structure/railing/deconstruct(disassembled)
if((obj_flags & NO_DECONSTRUCTION))
return ..()
/obj/structure/railing/atom_deconstruct(disassembled)
var/rods_to_make = istype(src,/obj/structure/railing/corner) ? 1 : 2
var/obj/rod = new item_deconstruct(drop_location(), rods_to_make)
transfer_fingerprints_to(rod)
return ..()
///Implements behaviour that makes it possible to unanchor the railing.
/obj/structure/railing/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(obj_flags & NO_DECONSTRUCTION)
return
to_chat(user, span_notice("You begin to [anchored ? "unfasten the railing from":"fasten the railing to"] the floor..."))
if(I.use_tool(src, user, volume = 75, extra_checks = CALLBACK(src, PROC_REF(check_anchored), anchored)))
set_anchored(!anchored)
+1 -2
View File
@@ -45,12 +45,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/secure_safe, 32)
if(mapload)
PopulateContents()
/obj/structure/secure_safe/deconstruct(disassembled)
/obj/structure/secure_safe/atom_deconstruct(disassembled)
if(!density) //if we're a wall item, we'll drop a wall frame.
var/obj/item/wallframe/secure_safe/new_safe = new(get_turf(src))
for(var/obj/item in contents)
item.forceMove(new_safe)
return ..()
/obj/structure/secure_safe/proc/PopulateContents()
new /obj/item/paper(src)
-3
View File
@@ -191,9 +191,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/shower, (-16))
/obj/machinery/shower/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(obj_flags & NO_DECONSTRUCTION)
return
I.play_tool_sound(src)
deconstruct()
return TRUE
+1 -2
View File
@@ -209,9 +209,8 @@
deconstruct(TRUE)
return TRUE
/obj/structure/stairs_frame/deconstruct(disassembled = TRUE)
/obj/structure/stairs_frame/atom_deconstruct(disassembled = TRUE)
new frame_stack(get_turf(src), frame_stack_amount)
qdel(src)
/obj/structure/stairs_frame/attackby(obj/item/attacked_by, mob/user, params)
if(!isstack(attacked_by))
@@ -43,7 +43,7 @@
return
var/datum/looping_sound/typing/typing_sounds = new(src, start_immediately = TRUE)
balloon_alert(user, "synchronizing...")
if(!do_after(user = user, delay = 3 SECONDS, target = src, interaction_key = REF(src)))
if(!do_after(user = user, delay = 3 SECONDS, target = src, interaction_key = REF(src), hidden = TRUE))
typing_sounds.stop()
return
typing_sounds.stop()
@@ -52,7 +52,7 @@
/obj/structure/syndicate_uplink_beacon/screwdriver_act_secondary(mob/living/user, obj/item/tool)
tool.play_tool_sound(src)
balloon_alert(user, "deconstructing...")
if (!do_after(user, 5 SECONDS, target = src))
if (!do_after(user, 5 SECONDS, target = src, hidden = TRUE))
return FALSE
var/turf/beacon_tile = get_turf(src)
new /obj/item/stack/sheet/iron/five(beacon_tile)
+1 -2
View File
@@ -75,9 +75,8 @@
T.set_custom_materials(custom_materials)
qdel(src)
/obj/structure/table_frame/deconstruct(disassembled = TRUE)
/obj/structure/table_frame/atom_deconstruct(disassembled = TRUE)
new framestack(get_turf(src), framestackamount)
qdel(src)
/obj/structure/table_frame/narsie_act()
new /obj/structure/table_frame/wood(src.loc)
+34 -54
View File
@@ -73,7 +73,7 @@
context[SCREENTIP_CONTEXT_RMB] = "Deal card faceup"
. = CONTEXTUAL_SCREENTIP_SET
if(!(obj_flags & NO_DECONSTRUCTION) && deconstruction_ready)
if(deconstruction_ready)
if(held_item.tool_behaviour == TOOL_SCREWDRIVER)
context[SCREENTIP_CONTEXT_RMB] = "Disassemble"
. = CONTEXTUAL_SCREENTIP_SET
@@ -207,7 +207,7 @@
pushed_mob.add_mood_event("table", /datum/mood_event/table_limbsmash, banged_limb)
/obj/structure/table/screwdriver_act_secondary(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION || !deconstruction_ready)
if(!deconstruction_ready)
return FALSE
to_chat(user, span_notice("You start disassembling [src]..."))
if(tool.use_tool(src, user, 2 SECONDS, volume=50))
@@ -215,12 +215,12 @@
return ITEM_INTERACT_SUCCESS
/obj/structure/table/wrench_act_secondary(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION || !deconstruction_ready)
if(!deconstruction_ready)
return FALSE
to_chat(user, span_notice("You start deconstructing [src]..."))
if(tool.use_tool(src, user, 4 SECONDS, volume=50))
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
deconstruct(TRUE, 1)
deconstruct(TRUE)
return ITEM_INTERACT_SUCCESS
/obj/structure/table/attackby(obj/item/I, mob/living/user, params)
@@ -297,20 +297,14 @@
/obj/structure/table/proc/AfterPutItemOnTable(obj/item/thing, mob/living/user)
return
/obj/structure/table/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
if(!(obj_flags & NO_DECONSTRUCTION))
var/turf/T = get_turf(src)
if(buildstack)
new buildstack(T, buildstackamount)
else
for(var/i in custom_materials)
var/datum/material/M = i
new M.sheet_type(T, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
if(!wrench_disassembly)
new frame(T)
else
new framestack(T, framestackamount)
qdel(src)
/obj/structure/table/atom_deconstruct(disassembled = TRUE)
var/turf/target_turf = get_turf(src)
if(buildstack)
new buildstack(target_turf, buildstackamount)
else
for(var/datum/material/mat in custom_materials)
new mat.sheet_type(target_turf, FLOOR(custom_materials[mat] / SHEET_MATERIAL_AMOUNT, 1))
new framestack(target_turf, framestackamount)
/obj/structure/table/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
if(the_rcd.mode == RCD_DECONSTRUCT)
@@ -437,8 +431,7 @@
/obj/structure/table/glass/proc/on_entered(datum/source, atom/movable/AM)
SIGNAL_HANDLER
if(obj_flags & NO_DECONSTRUCTION)
return
if(!isliving(AM))
return
// Don't break if they're just flying past
@@ -469,19 +462,16 @@
victim.Paralyze(100)
qdel(src)
/obj/structure/table/glass/deconstruct(disassembled = TRUE, wrench_disassembly = 0)
if(!(obj_flags & NO_DECONSTRUCTION))
if(disassembled)
..()
return
else
var/turf/T = get_turf(src)
playsound(T, SFX_SHATTER, 50, TRUE)
/obj/structure/table/glass/atom_deconstruct(disassembled = TRUE)
if(disassembled)
..()
return
else
var/turf/T = get_turf(src)
playsound(T, SFX_SHATTER, 50, TRUE)
new frame(loc)
new glass_shard_type(loc)
qdel(src)
new frame(loc)
new glass_shard_type(loc)
/obj/structure/table/glass/narsie_act()
color = NARSIE_WINDOW_COLOUR
@@ -845,10 +835,9 @@
if(isnull(held_item))
return NONE
if(!(obj_flags & NO_DECONSTRUCTION))
if(held_item.tool_behaviour == TOOL_WRENCH)
context[SCREENTIP_CONTEXT_RMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
if(held_item.tool_behaviour == TOOL_WRENCH)
context[SCREENTIP_CONTEXT_RMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
return NONE
@@ -864,8 +853,6 @@
return TRUE
/obj/structure/rack/wrench_act_secondary(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION)
return NONE
tool.play_tool_sound(src)
deconstruct(TRUE)
return ITEM_INTERACT_SUCCESS
@@ -905,12 +892,10 @@
* Rack destruction
*/
/obj/structure/rack/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
set_density(FALSE)
var/obj/item/rack_parts/newparts = new(loc)
transfer_fingerprints_to(newparts)
qdel(src)
/obj/structure/rack/atom_deconstruct(disassembled = TRUE)
set_density(FALSE)
var/obj/item/rack_parts/newparts = new(loc)
transfer_fingerprints_to(newparts)
/*
@@ -939,24 +924,19 @@
context[SCREENTIP_CONTEXT_LMB] = "Construct Rack"
return CONTEXTUAL_SCREENTIP_SET
if(!(obj_flags & NO_DECONSTRUCTION))
if(held_item.tool_behaviour == TOOL_WRENCH)
context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
if(held_item.tool_behaviour == TOOL_WRENCH)
context[SCREENTIP_CONTEXT_LMB] = "Deconstruct"
return CONTEXTUAL_SCREENTIP_SET
return NONE
/obj/item/rack_parts/wrench_act(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION)
return NONE
tool.play_tool_sound(src)
deconstruct(TRUE)
return ITEM_INTERACT_SUCCESS
/obj/item/rack_parts/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/stack/sheet/iron(drop_location())
return ..()
/obj/item/rack_parts/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/iron(drop_location())
/obj/item/rack_parts/attack_self(mob/user)
if(building)
@@ -103,13 +103,11 @@
return TRUE
/obj/structure/tank_dispenser/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
for(var/X in src)
var/obj/item/I = X
I.forceMove(loc)
new /obj/item/stack/sheet/iron (loc, 2)
qdel(src)
/obj/structure/tank_dispenser/atom_deconstruct(disassembled = TRUE)
for(var/X in src)
var/obj/item/I = X
I.forceMove(loc)
new /obj/item/stack/sheet/iron (loc, 2)
/obj/structure/tank_dispenser/proc/dispense(tank_type, mob/receiver)
var/existing_tank = locate(tank_type) in src
+1 -2
View File
@@ -63,12 +63,11 @@
deconstruct(TRUE)
return TRUE
/obj/structure/tank_holder/deconstruct(disassembled = TRUE)
/obj/structure/tank_holder/atom_deconstruct(disassembled = TRUE)
var/atom/Tsec = drop_location()
new /obj/item/stack/rods(Tsec, 2)
if(tank)
tank.forceMove(Tsec)
qdel(src)
/obj/structure/tank_holder/attack_paw(mob/user, list/modifiers)
return attack_hand(user, modifiers)
@@ -35,22 +35,16 @@
user.visible_message(span_notice("[user] empties \the [src]."), span_notice("You empty \the [src]."))
empty_pod()
else
deconstruct(TRUE, user)
deconstruct(TRUE)
else
return ..()
/obj/structure/transit_tube_pod/deconstruct(disassembled = TRUE, mob/user)
if(!(obj_flags & NO_DECONSTRUCTION))
var/atom/location = get_turf(src)
if(user)
location = user.loc
add_fingerprint(user)
user.visible_message(span_notice("[user] removes [src]."), span_notice("You remove [src]."))
var/obj/structure/c_transit_tube_pod/R = new/obj/structure/c_transit_tube_pod(location)
transfer_fingerprints_to(R)
R.setDir(dir)
empty_pod(location)
qdel(src)
/obj/structure/transit_tube_pod/atom_deconstruct(disassembled = TRUE)
var/atom/location = get_turf(src)
var/obj/structure/c_transit_tube_pod/tube_pod = new/obj/structure/c_transit_tube_pod(location)
transfer_fingerprints_to(tube_pod)
tube_pod.setDir(dir)
empty_pod(location)
/obj/structure/transit_tube_pod/ex_act(severity, target)
. = ..()
+1 -2
View File
@@ -149,9 +149,8 @@
for(var/atom/movable/AM in contents)
AM.forceMove(droppoint)
/obj/structure/votebox/deconstruct(disassembled)
/obj/structure/votebox/atom_deconstruct(disassembled)
dump_contents()
. = ..()
/obj/structure/votebox/proc/raffle(mob/user)
var/list/options = list()
+21 -34
View File
@@ -83,17 +83,15 @@
icon_state = "toilet[open][cistern]"
return ..()
/obj/structure/toilet/deconstruct()
if(!(obj_flags & NO_DECONSTRUCTION))
for(var/obj/toilet_item in contents)
toilet_item.forceMove(drop_location())
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
else
for(var/i in custom_materials)
var/datum/material/M = i
new M.sheet_type(loc, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
..()
/obj/structure/toilet/atom_deconstruct(dissambled = TRUE)
for(var/obj/toilet_item in contents)
toilet_item.forceMove(drop_location())
if(buildstacktype)
new buildstacktype(loc,buildstackamount)
else
for(var/i in custom_materials)
var/datum/material/M = i
new M.sheet_type(loc, FLOOR(custom_materials[M] / SHEET_MATERIAL_AMOUNT, 1))
/obj/structure/toilet/attackby(obj/item/I, mob/living/user, params)
add_fingerprint(user)
@@ -105,7 +103,7 @@
cistern = !cistern
update_appearance()
return COMPONENT_CANCEL_ATTACK_CHAIN
else if(I.tool_behaviour == TOOL_WRENCH && !(obj_flags & NO_DECONSTRUCTION))
else if(I.tool_behaviour == TOOL_WRENCH)
I.play_tool_sound(src)
deconstruct()
return TRUE
@@ -227,10 +225,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/urinal, 32)
exposed = !exposed
return TRUE
/obj/structure/urinal/deconstruct(disassembled = TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
new /obj/item/wallframe/urinal(loc)
qdel(src)
/obj/structure/urinal/atom_deconstruct(disassembled = TRUE)
new /obj/item/wallframe/urinal(loc)
/obj/item/wallframe/urinal
name = "urinal frame"
@@ -419,7 +415,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink, (-14))
playsound(loc, 'sound/effects/slosh.ogg', 25, TRUE)
return
if(O.tool_behaviour == TOOL_WRENCH && !(obj_flags & NO_DECONSTRUCTION))
if(O.tool_behaviour == TOOL_WRENCH)
O.play_tool_sound(src)
deconstruct()
return
@@ -495,12 +491,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink, (-14))
else
return ..()
/obj/structure/sink/deconstruct()
if(!(obj_flags & NO_DECONSTRUCTION))
drop_materials()
if(has_water_reclaimer)
new /obj/item/stock_parts/water_recycler(drop_location())
..()
/obj/structure/sink/atom_deconstruct(dissambled = TRUE)
drop_materials()
if(has_water_reclaimer)
new /obj/item/stock_parts/water_recycler(drop_location())
/obj/structure/sink/process(seconds_per_tick)
// Water reclamation complete?
@@ -571,10 +565,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16))
deconstruct()
return TRUE
/obj/structure/sinkframe/deconstruct()
if(!(obj_flags & NO_DECONSTRUCTION))
drop_materials()
return ..()
/obj/structure/sinkframe/atom_deconstruct(dissambled = TRUE)
drop_materials()
/obj/structure/sinkframe/proc/drop_materials()
for(var/datum/material/material as anything in custom_materials)
@@ -725,9 +717,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16))
. = ..()
icon_state = "puddle"
/obj/structure/water_source/puddle/deconstruct(disassembled = TRUE)
qdel(src)
//End legacy sink
@@ -804,11 +793,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16))
playsound(loc, 'sound/effects/curtain.ogg', 50, TRUE)
toggle()
/obj/structure/curtain/deconstruct(disassembled = TRUE)
/obj/structure/curtain/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/cloth (loc, 2)
new /obj/item/stack/sheet/plastic (loc, 2)
new /obj/item/stack/rods (loc, 1)
qdel(src)
/obj/structure/curtain/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
@@ -840,10 +828,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/sink/kitchen, (-16))
alpha = 255
opaque_closed = TRUE
/obj/structure/curtain/cloth/deconstruct(disassembled = TRUE)
/obj/structure/curtain/cloth/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/cloth (loc, 4)
new /obj/item/stack/rods (loc, 1)
qdel(src)
/obj/structure/curtain/cloth/fancy
icon_type = "cur_fancy"
+8 -21
View File
@@ -78,8 +78,6 @@
/obj/structure/window/examine(mob/user)
. = ..()
if(obj_flags & NO_DECONSTRUCTION)
return
switch(state)
if(WINDOW_SCREWED_TO_FRAME)
@@ -210,8 +208,6 @@
return ITEM_INTERACT_SUCCESS
/obj/structure/window/screwdriver_act(mob/living/user, obj/item/tool)
if(obj_flags & NO_DECONSTRUCTION)
return
switch(state)
if(WINDOW_SCREWED_TO_FRAME)
@@ -240,7 +236,7 @@
/obj/structure/window/wrench_act(mob/living/user, obj/item/tool)
if(anchored)
return FALSE
if((obj_flags & NO_DECONSTRUCTION) || (reinf && state >= RWINDOW_FRAME_BOLTED))
if(reinf && state >= RWINDOW_FRAME_BOLTED)
return FALSE
to_chat(user, span_notice("You begin to disassemble [src]..."))
@@ -255,7 +251,7 @@
return ITEM_INTERACT_SUCCESS
/obj/structure/window/crowbar_act(mob/living/user, obj/item/tool)
if(!anchored || (obj_flags & NO_DECONSTRUCTION))
if(!anchored)
return FALSE
switch(state)
@@ -330,18 +326,13 @@
playsound(src, 'sound/items/welder.ogg', 100, TRUE)
/obj/structure/window/deconstruct(disassembled = TRUE)
if(QDELETED(src))
return
/obj/structure/window/atom_deconstruct(disassembled = TRUE)
if(!disassembled)
playsound(src, break_sound, 70, TRUE)
if(!(obj_flags & NO_DECONSTRUCTION))
for(var/obj/item/shard/debris in spawn_debris(drop_location()))
transfer_fingerprints_to(debris) // transfer fingerprints to shards only
qdel(src)
for(var/obj/item/shard/debris in spawn_debris(drop_location()))
transfer_fingerprints_to(debris) // transfer fingerprints to shards only
update_nearby_icons()
///Spawns shard and debris decal based on the glass_material_datum, spawns rods if window is reinforned and number of shards/rods is determined by the window being fulltile or not.
/obj/structure/window/proc/spawn_debris(location)
var/datum/material/glass_material_ref = GET_MATERIAL_REF(glass_material_datum)
@@ -480,9 +471,6 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0)
return FALSE
/obj/structure/window/reinforced/attackby_secondary(obj/item/tool, mob/user, params)
if(obj_flags & NO_DECONSTRUCTION)
return ..()
switch(state)
if(RWINDOW_SECURE)
if(tool.tool_behaviour == TOOL_WELDER)
@@ -546,7 +534,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0)
/obj/structure/window/reinforced/crowbar_act(mob/living/user, obj/item/tool)
if(!anchored)
return FALSE
if((obj_flags & NO_DECONSTRUCTION) || (state != WINDOW_OUT_OF_FRAME))
if(state != WINDOW_OUT_OF_FRAME)
return FALSE
to_chat(user, span_notice("You begin to lever the window back into the frame..."))
if(tool.use_tool(src, user, 10 SECONDS, volume = 75, extra_checks = CALLBACK(src, PROC_REF(check_state_and_anchored), state, anchored)))
@@ -561,8 +549,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/unanchored/spawner, 0)
/obj/structure/window/reinforced/examine(mob/user)
. = ..()
if(obj_flags & NO_DECONSTRUCTION)
return
switch(state)
if(RWINDOW_SECURE)
. += span_notice("It's been screwed in with one way screws, you'd need to <b>heat them</b> to have any chance of backing them out.")
@@ -803,9 +790,9 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/window/reinforced/tinted/frosted/spaw
/obj/structure/window/reinforced/shuttle/indestructible
name = "hardened shuttle window"
obj_flags = parent_type::obj_flags | NO_DECONSTRUCTION
flags_1 = PREVENT_CLICK_UNDER_1
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
obj_flags = parent_type::obj_flags | NO_DECONSTRUCTION
/obj/structure/window/reinforced/shuttle/indestructible/rcd_vals(mob/user, obj/item/construction/rcd/the_rcd)
return FALSE