Tg patch branch to master (#192)

* code nitpicking

* Midnight oil

More like 6am oil.  Still having issues with actually eating anyone.

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Tg modern (#149)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* Mentor system, Tickets, and discord (#151)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

* you could save that hookers number but wouldn't you rather just vore the hooker instead

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

* fuck if I know anymore. I'm going to bed

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* Vore code sync (#157)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

also ensured some mobs have vore controls, so silicons can't even
remotely do vore things.

* code nitpicking

* Midnight oil

More like 6am oil.  Still having issues with actually eating anyone.

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

* you could save that hookers number but wouldn't you rather just vore the hooker instead

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

* fuck if I know anymore. I'm going to bed

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

* gamemode voting in lobby via TalkingCactus
disabled ashwalkers as roundstart
Verk's species tweak
paralax starts disabled by default

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* edgy code of the modernization (#164)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

also ensured some mobs have vore controls, so silicons can't even
remotely do vore things.

* code nitpicking

* Midnight oil

More like 6am oil.  Still having issues with actually eating anyone.

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* Small fixes for dogborgs and sprite accessories:
-Ported the hidden snippets of the dogborg code.
-Reset module now resets pixel offset and icon directory again. (broke shit when reseting from dogborg)
-Medihound belly fixed.
-Husky body marking tweaked to not overlap arms in side view.
-Added husky ears that are basically wolf ears that use secondary color instead.

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

* you could save that hookers number but wouldn't you rather just vore the hooker instead

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

* fuck if I know anymore. I'm going to bed

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

* gamemode voting in lobby via TalkingCactus
disabled ashwalkers as roundstart
Verk's species tweak
paralax starts disabled by default

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* Merge test onto bleeding edgy (#165)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

also ensured some mobs have vore controls, so silicons can't even
remotely do vore things.

* code nitpicking

* Midnight oil

More like 6am oil.  Still having issues with actually eating anyone.

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* Small fixes for dogborgs and sprite accessories:
-Ported the hidden snippets of the dogborg code.
-Reset module now resets pixel offset and icon directory again. (broke shit when reseting from dogborg)
-Medihound belly fixed.
-Husky body marking tweaked to not overlap arms in side view.
-Added husky ears that are basically wolf ears that use secondary color instead.

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

* you could save that hookers number but wouldn't you rather just vore the hooker instead

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

* fuck if I know anymore. I'm going to bed

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

* gamemode voting in lobby via TalkingCactus
disabled ashwalkers as roundstart
Verk's species tweak
paralax starts disabled by default

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* travis map updates

* updates

* pool's closed due to lag

* datum pools are closed too

* Initializing new pool's closed

* Pool's closed and initializing shit is done

* sprite updates

* chattering is okay to do now.

* bleeblin edgy 1/23 (#166)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

also ensured some mobs have vore controls, so silicons can't even
remotely do vore things.

* code nitpicking

* Midnight oil

More like 6am oil.  Still having issues with actually eating anyone.

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

No idea if it's test worthy tho as conflicts with race overhaul and
narky removal.

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

* My code doesn't pass it's own sanity check.

Maybe it's a sign of things to come.

* uncommented and notes

* It Works and I Don't Know Why (#38)

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

I'm sure I've missed a fuckton of shit

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

* I'll give you a bad argument you piece of shit dream maker I fucking swear on my mum

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* Small fixes for dogborgs and sprite accessories:
-Ported the hidden snippets of the dogborg code.
-Reset module now resets pixel offset and icon directory again. (broke shit when reseting from dogborg)
-Medihound belly fixed.
-Husky body marking tweaked to not overlap arms in side view.
-Added husky ears that are basically wolf ears that use secondary color instead.

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

* you could save that hookers number but wouldn't you rather just vore the hooker instead

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

* fuck if I know anymore. I'm going to bed

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

* gamemode voting in lobby via TalkingCactus
disabled ashwalkers as roundstart
Verk's species tweak
paralax starts disabled by default

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* travis map updates

* updates

* pool's closed due to lag

* datum pools are closed too

* Initializing new pool's closed

* Pool's closed and initializing shit is done

* sprite updates

* chattering is okay to do now.

* Update .travis.yml

* Update .travis.yml

* Update .travis.yml

* Revert "Modern modern"

* Revert "Revert "Modern modern""

* fix it fix it fix it fix it

* fixes title screen - thanks crow

* Riding code reverted

* possible tgui fix?

* who the fuck even knows if this is the problem

* adds moths and sharks (no colors yet, not greyscaled)
adds LOOC back

* "fixes" missing items in some machinery.

* slight tweaks to abductor spawns
borer event enabled (max 1)

* Update .travis.yml

* fixes shuttle purchase from comms

* fixes and QoL

* Polymorphing all is dangerous too

* re-fixes ahelp ticket system again

* metagaming check proving to be spamlicious

* Fixes not being able to see devoured mob poses

* fix for vehicle buckling

* ahelp timer runtime fix (#178)

* controller and game updates 1/29

* Defines, helpers, datums 1/29

* world.dm updates

* modules/admin tweaks

* everything in modules not a mob

* modules/mob fixes and such

No more PAIs ventcrawling

* icons, maps, tools, etc.

* compiler fixes

* round type vote fixed

* hardsuit cargo pack

* reduce ion and electric storm chance

* perms access for travis

* fix helmet to the suit
removes CE from crate

* changelog

* fuck

* perms for travis... again

* Update tgstation.dme

* Update tgstation.dme

* Donation race

* redpanda

* red panda

* size play work

* Size chemical basics

Needs testing/refining

* some fixing ports before I just fucking ported it anyway

* It's been a fucking week.

* commiting moar changes because github

* admins.txt lol

* icons

* defines and such

* globalvars and onclick

* Controllers

* datums

* game folder

* oh look, HoG is back

* modules pt 1

* client things

* more modules

* everything not mob code

* some mob stuff

* more mob things

* silicon mobs

* ayylims and monkeys

* human updates

* huh

* housekeeping is fired.

* last minute fixes

* more last minute things

* human parts double check'd

* more paper

* Icons are fixed

* double check of thermal protection code. (#191)
This commit is contained in:
TalkingCactus
2017-02-03 06:56:14 -05:00
committed by Poojawa
parent 7735dec0ec
commit f7c09077d2
2489 changed files with 830965 additions and 416701 deletions
+23 -9
View File
@@ -6,6 +6,7 @@
var/buckle_requires_restraints = 0 //require people to be handcuffed before being able to buckle. eg: pipes
var/list/mob/living/buckled_mobs = null //list()
var/max_buckled_mobs = 1
var/buckle_prevents_pull = FALSE
//Interaction
/atom/movable/attack_hand(mob/living/user)
@@ -37,10 +38,17 @@
return TRUE
//procs that handle the actual buckling and unbuckling
/atom/movable/proc/buckle_mob(mob/living/M, force = 0)
/atom/movable/proc/buckle_mob(mob/living/M, force = 0, check_loc = 1)
if(!buckled_mobs)
buckled_mobs = list()
if((!can_buckle && !force) || !istype(M) || (M.loc != loc) || M.buckled || (buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src)
if(!istype(M))
return 0
if(check_loc && M.loc != loc)
return 0
if((!can_buckle && !force) || M.buckled || (buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src)
return 0
if(!M.can_buckle() && !force)
if(M == usr)
@@ -49,19 +57,25 @@
usr << "<span class='warning'>You are unable to buckle [M] to the [src]!</span>"
return 0
if(M.pulledby && buckle_prevents_pull)
M.pulledby.stop_pulling()
if(!check_loc && M.loc != loc)
M.forceMove(loc)
M.buckled = src
M.setDir(dir)
buckled_mobs |= M
M.update_canmove()
post_buckle_mob(M)
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
post_buckle_mob(M)
return 1
/obj/buckle_mob(mob/living/M, force = 0)
/obj/buckle_mob(mob/living/M, force = 0, check_loc = 1)
. = ..()
if(.)
if(burn_state == ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect
if(resistance_flags & ON_FIRE) //Sets the mob on fire if you buckle them to a burning atom/movableect
M.adjust_fire_stacks(1)
M.IgniteMob()
@@ -89,16 +103,16 @@
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user)
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = 1)
if(!in_range(user, src) || user.stat || user.restrained())
return 0
add_fingerprint(user)
if(buckle_mob(M))
if(buckle_mob(M, check_loc = check_loc))
if(M == user)
M.visible_message(\
"<span class='notice'>[M] buckles themself to [src].</span>",\
"<span class='notice'>[M] buckles [M.p_them()]self to [src].</span>",\
"<span class='notice'>You buckle yourself to [src].</span>",\
"<span class='italics'>You hear metal clanking.</span>")
else
@@ -119,7 +133,7 @@
"<span class='italics'>You hear metal clanking.</span>")
else
M.visible_message(\
"<span class='notice'>[M] unbuckles themselves from [src].</span>",\
"<span class='notice'>[M] unbuckles [M.p_them()]self from [src].</span>",\
"<span class='notice'>You unbuckle yourself from [src].</span>",\
"<span class='italics'>You hear metal clanking.</span>")
add_fingerprint(user)
+67 -53
View File
@@ -15,73 +15,87 @@
density = 0
opacity = 0
anchored = 1
unacidable = 1
var/atom/target
var/ticks = 0
var/target_strength = 0
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
layer = ABOVE_NORMAL_TURF_LAYER
var/turf/target
/obj/effect/acid/New(loc, targ)
/obj/effect/acid/New(loc, acid_pwr, acid_amt)
..(loc)
target = targ
target = get_turf(src)
if(acid_amt)
acid_level = min(acid_amt*acid_pwr, 12000) //capped so the acid effect doesn't last a half hour on the floor.
//handle APCs and newscasters and stuff nicely
pixel_x = target.pixel_x
pixel_y = target.pixel_y
pixel_x = target.pixel_x + rand(-4,4)
pixel_y = target.pixel_y + rand(-4,4)
if(isturf(target)) //Turfs take twice as long to take down.
target_strength = 640
else
target_strength = 320
tick()
START_PROCESSING(SSobj, src)
/obj/effect/acid/proc/tick()
/obj/effect/acid/Destroy()
STOP_PROCESSING(SSobj, src)
target = null
return ..()
/obj/effect/acid/process()
. = 1
if(!target)
qdel(src)
return 0
ticks++
if(prob(5))
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
if(ticks >= target_strength)
target.visible_message("<span class='warning'>[target] collapses under its own weight into a puddle of goop and undigested debris!</span>")
if(istype(target, /obj/structure/closet))
var/obj/structure/closet/T = target
T.dump_contents()
qdel(target)
if(istype(target, /turf/closed/mineral))
var/turf/closed/mineral/M = target
M.ChangeTurf(M.baseturf)
if(istype(target, /turf/open/floor))
var/turf/open/floor/F = target
F.ChangeTurf(F.baseturf)
if(istype(target, /turf/closed/wall))
var/turf/closed/wall/W = target
W.dismantle_wall(1)
else
qdel(target)
for(var/obj/O in target)
if(prob(20) && !(resistance_flags & UNACIDABLE))
if(O.acid_level < acid_level*0.3)
var/acid_used = min(acid_level*0.05, 20)
O.acid_act(10, acid_used)
acid_level = max(0, acid_level - acid_used*10)
acid_level = max(acid_level - (5 + 2*round(sqrt(acid_level))), 0)
if(acid_level <= 0)
qdel(src)
return
return 0
x = target.x
y = target.y
z = target.z
/obj/effect/acid/Crossed(AM as mob|obj)
if(isliving(AM))
var/mob/living/L = AM
if(L.movement_type & FLYING)
return
if(L.m_intent != MOVE_INTENT_WALK && prob(40))
var/acid_used = min(acid_level*0.05, 20)
if(L.acid_act(10, acid_used, "feet"))
acid_level = max(0, acid_level - acid_used*10)
playsound(L, 'sound/weapons/sear.ogg', 50, 1)
L << "<span class='userdanger'>[src] burns you!</span>"
switch(target_strength - ticks)
if(480)
visible_message("<span class='warning'>[target] is holding up against the acid!</span>")
if(320)
visible_message("<span class='warning'>[target] is being melted by the acid!</span>")
if(160)
visible_message("<span class='warning'>[target] is struggling to withstand the acid!</span>")
if(80)
visible_message("<span class='warning'>[target] begins to crumble under the acid!</span>")
//xenomorph corrosive acid
/obj/effect/acid/alien
var/target_strength = 30
spawn(1)
if(src)
tick()
/obj/effect/acid/alien/process()
. = ..()
if(.)
if(prob(45))
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
target_strength--
if(target_strength <= 0)
target.visible_message("<span class='warning'>[target] collapses under its own weight into a puddle of goop and undigested debris!</span>")
target.acid_melt()
qdel(src)
else
switch(target_strength)
if(24)
visible_message("<span class='warning'>[target] is holding up against the acid!</span>")
if(16)
visible_message("<span class='warning'>[target] is being melted by the acid!</span>")
if(8)
visible_message("<span class='warning'>[target] is struggling to withstand the acid!</span>")
if(4)
visible_message("<span class='warning'>[target] begins to crumble under the acid!</span>")
+101 -3
View File
@@ -4,39 +4,66 @@
name = "anomaly"
desc = "A mysterious anomaly, seen commonly only in the region of space that the station orbits..."
icon_state = "bhole3"
unacidable = 1
density = 0
anchored = 1
luminosity = 3
var/movechance = 70
var/obj/item/device/assembly/signaler/anomaly/aSignal = null
var/area/impact_area
var/lifespan = 990
var/death_time
var/countdown_colour
var/obj/effect/countdown/anomaly/countdown
/obj/effect/anomaly/New()
..()
poi_list |= src
set_light(initial(luminosity))
START_PROCESSING(SSobj, src)
impact_area = get_area(src)
SetLuminosity(initial(luminosity))
aSignal = new(src)
aSignal.name = "[name] core"
aSignal.code = rand(1,100)
aSignal.frequency = rand(1200, 1599)
if(IsMultiple(aSignal.frequency, 2))//signaller frequencies are always uneven!
aSignal.frequency++
death_time = world.time + lifespan
countdown = new(src)
if(countdown_colour)
countdown.color = countdown_colour
countdown.start()
/obj/effect/anomaly/process()
anomalyEffect()
if(death_time < world.time)
if(loc)
detonate()
qdel(src)
/obj/effect/anomaly/Destroy()
poi_list.Remove(src)
STOP_PROCESSING(SSobj, src)
qdel(countdown)
return ..()
/obj/effect/anomaly/proc/anomalyEffect()
if(prob(movechance))
step(src,pick(alldirs))
/obj/effect/anomaly/proc/detonate()
return
/obj/effect/anomaly/ex_act(severity, target)
if(severity == 1)
qdel(src)
/obj/effect/anomaly/proc/anomalyNeutralize()
PoolOrNew(/obj/effect/particle_effect/smoke/bad, loc)
new /obj/effect/particle_effect/smoke/bad(loc)
for(var/atom/movable/O in src)
O.loc = src.loc
@@ -135,6 +162,10 @@
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>")
/obj/effect/anomaly/flux/detonate()
explosion(src, 1, 4, 16, 18) //Low devastation, but hits a lot of stuff.
/////////////////////
/obj/effect/anomaly/bluespace
@@ -156,11 +187,64 @@
if(isliving(A))
do_teleport(A, locate(A.x, A.y, A.z), 8)
/obj/effect/anomaly/bluespace/detonate()
var/turf/T = safepick(get_area_turfs(impact_area))
if(T)
// Calculate new position (searches through beacons in world)
var/obj/item/device/radio/beacon/chosen
var/list/possible = list()
for(var/obj/item/device/radio/beacon/W in teleportbeacons)
possible += W
if(possible.len > 0)
chosen = pick(possible)
if(chosen)
// Calculate previous position for transition
var/turf/FROM = T // the turf of origin we're travelling FROM
var/turf/TO = get_turf(chosen) // the turf of origin we're travelling TO
playsound(TO, 'sound/effects/phasein.ogg', 100, 1)
priority_announce("Massive bluespace translocation detected.", "Anomaly Alert")
var/list/flashers = list()
for(var/mob/living/carbon/C in viewers(TO, null))
if(C.flash_act())
flashers += C
var/y_distance = TO.y - FROM.y
var/x_distance = TO.x - FROM.x
for (var/atom/movable/A in urange(12, FROM )) // iterate thru list of mobs in the area
if(istype(A, /obj/item/device/radio/beacon)) continue // don't teleport beacons because that's just insanely stupid
if(A.anchored) continue
var/turf/newloc = locate(A.x + x_distance, A.y + y_distance, TO.z) // calculate the new place
if(!A.Move(newloc) && newloc) // if the atom, for some reason, can't move, FORCE them to move! :) We try Move() first to invoke any movement-related checks the atom needs to perform after moving
A.loc = newloc
spawn()
if(ismob(A) && !(A in flashers)) // don't flash if we're already doing an effect
var/mob/M = A
if(M.client)
var/obj/blueeffect = new /obj(src)
blueeffect.screen_loc = "WEST,SOUTH to EAST,NORTH"
blueeffect.icon = 'icons/effects/effects.dmi'
blueeffect.icon_state = "shieldsparkles"
blueeffect.layer = FLASH_LAYER
blueeffect.plane = FULLSCREEN_PLANE
blueeffect.mouse_opacity = 0
M.client.screen += blueeffect
sleep(20)
M.client.screen -= blueeffect
qdel(blueeffect)
/////////////////////
/obj/effect/anomaly/pyro
name = "pyroclastic anomaly"
icon_state = "mustard"
var/ticks = 0
/obj/effect/anomaly/pyro/New()
..()
@@ -168,10 +252,24 @@
/obj/effect/anomaly/pyro/anomalyEffect()
..()
ticks++
if(ticks < 5)
return
else
ticks = 0
var/turf/open/T = get_turf(src)
if(istype(T))
T.atmos_spawn_air("o2=5;plasma=5;TEMP=1000")
/obj/effect/anomaly/pyro/detonate()
var/turf/open/T = get_turf(src)
if(istype(T))
T.atmos_spawn_air("o2=500;plasma=500;TEMP=1000") //Make it hot and burny for the new slime
var/new_colour = pick("red", "orange")
var/mob/living/simple_animal/slime/S = new(T, new_colour)
S.rabid = 1
/////////////////////
/obj/effect/anomaly/bhole
+17 -20
View File
@@ -103,7 +103,7 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
desc = "You probably shouldn't be holding this."
icon = 'icons/obj/contraband.dmi'
force = 0
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
var/serial_number = 0
var/obj/structure/sign/poster/resulting_poster = null //The poster that will be created is initialised and stored through contraband/poster's constructor
var/official = 0
@@ -201,7 +201,7 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
/obj/structure/sign/poster/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/wirecutters))
playsound(loc, 'sound/items/Wirecutter.ogg', 100, 1)
playsound(loc, I.usesound, 100, 1)
if(ruined)
user << "<span class='notice'>You remove the remnants of the poster.</span>"
qdel(src)
@@ -225,21 +225,16 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
add_fingerprint(user)
/obj/structure/sign/poster/proc/roll_and_drop(turf/location, official)
pixel_x = 0
pixel_y = 0
var/obj/item/weapon/poster/P
if (!official)
var/obj/item/weapon/poster/contraband/P = new(src, serial_number)
P.resulting_poster = src
P.loc = location
P.pixel_x = 0
P.pixel_y = 0
loc = P
P = new /obj/item/weapon/poster/contraband(src, serial_number)
else
var/obj/item/weapon/poster/legit/P = new(src, serial_number)
P.resulting_poster = src
P.loc = location
P.pixel_x = 0
P.pixel_y = 0
loc = P
P = new /obj/item/weapon/poster/legit(src, serial_number)
P.resulting_poster = src
P.forceMove(location)
loc = P
//seperated to reduce code duplication. Moved here for ease of reference and to unclutter r_wall/attackby()
/turf/closed/wall/proc/place_poster(obj/item/weapon/poster/P, mob/user)
@@ -261,7 +256,7 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
//declaring D because otherwise if P gets 'deconstructed' we lose our reference to P.resulting_poster
var/obj/structure/sign/poster/D = P.resulting_poster
var/temp_loc = user.loc
var/temp_loc = get_turf(user)
flick("poster_being_set",D)
D.loc = src
D.official = P.official
@@ -269,10 +264,12 @@ list(name = "- Carbon Dioxide", desc = " This informational poster teaches the v
playsound(D.loc, 'sound/items/poster_being_created.ogg', 100, 1)
if(do_after(user,D.placespeed,target=src))
if(!D)
if(!D || qdeleted(D))
return
if(istype(src,/turf/closed/wall) && user && user.loc == temp_loc) //Let's check if everything is still there
if(iswallturf(src) && user && user.loc == temp_loc) //Let's check if everything is still there
user << "<span class='notice'>You place the poster!</span>"
else
D.roll_and_drop(temp_loc,D.official)
return
D.roll_and_drop(temp_loc,D.official)
user << "<span class='notice'>The poster falls down!</span>"
+171
View File
@@ -0,0 +1,171 @@
/obj/effect/countdown
name = "countdown"
desc = "We're leaving together\n\
But still it's farewell\n\
And maybe we'll come back\n\
To earth, who can tell?"
var/displayed_text
var/atom/attached_to
color = "#ff0000"
var/text_size = 4
var/started = FALSE
invisibility = INVISIBILITY_OBSERVER
anchored = TRUE
layer = GHOST_LAYER
/obj/effect/countdown/New(atom/A)
. = ..()
attach(A)
/obj/effect/countdown/examine(mob/user)
. = ..()
user << "This countdown is displaying: [displayed_text]"
/obj/effect/countdown/proc/attach(atom/A)
attached_to = A
loc = get_turf(A)
/obj/effect/countdown/proc/start()
if(!started)
START_PROCESSING(SSfastprocess, src)
started = TRUE
/obj/effect/countdown/proc/stop()
if(started)
maptext = null
STOP_PROCESSING(SSfastprocess, src)
started = FALSE
/obj/effect/countdown/proc/get_value()
// Get the value from our atom
return
/obj/effect/countdown/process()
if(!attached_to || qdeleted(attached_to))
qdel(src)
forceMove(get_turf(attached_to))
var/new_val = get_value()
if(new_val == displayed_text)
return
displayed_text = new_val
if(displayed_text)
maptext = "<font size = [text_size]>[displayed_text]</font>"
else
maptext = null
/obj/effect/countdown/Destroy()
attached_to = null
STOP_PROCESSING(SSfastprocess, src)
. = ..()
/obj/effect/countdown/ex_act(severity, target) //immune to explosions
return
/obj/effect/countdown/syndicatebomb
name = "syndicate bomb countdown"
/obj/effect/countdown/syndicatebomb/get_value()
var/obj/machinery/syndicatebomb/S = attached_to
if(!istype(S))
return
else if(S.active)
return S.seconds_remaining()
/obj/effect/countdown/nuclearbomb
name = "nuclear bomb countdown"
color = "#81FF14"
/obj/effect/countdown/nuclearbomb/get_value()
var/obj/machinery/nuclearbomb/N = attached_to
if(!istype(N))
return
else if(N.timing)
return round(N.get_time_left(), 1)
/obj/effect/countdown/clonepod
name = "cloning pod countdown"
color = "#0C479D"
text_size = 1
/obj/effect/countdown/clonepod/get_value()
var/obj/machinery/clonepod/C = attached_to
if(!istype(C))
return
else if(C.occupant)
var/completion = round(C.get_completion())
return completion
/obj/effect/countdown/dominator
name = "dominator countdown"
text_size = 1
color = "#ff00ff" // Overwritten when the dominator starts
/obj/effect/countdown/dominator/get_value()
var/obj/machinery/dominator/D = attached_to
if(!istype(D))
return
else if(D.gang && D.gang.is_dominating)
var/timer = D.gang.domination_time_remaining()
return timer
else
return "OFFLINE"
/obj/effect/countdown/clockworkgate
name = "gateway countdown"
text_size = 1
color = "#BE8700"
layer = POINT_LAYER
/obj/effect/countdown/clockworkgate/get_value()
var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = attached_to
if(!istype(G))
return
else if(G.obj_integrity && !G.purpose_fulfilled)
return "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'>[G.get_arrival_text(FALSE)]</div>"
/obj/effect/countdown/supermatter
name = "supermatter damage"
text_size = 1
color = "#ED84F4"
/obj/effect/countdown/supermatter/get_value()
var/obj/machinery/power/supermatter_shard/S = attached_to
if(!istype(S))
return
return "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'>[round((S.damage / S.explosion_point) * 100)]</div>"
/obj/effect/countdown/transformer
name = "transformer countdown"
color = "#4C5866"
/obj/effect/countdown/transformer/get_value()
var/obj/machinery/transformer/T = attached_to
if(!istype(T))
return
else if(T.cooldown)
var/seconds_left = max(0, (T.cooldown_timer - world.time) / 10)
return "[round(seconds_left)]"
/obj/effect/countdown/doomsday
name = "doomsday countdown"
text_size = 3
/obj/effect/countdown/doomsday/get_value()
var/obj/machinery/doomsday_device/DD = attached_to
if(!istype(DD))
return
else if(DD.timing)
return "<div align='center' valign='middle' style='position:relative; top:0px; left:0px'>[DD.seconds_remaining()]</div>"
/obj/effect/countdown/anomaly
name = "anomaly countdown"
/obj/effect/countdown/anomaly/get_value()
var/obj/effect/anomaly/A = attached_to
if(!istype(A))
return
else
var/time_left = max(0, (A.death_time - world.time) / 10)
return round(time_left)
@@ -3,57 +3,45 @@
/obj/effect/decal/cleanable/xenoblood
name = "xeno blood"
desc = "It's green and acidic. It looks like... <i>blood?</i>"
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "xfloor1"
random_icon_states = list("xfloor1", "xfloor2", "xfloor3", "xfloor4", "xfloor5", "xfloor6", "xfloor7")
var/list/viruses = list()
blood_DNA = list("UNKNOWN DNA" = "X")
blood_DNA = list("UNKNOWN DNA" = "X*")
bloodiness = MAX_SHOE_BLOODINESS
blood_state = BLOOD_STATE_XENO
/obj/effect/decal/cleanable/xenoblood/can_bloodcrawl_in()
return 1
/obj/effect/decal/cleanable/xenoblood/Destroy()
for(var/datum/disease/D in viruses)
D.cure(0)
viruses = null
return ..()
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
spawn (0)
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
var/obj/effect/decal/cleanable/xenoblood/b = new /obj/effect/decal/cleanable/xenoblood/xsplatter(src.loc)
for(var/datum/disease/D in src.viruses)
var/datum/disease/ND = D.Copy(1)
b.viruses += ND
ND.holder = b
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/xenoblood/xsplatter
random_icon_states = list("xgibbl1", "xgibbl2", "xgibbl3", "xgibbl4", "xgibbl5")
/obj/effect/decal/cleanable/xsplatter/can_bloodcrawl_in()
return 1
/obj/effect/decal/cleanable/xenoblood/xgibs
name = "xeno gibs"
desc = "Gnarly..."
gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "xgib1"
layer = LOW_OBJ_LAYER
random_icon_states = list("xgib1", "xgib2", "xgib3", "xgib4", "xgib5", "xgib6")
mergeable_decal = 0
/obj/effect/decal/cleanable/xgibs/can_bloodcrawl_in()
return 1
/obj/effect/decal/cleanable/xenoblood/xgibs/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for(var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if (i > 0)
var/obj/effect/decal/cleanable/xenoblood/b = new /obj/effect/decal/cleanable/xenoblood/xsplatter(src.loc)
for(var/datum/disease/D in src.viruses)
var/datum/disease/ND = D.Copy(1)
b.viruses += ND
ND.holder = b
if (!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/xenoblood/xgibs/ex_act()
return
@@ -67,27 +55,22 @@
/obj/effect/decal/cleanable/xenoblood/xgibs/body
random_icon_states = list("xgibhead", "xgibtorso")
/obj/effect/decal/cleanable/xenoblood/xgibs/torso
random_icon_states = list("xgibtorso")
/obj/effect/decal/cleanable/xenoblood/xgibs/limb
random_icon_states = list("xgibleg", "xgibarm")
/obj/effect/decal/cleanable/xenoblood/xgibs/core
random_icon_states = list("xgibmid1", "xgibmid2", "xgibmid3")
/obj/effect/decal/cleanable/xenoblood/xgibs/larva
random_icon_states = list("xgiblarva1", "xgiblarva2")
/obj/effect/decal/cleanable/xenoblood/xgibs/larva/body
random_icon_states = list("xgiblarvahead", "xgiblarvatorso")
/obj/effect/decal/cleanable/blood/xtracks
icon_state = "xtracks"
random_icon_states = null
blood_DNA = list("UNKNOWN DNA" = "X")
/obj/effect/decal/cleanable/xdrip
name = "drips of blood"
desc = "It's green."
gender = PLURAL
icon = 'icons/effects/blood.dmi'
icon_state = "1"
random_icon_states = list("xdrip1","xdrip2","xdrip3","xdrip4","xdrip5")
bloodiness = 0
var/drips = 1
blood_DNA = list("UNKNOWN DNA" = "X")
/obj/effect/decal/cleanable/xdrip/can_bloodcrawl_in()
return 1
blood_DNA = list("UNKNOWN DNA" = "X*")
@@ -1,9 +1,6 @@
/obj/effect/decal/cleanable/blood
name = "blood"
desc = "It's red and gooey. Perhaps it's the chef's cooking?"
gender = PLURAL
density = 0
layer = ABOVE_NORMAL_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
@@ -29,16 +26,12 @@
/obj/effect/decal/cleanable/blood/tracks
icon_state = "tracks"
desc = "They look like tracks left by wheels."
gender = PLURAL
random_icon_states = null
/obj/effect/decal/cleanable/trail_holder //not a child of blood on purpose
name = "blood"
icon_state = "ltrails_1"
desc = "Your instincts say you shouldn't be following these."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
random_icon_states = null
var/list/existing_dirs = list()
blood_DNA = list()
@@ -51,23 +44,33 @@
/obj/effect/decal/cleanable/blood/gibs
name = "gibs"
desc = "They look bloody and gruesome."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "gibbl5"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = 0
/obj/effect/decal/cleanable/blood/gibs/New()
..()
reagents.add_reagent("liquidgibs", 5)
/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C)
return
/obj/effect/decal/cleanable/blood/gibs/ex_act(severity, target)
return
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if (i > 0)
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
for(var/datum/disease/D in src.viruses)
var/datum/disease/ND = D.Copy(1)
b.viruses += ND
ND.holder = b
if (!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -77,6 +80,10 @@
/obj/effect/decal/cleanable/blood/gibs/body
random_icon_states = list("gibhead", "gibtorso")
/obj/effect/decal/cleanable/blood/gibs/torso
random_icon_states = list("gibtorso")
/obj/effect/decal/cleanable/blood/gibs/limb
random_icon_states = list("gibleg", "gibarm")
@@ -84,24 +91,9 @@
random_icon_states = list("gibmid1", "gibmid2", "gibmid3")
/obj/effect/decal/cleanable/blood/gibs/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
if (i > 0)
var/obj/effect/decal/cleanable/blood/b = new /obj/effect/decal/cleanable/blood/splatter(src.loc)
for(var/datum/disease/D in src.viruses)
var/datum/disease/ND = D.Copy(1)
b.viruses += ND
ND.holder = b
if (step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/drip
name = "drips of blood"
desc = "It's red."
gender = PLURAL
icon_state = "1"
random_icon_states = list("drip1","drip2","drip3","drip4","drip5")
bloodiness = 0
@@ -118,7 +110,6 @@
icon = 'icons/effects/footprints.dmi'
icon_state = "nothingwhatsoever"
desc = "where might they lead?"
gender = PLURAL
random_icon_states = null
var/entered_dirs = 0
var/exited_dirs = 0
@@ -1,18 +1,15 @@
/obj/effect/decal/cleanable/generic
name = "clutter"
desc = "Someone should clean that up."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/obj/objects.dmi'
icon_state = "shards"
/obj/effect/decal/cleanable/ash
name = "ashes"
desc = "Ashes to ashes, dust to dust, and into space."
gender = PLURAL
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
mergeable_decal = 0
/obj/effect/decal/cleanable/ash/New()
..()
@@ -20,29 +17,29 @@
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
/obj/effect/decal/cleanable/ash/large
name = "large pile of ashes"
icon_state = "big_ash"
/obj/effect/decal/cleanable/ash/large/New()
..()
reagents.add_reagent("ash", 30) //double the amount of ash.
/obj/effect/decal/cleanable/dirt
name = "dirt"
desc = "Someone should clean that up."
icon_state = "dirt"
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
mouse_opacity = 0
/obj/effect/decal/cleanable/flour
name = "flour"
desc = "It's still good. Four second rule!"
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon_state = "flour"
/obj/effect/decal/cleanable/greenglow
name = "glowing goo"
desc = "Jeez. I hope that's not for lunch."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
luminosity = 1
icon_state = "greenglow"
@@ -52,45 +49,39 @@
/obj/effect/decal/cleanable/cobweb
name = "cobweb"
desc = "Somebody should remove that."
density = 0
layer = OBJ_LAYER
gender = NEUTER
layer = WALL_OBJ_LAYER
icon_state = "cobweb1"
burntime = 1
resistance_flags = FLAMMABLE
/obj/effect/decal/cleanable/cobweb/fire_act()
qdel(src)
/obj/effect/decal/cleanable/cobweb/cobweb2
icon_state = "cobweb2"
/obj/effect/decal/cleanable/molten_item
/obj/effect/decal/cleanable/molten_object
name = "gooey grey mass"
desc = "It looks like a melted... something."
density = 0
layer = OBJ_LAYER
icon = 'icons/obj/chemical.dmi'
gender = NEUTER
icon = 'icons/effects/effects.dmi'
icon_state = "molten"
mergeable_decal = 0
/obj/effect/decal/cleanable/cobweb2
name = "cobweb"
desc = "Somebody should remove that."
density = 0
layer = OBJ_LAYER
icon_state = "cobweb2"
/obj/effect/decal/cleanable/molten_object/large
name = "big gooey grey mass"
icon_state = "big_molten"
//Vomit (sorry)
/obj/effect/decal/cleanable/vomit
name = "vomit"
desc = "Gosh, how unpleasant."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/effects/blood.dmi'
icon_state = "vomit_1"
random_icon_states = list("vomit_1", "vomit_2", "vomit_3", "vomit_4")
var/list/viruses = list()
/obj/effect/decal/cleanable/vomit/attack_hand(var/mob/user)
if(istype(user,/mob/living/carbon/human))
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna.species.id == "fly")
if(isflyperson(H))
playsound(get_turf(src), 'sound/items/drink.ogg', 50, 1) //slurp
H.visible_message("<span class='alert'>[H] extends a small proboscis into the vomit pool, sucking it with a slurping sound.</span>")
if(reagents)
@@ -112,38 +103,34 @@
/obj/effect/decal/cleanable/tomato_smudge
name = "tomato smudge"
desc = "It's red."
density = 0
layer = ABOVE_OPEN_TURF_LAYER
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("tomato_floor1", "tomato_floor2", "tomato_floor3")
/obj/effect/decal/cleanable/plant_smudge
name = "plant smudge"
density = 0
layer = ABOVE_OPEN_TURF_LAYER
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_plant")
/obj/effect/decal/cleanable/egg_smudge
name = "smashed egg"
desc = "Seems like this one won't hatch."
density = 0
layer = ABOVE_OPEN_TURF_LAYER
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_egg1", "smashed_egg2", "smashed_egg3")
/obj/effect/decal/cleanable/pie_smudge //honk
name = "smashed pie"
desc = "It's pie cream from a cream pie."
density = 0
layer = ABOVE_OPEN_TURF_LAYER
gender = NEUTER
icon = 'icons/effects/tomatodecal.dmi'
random_icon_states = list("smashed_pie")
/obj/effect/decal/cleanable/chem_pile
name = "chemical pile"
desc = "A pile of chemicals. You can't quite tell what's inside it."
gender = PLURAL
gender = NEUTER
icon = 'icons/obj/objects.dmi'
icon_state = "ash"
@@ -152,12 +139,15 @@
desc = "The shredded remains of what appears to be clothing."
icon_state = "shreds"
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
mergeable_decal = 0
/obj/effect/decal/cleanable/shreds/ex_act(severity, target)
if(severity == 1) //so shreds created during an explosion aren't deleted by the explosion.
qdel(src)
/obj/effect/decal/cleanable/shreds/New()
pixel_x = rand(-5, 5)
pixel_y = rand(-5, 5)
pixel_x = rand(-10, 10)
pixel_y = rand(-10, 10)
..()
/obj/effect/decal/cleanable/salt
@@ -165,3 +155,4 @@
desc = "A sizable pile of table salt. Someone must be upset."
icon = 'icons/effects/tomatodecal.dmi'
icon_state = "salt_pile"
gender = NEUTER
@@ -3,20 +3,19 @@
/obj/effect/decal/cleanable/robot_debris
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/mob/robots.dmi'
icon_state = "gib1"
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
blood_state = BLOOD_STATE_OIL
bloodiness = MAX_SHOE_BLOODINESS
mergeable_decal = 0
/obj/effect/decal/cleanable/robot_debris/proc/streak(list/directions)
set waitfor = 0
var/direction = pick(directions)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50; 4), i++)
sleep(3)
for (var/i = 0, i < pick(1, 200; 2, 150; 3, 50), i++)
sleep(2)
if (i > 0)
if (prob(40))
new /obj/effect/decal/cleanable/oil/streak(src.loc)
@@ -24,7 +23,7 @@
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, src)
s.start()
if (step_to(src, get_step(src, direction), 0))
if (!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/robot_debris/ex_act()
@@ -42,9 +41,6 @@
/obj/effect/decal/cleanable/oil
name = "motor oil"
desc = "It's black and greasy. Looks like Beepsky made another mess."
gender = PLURAL
density = 0
layer = ABOVE_OPEN_TURF_LAYER
icon = 'icons/mob/robots.dmi'
icon_state = "floor1"
var/viruses = list()
@@ -1,7 +1,10 @@
/obj/effect/decal/cleanable
gender = PLURAL
layer = ABOVE_NORMAL_TURF_LAYER
var/list/random_icon_states = list()
var/blood_state = "" //I'm sorry but cleanable/blood code is ass, and so is blood_DNA
var/bloodiness = 0 //0-100, amount of blood in this decal, used for making footprints and affecting the alpha of bloody footprints
var/mergeable_decal = 1 //when two of these are on a same tile or do we need to merge them into just one?
/obj/effect/decal/cleanable/New()
if (random_icon_states && length(src.random_icon_states) > 0)
@@ -16,7 +19,8 @@
/obj/effect/decal/cleanable/proc/replace_decal(obj/effect/decal/cleanable/C)
qdel(C)
if(mergeable_decal)
qdel(C)
/obj/effect/decal/cleanable/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/reagent_containers/glass) || istype(W, /obj/item/weapon/reagent_containers/food/drinks))
@@ -42,6 +46,8 @@
src.reagents.chem_temp = min(src.reagents.chem_temp + added_heat, hotness)
src.reagents.handle_reactions()
user << "<span class='notice'>You heat [src] with [W]!</span>"
else
return ..()
/obj/effect/decal/cleanable/ex_act()
if(reagents)
@@ -49,7 +55,7 @@
R.on_ex_act()
..()
/obj/effect/decal/cleanable/fire_act()
/obj/effect/decal/cleanable/fire_act(exposed_temperature, exposed_volume)
if(reagents)
reagents.chem_temp += 30
reagents.handle_reactions()
+4 -12
View File
@@ -3,15 +3,9 @@
desc = "Graffiti. Damn kids."
icon = 'icons/effects/crayondecal.dmi'
icon_state = "rune1"
layer = ABOVE_NORMAL_TURF_LAYER
gender = NEUTER
var/do_icon_rotate = TRUE
/obj/effect/decal/cleanable/crayon/examine()
set src in view(2)
..()
return
/obj/effect/decal/cleanable/crayon/New(location, main = "#FFFFFF", var/type = "rune1", var/e_name = "rune", var/rotation = 0, var/alt_icon = null)
..()
loc = location
@@ -30,7 +24,7 @@
M.Turn(rotation)
src.transform = M
color = main
add_atom_colour(main, FIXED_COLOUR_PRIORITY)
/obj/effect/decal/cleanable/crayon/gang
@@ -43,14 +37,12 @@
qdel(src)
var/area/territory = get_area(location)
var/color
gang = G
color = G.color_hex
var/newcolor = G.color_hex
icon_state = G.name
G.territory_new |= list(territory.type = territory.name)
..(location, color, icon_state, e_name, rotation)
..(location, newcolor, icon_state, e_name, rotation)
/obj/effect/decal/cleanable/crayon/gang/Destroy()
var/area/territory = get_area(src)
+52 -1
View File
@@ -1,6 +1,57 @@
/obj/effect/decal
name = "decal"
anchored = 1
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/effect/decal/ex_act(severity, target)
qdel(src)
qdel(src)
/obj/effect/decal/fire_act(exposed_temperature, exposed_volume)
if(!(resistance_flags & FIRE_PROOF)) //non fire proof decal or being burned by lava
qdel(src)
/obj/effect/turf_decal
var/group = TURF_DECAL_PAINT
icon = 'icons/turf/decals.dmi'
icon_state = "warningline"
anchored = 1
//in case we need some special decals
/obj/effect/turf_decal/proc/get_decal()
return image(icon='icons/turf/decals.dmi',icon_state=icon_state,dir=dir,layer=TURF_LAYER)
/obj/effect/turf_decal/Initialize(mapload)
var/turf/T = loc
if(!istype(T)) //you know this will happen somehow
CRASH("Turf decal initialized in an object/nullspace")
T.add_decal(get_decal(),group)
qdel(src)
/obj/effect/turf_decal/stripes/line
icon_state = "warningline"
/obj/effect/turf_decal/stripes/end
icon_state = "warn_end"
/obj/effect/turf_decal/stripes/corner
icon_state = "warninglinecorner"
/obj/effect/turf_decal/stripes/asteroid/line
icon_state = "ast_warn"
/obj/effect/turf_decal/stripes/asteroid/end
icon_state = "ast_warn_end"
/obj/effect/turf_decal/stripes/asteroid/corner
icon_state = "ast_warn_corner"
/obj/effect/turf_decal/delivery
icon_state = "delivery"
/obj/effect/turf_decal/bot
icon_state = "bot"
/obj/effect/turf_decal/loading_area
icon_state = "loading_area"
@@ -11,6 +11,9 @@
desc = "They look like the remains of something... alien. They have a strange aura about them."
icon_state = "remainsxeno"
/obj/effect/decal/remains/xeno/larva
icon_state = "remainslarva"
/obj/effect/decal/remains/robot
desc = "They look like the remains of something mechanical. They have a strange aura about them."
icon = 'icons/mob/robots.dmi'
@@ -9,7 +9,6 @@ would spawn and follow the beaker, even if it is carried or thrown.
/obj/effect/particle_effect
name = "particle effect"
mouse_opacity = 0
unacidable = 1//So effects are not targeted by alien acid.
pass_flags = PASSTABLE | PASSGRILLE
/obj/effect/particle_effect/New()
@@ -20,8 +19,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
/obj/effect/particle_effect/Destroy()
if(ticker)
cameranet.updateVisibility(src)
..()
return QDEL_HINT_PUTINPOOL
. = ..()
/datum/effect_system
var/number = 3
@@ -53,12 +51,12 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/i in 1 to number)
if(total_effects > 20)
return
addtimer(src, "generate_effect", 0)
INVOKE_ASYNC(src, .proc/generate_effect)
/datum/effect_system/proc/generate_effect()
if(holder)
location = get_turf(holder)
var/obj/effect/E = PoolOrNew(effect_type, location)
var/obj/effect/E = new effect_type(location)
total_effects++
var/direction
if(cardinals)
@@ -69,7 +67,7 @@ would spawn and follow the beaker, even if it is carried or thrown.
for(var/j in 1 to steps_amt)
sleep(5)
step(E,direction)
addtimer(src, "decrement_total_effect", 20)
addtimer(CALLBACK(src, .proc/decrement_total_effect), 20)
/datum/effect_system/proc/decrement_total_effect()
total_effects--
@@ -48,6 +48,11 @@
var/datum/effect_system/expl_particles/P = new/datum/effect_system/expl_particles()
P.set_up(10, 0, location)
P.start()
/datum/effect_system/explosion/smoke
/datum/effect_system/explosion/smoke/start()
..()
spawn(5)
var/datum/effect_system/smoke_spread/S = new
S.set_up(2, location)
@@ -7,12 +7,17 @@
opacity = 0
anchored = 1
density = 0
layer = ABOVE_ALL_MOB_LAYER
layer = WALL_OBJ_LAYER
mouse_opacity = 0
var/amount = 3
animate_movement = 0
var/metal = 0
var/lifetime = 40
var/reagent_divisor = 7
var/static/list/blacklisted_turfs = typecacheof(list(
/turf/open/space/transit,
/turf/open/chasm,
/turf/open/floor/plating/lava))
/obj/effect/particle_effect/foam/metal
@@ -39,10 +44,11 @@
/obj/effect/particle_effect/foam/proc/kill_foam()
STOP_PROCESSING(SSfastprocess, src)
if(metal)
var/obj/structure/foamedmetal/M = new(src.loc)
M.metal = metal
M.updateicon()
switch(metal)
if(1)
new /obj/structure/foamedmetal(src.loc)
if(2)
new /obj/structure/foamedmetal/iron(src.loc)
flick("[icon_state]-disolve", src)
QDEL_IN(src, 5)
@@ -52,18 +58,24 @@
kill_foam()
return
var/fraction = 1/initial(lifetime)
var/fraction = 1/initial(reagent_divisor)
for(var/obj/O in range(0,src))
if(O.type == src.type)
continue
reagents.reaction(O, VAPOR, fraction)
if(isturf(O.loc))
var/turf/T = O.loc
if(T.intact && O.level == 1) //hidden under the floor
continue
if(lifetime % reagent_divisor)
reagents.reaction(O, VAPOR, fraction)
var/hit = 0
for(var/mob/living/L in range(0,src))
hit += foam_mob(L)
if(hit)
lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate.
var/T = get_turf(src)
reagents.reaction(T, VAPOR, fraction)
if(lifetime % reagent_divisor)
reagents.reaction(T, VAPOR, fraction)
if(--amount < 0)
return
@@ -74,8 +86,9 @@
return 0
if(!istype(L))
return 0
var/fraction = 1/initial(lifetime)
reagents.reaction(L, VAPOR, fraction)
var/fraction = 1/initial(reagent_divisor)
if(lifetime % reagent_divisor)
reagents.reaction(L, VAPOR, fraction)
lifetime--
return 1
@@ -95,12 +108,15 @@
if(foundfoam)
continue
if(is_type_in_typecache(T, blacklisted_turfs))
continue
for(var/mob/living/L in T)
foam_mob(L)
var/obj/effect/particle_effect/foam/F = PoolOrNew(src.type, T)
var/obj/effect/particle_effect/foam/F = new src.type(T)
F.amount = amount
reagents.copy_to(F, (reagents.total_volume))
F.color = color
F.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
F.metal = metal
@@ -128,7 +144,7 @@
/datum/effect_system/foam_spread/New()
..()
chemholder = PoolOrNew(/obj)
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(1000)
chemholder.reagents = R
R.my_atom = chemholder
@@ -139,7 +155,7 @@
return ..()
/datum/effect_system/foam_spread/set_up(amt=5, loca, datum/reagents/carry = null)
if(istype(loca, /turf/))
if(isturf(loca))
location = loca
else
location = get_turf(loca)
@@ -156,10 +172,10 @@
if(foundfoam)//If there was already foam where we start, we add our foaminess to it.
foundfoam.amount += amount
else
var/obj/effect/particle_effect/foam/F = PoolOrNew(effect_type, location)
var/obj/effect/particle_effect/foam/F = new effect_type(location)
var/foamcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
chemholder.reagents.copy_to(F, chemholder.reagents.total_volume/amount)
F.color = foamcolor
F.add_atom_colour(foamcolor, FIXED_COLOUR_PRIORITY)
F.amount = amount
F.metal = metal
@@ -172,11 +188,13 @@
density = 1
opacity = 1 // changed in New()
anchored = 1
unacidable = 1
resistance_flags = FIRE_PROOF | ACID_PROOF
name = "foamed metal"
desc = "A lightweight foamed metal wall."
gender = PLURAL
var/metal = 1 // 1=aluminium, 2=iron
obj_integrity = 20
max_integrity = 20
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/structure/foamedmetal/New()
..()
@@ -188,96 +206,27 @@
air_update_turf(1)
return ..()
/obj/structure/foamedmetal/Move()
var/turf/T = loc
..()
move_update_air(T)
/obj/structure/foamedmetal/proc/updateicon()
if(metal == 1)
icon_state = "metalfoam"
else
icon_state = "ironfoam"
/obj/structure/foamedmetal/ex_act(severity, target)
qdel(src)
/obj/structure/foamedmetal/blob_act(obj/effect/blob/B)
qdel(src)
/obj/structure/foamedmetal/bullet_act()
..()
if(metal==1 || prob(50))
qdel(src)
/obj/structure/foamedmetal/attack_paw(mob/user)
attack_hand(user)
/obj/structure/foamedmetal/attack_animal(mob/living/simple_animal/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
/obj/structure/foamedmetal/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
if(user.environment_smash >= 1)
user.do_attack_animation(src)
user << "<span class='notice'>You smash apart the foam wall.</span>"
qdel(src)
/obj/structure/foamedmetal/attack_hulk(mob/living/carbon/human/user)
..(user, 1)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
if(prob(75 - metal*25))
user.visible_message("<span class='danger'>[user] smashes through the foamed metal!</span>", \
"<span class='danger'>You smash through the metal foam wall!</span>")
qdel(src)
return 1
/obj/structure/foamedmetal/attack_alien(mob/living/carbon/alien/humanoid/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
if(prob(75 - metal*25))
user.visible_message("<span class='danger'>[user] smashes through the foamed metal!</span>", \
"<span class='danger'>You smash through the metal foam wall!</span>")
qdel(src)
/obj/structure/foamedmetal/attack_slime(mob/living/simple_animal/slime/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
if(!user.is_adult)
attack_hand(user)
return
if(prob(75 - metal*25))
user.visible_message("<span class='danger'>[user] smashes through the foamed metal!</span>", \
"<span class='danger'>You smash through the metal foam wall!</span>")
qdel(src)
/obj/structure/foamedmetal/attack_hand(mob/user)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
user.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
user << "<span class='warning'>You hit the metal foam but bounce off it!</span>"
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1)
/obj/structure/foamedmetal/attacked_by(obj/item/I, mob/living/user)
playsound(src.loc, 'sound/weapons/tap.ogg', 100, 1) //the item attack sound is muffled by the foam.
if(prob(I.force*20 - metal*25))
user.visible_message("<span class='danger'>[user] smashes through the foamed metal!</span>", \
"<span class='danger'>You smash through the foamed metal with \the [I]!</span>")
qdel(src)
else
user << "<span class='warning'>You hit the metal foam to no effect!</span>"
/obj/structure/foamedmetal/CanPass(atom/movable/mover, turf/target, height=1.5)
return !density
/obj/structure/foamedmetal/CanAtmosPass()
return !density
/obj/structure/foamedmetal/iron
obj_integrity = 50
max_integrity = 50
icon_state = "ironfoam"
@@ -36,7 +36,7 @@
if(processing)
processing = 0
if(number < 3)
var/obj/effect/particle_effect/steam/I = PoolOrNew(/obj/effect/particle_effect/steam, oldposition)
var/obj/effect/particle_effect/steam/I = new /obj/effect/particle_effect/steam(oldposition)
number++
I.setDir(holder.dir)
oldposition = get_turf(holder)
@@ -53,8 +53,14 @@
icon_state = "ion_trails"
anchored = 1
/obj/effect/particle_effect/ion_trails/flight
icon_state = "ion_trails_flight"
/datum/effect_system/trail_follow/ion
effect_type = /obj/effect/particle_effect/ion_trails
var/fadetype = "ion_fade"
var/fade = 1
var/nograv_required = 1
/datum/effect_system/trail_follow/ion/start() //Whoever is responsible for this abomination of code should become an hero
if(!on)
@@ -66,11 +72,12 @@
processing = 0
var/turf/T = get_turf(holder)
if(T != oldposition)
if(!has_gravity(T))
var/obj/effect/particle_effect/ion_trails/I = PoolOrNew(effect_type, oldposition)
I.setDir(holder.dir)
flick("ion_fade", I)
I.icon_state = ""
if(!T.has_gravity() || !nograv_required)
var/obj/effect/particle_effect/ion_trails/I = new effect_type(oldposition)
set_dir(I)
if(fade)
flick(fadetype, I)
I.icon_state = ""
spawn(20)
qdel(I)
oldposition = T
@@ -79,7 +86,18 @@
processing = 1
start()
/datum/effect_system/trail_follow/ion/proc/set_dir(obj/effect/particle_effect/ion_trails/I)
I.setDir(holder.dir)
/datum/effect_system/trail_follow/ion/flight
effect_type = /obj/effect/particle_effect/ion_trails/flight
fadetype = "ion_fade_flight"
nograv_required = 0
/datum/effect_system/trail_follow/ion/flight/set_dir(obj/effect/particle_effect/ion_trails/I)
if(istype(holder, /obj/item/device/flightpack))
var/obj/item/device/flightpack/F = holder
I.setDir(F.suit.user.dir)
//Reagent-based explosion effect
@@ -105,7 +123,7 @@
if(explosion_message)
location.visible_message("<span class='danger'>The solution violently explodes!</span>", \
"<span class='italics'>You hear an explosion!</span>")
if (amount <= 2)
if (amount < 1)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
@@ -116,22 +134,4 @@
M.Weaken(rand(1,5))
return
else
var/devastation = -1
var/heavy = -1
var/light = -1
var/flash = -1
// Clamp all values to MAX_EXPLOSION_RANGE
if (round(amount/12) > 0)
devastation = min (MAX_EX_DEVESTATION_RANGE, devastation + round(amount/12))
if (round(amount/6) > 0)
heavy = min (MAX_EX_HEAVY_RANGE, heavy + round(amount/6))
if (round(amount/3) > 0)
light = min (MAX_EX_LIGHT_RANGE, light + round(amount/3))
if (flashing && flashing_factor)
flash += (round(amount/4) * flashing_factor)
explosion(location, devastation, heavy, light, flash)
dyn_explosion(location, amount, flashing_factor)
@@ -9,6 +9,7 @@
pixel_x = -32
pixel_y = -32
opacity = 0
layer = FLY_LAYER
anchored = 1
mouse_opacity = 0
animate_movement = 0
@@ -25,6 +26,8 @@
var/step = alpha / frames
for(var/i = 0, i < frames, i++)
alpha -= step
if(alpha < 160)
opacity = 0 //if we were blocking view, we aren't now because we're fading out
stoplag()
/obj/effect/particle_effect/smoke/New()
@@ -39,7 +42,7 @@
/obj/effect/particle_effect/smoke/proc/kill_smoke()
STOP_PROCESSING(SSobj, src)
addtimer(src, "fade_out", 0)
INVOKE_ASYNC(src, .proc/fade_out)
QDEL_IN(src, 10)
/obj/effect/particle_effect/smoke/process()
@@ -61,7 +64,7 @@
if(C.smoke_delay)
return 0
C.smoke_delay++
addtimer(src, "remove_smoke_delay", 10, FALSE, C)
addtimer(CALLBACK(src, .proc/remove_smoke_delay, C), 10)
return 1
/obj/effect/particle_effect/smoke/proc/remove_smoke_delay(mob/living/carbon/C)
@@ -81,7 +84,7 @@
reagents.copy_to(S, reagents.total_volume)
S.setDir(pick(cardinal))
S.amount = amount-1
S.color = color
S.add_atom_colour(color, FIXED_COLOUR_PRIORITY)
S.lifetime = lifetime
if(S.amount>0)
if(opaque)
@@ -154,7 +157,7 @@
var/blast = 0
/datum/effect_system/smoke_spread/freezing/proc/Chilled(atom/A)
if(istype(A,/turf/open))
if(isopenturf(A))
var/turf/open/T = A
if(T.air)
var/datum/gas_mixture/G = T.air
@@ -224,6 +227,8 @@
for(var/atom/movable/AM in T)
if(AM.type == src.type)
continue
if(T.intact && AM.level == 1) //hidden under the floor
continue
reagents.reaction(AM, TOUCH, fraction)
reagents.reaction(T, TOUCH, fraction)
@@ -250,7 +255,7 @@
/datum/effect_system/smoke_spread/chem/New()
..()
chemholder = PoolOrNew(/obj)
chemholder = new /obj()
var/datum/reagents/R = new/datum/reagents(500)
chemholder.reagents = R
R.my_atom = chemholder
@@ -261,7 +266,7 @@
return ..()
/datum/effect_system/smoke_spread/chem/set_up(datum/reagents/carry = null, radius = 1, loca, silent = 0)
if(istype(loca, /turf/))
if(isturf(loca))
location = loca
else
location = get_turf(loca)
@@ -284,15 +289,15 @@
var/more = ""
if(M)
more = "(<A HREF='?_src_=holder;adminmoreinfo=\ref[M]'>?</a>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) "
message_admins("A chemical smoke reaction has taken place in ([whereLink])[contained]. Last associated key is [carry.my_atom.fingerprintslast][more].", 0, 1)
message_admins("Smoke: ([whereLink])[contained]. Key: [carry.my_atom.fingerprintslast][more].", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. Last associated key is [carry.my_atom.fingerprintslast].")
else
message_admins("A chemical smoke reaction has taken place in ([whereLink]). No associated key.", 0, 1)
message_admins("Smoke: ([whereLink])[contained]. No associated key.", 0, 1)
log_game("A chemical smoke reaction has taken place in ([where])[contained]. No associated key.")
/datum/effect_system/smoke_spread/chem/start()
var/color = mix_color_from_reagents(chemholder.reagents.reagent_list)
var/mixcolor = mix_color_from_reagents(chemholder.reagents.reagent_list)
if(holder)
location = get_turf(holder)
var/obj/effect/particle_effect/smoke/chem/S = new effect_type(location)
@@ -300,9 +305,20 @@
if(chemholder.reagents.total_volume > 1) // can't split 1 very well
chemholder.reagents.copy_to(S, chemholder.reagents.total_volume)
if(color)
S.color = color // give the smoke color, if it has any to begin with
if(mixcolor)
S.add_atom_colour(mixcolor, FIXED_COLOUR_PRIORITY) // give the smoke color, if it has any to begin with
S.amount = amount
if(S.amount)
S.spread_smoke() //calling process right now so the smoke immediately attacks mobs.
/////////////////////////////////////////////
// Transparent smoke
/////////////////////////////////////////////
//Same as the base type, but the smoke produced is not opaque
/datum/effect_system/smoke_spread/transparent
effect_type = /obj/effect/particle_effect/smoke/transparent
/obj/effect/particle_effect/smoke/transparent
opaque = FALSE
@@ -15,20 +15,20 @@
..()
flick("sparks", src) // replay the animation
playsound(src.loc, "sparks", 100, 1)
var/turf/T = src.loc
if (istype(T, /turf))
var/turf/T = loc
if(isturf(T))
T.hotspot_expose(1000,100)
QDEL_IN(src, 20)
/obj/effect/particle_effect/sparks/Destroy()
var/turf/T = src.loc
if (istype(T, /turf))
var/turf/T = loc
if(isturf(T))
T.hotspot_expose(1000,100)
return ..()
/obj/effect/particle_effect/sparks/Move()
..()
var/turf/T = src.loc
var/turf/T = loc
if(isturf(T))
T.hotspot_expose(1000,100)
+44
View File
@@ -0,0 +1,44 @@
//objects in /obj/effect should never be things that are attackable, use obj/structure instead.
//Effects are mostly temporary visual effects like sparks, smoke, as well as decals, etc...
/obj/effect
icon = 'icons/effects/effects.dmi'
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
/obj/effect/attackby(obj/item/I, mob/living/user, params)
return
/obj/effect/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
return
/obj/effect/fire_act(exposed_temperature, exposed_volume)
return
/obj/effect/acid_act()
return
/obj/effect/mech_melee_attack(obj/mecha/M)
return 0
/obj/effect/blob_act()
return
/obj/effect/ex_act(severity, target)
if(target == src)
qdel(src)
else
switch(severity)
if(1)
qdel(src)
if(2)
if(prob(60))
qdel(src)
if(3)
if(prob(25))
qdel(src)
/obj/effect/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
return 0
/obj/effect/experience_pressure_difference()
return
+1 -4
View File
@@ -5,10 +5,7 @@
anchored = 1
opacity = 0
density = 1
unacidable = 1
/obj/effect/forcefield/CanAtmosPass(turf/T)
return !density
CanAtmosPass = ATMOS_PASS_DENSITY
/obj/effect/forcefield/cult
desc = "An unholy shield that blocks all attacks."
-62
View File
@@ -1,62 +0,0 @@
/proc/gibs(atom/location, list/viruses, datum/dna/MobDNA)
new /obj/effect/gibspawner/generic(location,viruses,MobDNA)
/proc/hgibs(atom/location, list/viruses, datum/dna/MobDNA)
new /obj/effect/gibspawner/human(location,viruses,MobDNA)
/proc/xgibs(atom/location, list/viruses)
new /obj/effect/gibspawner/xeno(location,viruses)
/proc/robogibs(atom/location, list/viruses)
new /obj/effect/gibspawner/robot(location,viruses)
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread on Gib()
var/virusProb = 20 //the chance for viruses to spread on the gibs
var/list/gibtypes = list()
var/list/gibamounts = list()
var/list/gibdirections = list() //of lists
/obj/effect/gibspawner/New(location, var/list/viruses, var/datum/dna/MobDNA)
..()
Gib(loc,viruses,MobDNA)
/obj/effect/gibspawner/proc/Gib(atom/location, list/viruses = list(), datum/dna/MobDNA = null)
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
world << "<span class='danger'>Gib list length mismatch!</span>"
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
if(sparks)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
var/gibType = gibtypes[i]
gib = new gibType(location)
if(istype(location,/mob/living/carbon))
var/mob/living/carbon/digester = location
digester.stomach_contents += gib
if(viruses.len > 0)
for(var/datum/disease/D in viruses)
if(prob(virusProb))
var/datum/disease/viruus = D.Copy(1)
gib.viruses += viruus
viruus.holder = gib
if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
var/list/directions = gibdirections[i]
if(istype(loc,/turf))
if(directions.len)
gib.streak(directions)
qdel(src)
+26 -40
View File
@@ -4,7 +4,7 @@ var/list/blacklisted_glowshroom_turfs = typecacheof(list(
/turf/open/floor/plating/lava,
/turf/open/floor/plating/beach/water))
/obj/effect/glowshroom
/obj/structure/glowshroom
name = "glowshroom"
desc = "Mycena Bregprox, a species of mushroom that glows in the dark."
anchored = 1
@@ -13,7 +13,8 @@ var/list/blacklisted_glowshroom_turfs = typecacheof(list(
icon = 'icons/obj/lighting.dmi'
icon_state = "glowshroom" //replaced in New
layer = ABOVE_NORMAL_TURF_LAYER
var/endurance = 30
obj_integrity = 30
max_integrity = 30
var/potency = 30
var/delay = 1200
var/floor = 0
@@ -21,20 +22,20 @@ var/list/blacklisted_glowshroom_turfs = typecacheof(list(
var/generation = 1
var/spreadIntoAdjacentChance = 60
obj/effect/glowshroom/glowcap
/obj/structure/glowshroom/glowcap
name = "glowcap"
icon_state = "glowcap"
/obj/effect/glowshroom/single
/obj/structure/glowshroom/single
yield = 0
/obj/effect/glowshroom/examine(mob/user)
/obj/structure/glowshroom/examine(mob/user)
. = ..()
user << "This is a [generation]\th generation [name]!"
/obj/effect/glowshroom/New()
/obj/structure/glowshroom/New()
..()
set_light(round(potency/10))
SetLuminosity(round(potency/10))
setDir(CalcDir())
var/base_icon_state = initial(icon_state)
if(!floor)
@@ -51,9 +52,9 @@ obj/effect/glowshroom/glowcap
else //if on the floor, glowshroom on-floor sprite
icon_state = "[base_icon_state]f"
addtimer(src, "Spread", delay)
addtimer(CALLBACK(src, .proc/Spread), delay)
/obj/effect/glowshroom/proc/Spread()
/obj/structure/glowshroom/proc/Spread()
for(var/i = 1 to yield)
if(prob(1/(generation * generation) * 100))//This formula gives you diminishing returns based on generation. 100% with 1st gen, decreasing to 25%, 11%, 6, 4, 2...
var/list/possibleLocs = list()
@@ -65,7 +66,7 @@ obj/effect/glowshroom/glowcap
for(var/turf/open/floor/earth in view(3,src))
if(is_type_in_typecache(earth, blacklisted_glowshroom_turfs))
continue
if(spreadsIntoAdjacent || !locate(/obj/effect/glowshroom) in view(1,earth))
if(spreadsIntoAdjacent || !locate(/obj/structure/glowshroom) in view(1,earth))
possibleLocs += earth
CHECK_TICK
@@ -76,7 +77,7 @@ obj/effect/glowshroom/glowcap
var/shroomCount = 0 //hacky
var/placeCount = 1
for(var/obj/effect/glowshroom/shroom in newLoc)
for(var/obj/structure/glowshroom/shroom in newLoc)
shroomCount++
for(var/wallDir in cardinal)
var/turf/isWall = get_step(newLoc,wallDir)
@@ -85,16 +86,18 @@ obj/effect/glowshroom/glowcap
if(shroomCount >= placeCount)
continue
var/obj/effect/glowshroom/child = new type(newLoc)//The baby mushrooms have different stats :3
var/obj/structure/glowshroom/child = new type(newLoc)//The baby mushrooms have different stats :3
child.potency = max(potency + rand(-3,6), 0)
child.yield = max(yield + rand(-1,2), 0)
child.delay = max(delay + rand(-30,60), 0)
child.endurance = max(endurance + rand(-3,6), 1)
var/newhealth = max(obj_integrity + rand(-3,6), 1)
child.obj_integrity = newhealth
child.max_integrity = newhealth
child.generation = generation + 1
CHECK_TICK
/obj/effect/glowshroom/proc/CalcDir(turf/location = loc)
/obj/structure/glowshroom/proc/CalcDir(turf/location = loc)
var/direction = 16
for(var/wallDir in cardinal)
@@ -102,7 +105,7 @@ obj/effect/glowshroom/glowcap
if(newTurf.density)
direction |= wallDir
for(var/obj/effect/glowshroom/shroom in location)
for(var/obj/structure/glowshroom/shroom in location)
if(shroom == src)
continue
if(shroom.floor) //special
@@ -126,34 +129,17 @@ obj/effect/glowshroom/glowcap
floor = 1
return 1
/obj/effect/glowshroom/attacked_by(obj/item/I, mob/user)
..()
if(I.damtype != STAMINA)
endurance -= I.force
CheckEndurance()
/obj/structure/glowshroom/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
if(damage_type == BURN && damage_amount)
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
/obj/effect/glowshroom/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
if(2)
if(prob(50))
qdel(src)
if(3)
if(prob(5))
qdel(src)
/obj/effect/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
/obj/structure/glowshroom/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
endurance -= 5
CheckEndurance()
take_damage(5, BURN, 0, 0)
/obj/effect/glowshroom/proc/CheckEndurance()
if(endurance <= 0)
qdel(src)
/obj/effect/glowshroom/acid_act(acidpwr, toxpwr, acid_volume)
/obj/structure/glowshroom/acid_act(acidpwr, acid_volume)
. = 1
visible_message("<span class='danger'>[src] melts away!</span>")
var/obj/effect/decal/cleanable/molten_item/I = new (get_turf(src))
var/obj/effect/decal/cleanable/molten_object/I = new (get_turf(src))
I.desc = "Looks like this was \an [src] some time ago."
qdel(src)
+2 -4
View File
@@ -3,7 +3,6 @@
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x2"
anchored = 1
unacidable = 1
invisibility = INVISIBILITY_ABSTRACT
/obj/effect/landmark/New()
@@ -75,9 +74,9 @@
anchored = 1
/obj/effect/landmark/start/New()
start_landmarks_list += src
..()
tag = "start*[name]"
start_landmarks_list += src
return 1
/obj/effect/landmark/start/Destroy()
@@ -109,7 +108,6 @@
new /obj/item/clothing/under/gimmick/rank/captain/suit(src.loc)
new /obj/item/clothing/head/flatcap(src.loc)
new /obj/item/clothing/suit/toggle/labcoat/mad(src.loc)
new /obj/item/clothing/glasses/gglasses(src.loc)
qdel(src)
/obj/effect/landmark/costume/elpresidente/New()
@@ -126,7 +124,7 @@
qdel(src)
/obj/effect/landmark/costume/maid/New()
new /obj/item/clothing/under/blackskirt(src.loc)
new /obj/item/clothing/under/skirt/black(src.loc)
var/CHOICE = pick( /obj/item/clothing/head/beret , /obj/item/clothing/head/rabbitears )
new CHOICE(src.loc)
new /obj/item/clothing/glasses/sunglasses/blindfold(src.loc)
-1
View File
@@ -2,7 +2,6 @@
name = "manifest"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "x"
unacidable = 1//Just to be sure.
/obj/effect/manifest/New()
src.invisibility = INVISIBILITY_ABSTRACT
+12 -12
View File
@@ -11,10 +11,10 @@
victim << "<span class='danger'>*click*</span>"
/obj/effect/mine/Crossed(AM as mob|obj)
if(isanimal(AM))
var/mob/living/simple_animal/SA = AM
if(!SA.flying)
triggermine(SA)
if(ismob(AM))
var/mob/MM = AM
if(!(MM.movement_type & FLYING))
triggermine(AM)
else
triggermine(AM)
@@ -55,7 +55,7 @@
/obj/effect/mine/kickmine/mineEffect(mob/victim)
if(isliving(victim) && victim.client)
victim << "<span class='userdanger'>You have been kicked FOR NO REISIN!</span>"
del(victim.client)
qdel(victim.client)
/obj/effect/mine/gas
@@ -114,7 +114,7 @@
name = "Red Orb"
desc = "You feel angry just looking at it."
duration = 1200 //2min
color = "red"
color = "#FF0000"
/obj/effect/mine/pickup/bloodbath/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
@@ -130,10 +130,10 @@
var/obj/item/weapon/twohanded/required/chainsaw/doomslayer/chainsaw = new(victim.loc)
chainsaw.flags |= NODROP
victim.drop_r_hand()
victim.drop_l_hand()
victim.drop_all_held_items()
victim.put_in_hands(chainsaw)
chainsaw.attack_self(victim)
chainsaw.wield(victim)
victim.reagents.add_reagent("adminordrazine",25)
victim.client.color = pure_red
@@ -148,7 +148,7 @@
/obj/effect/mine/pickup/healing
name = "Blue Orb"
desc = "You feel better just looking at it."
color = "blue"
color = "#0000FF"
/obj/effect/mine/pickup/healing/mineEffect(mob/living/carbon/victim)
if(!victim.client || !istype(victim))
@@ -159,7 +159,7 @@
/obj/effect/mine/pickup/speed
name = "Yellow Orb"
desc = "You feel faster just looking at it."
color = "yellow"
color = "#FFFF00"
duration = 300
/obj/effect/mine/pickup/speed/mineEffect(mob/living/carbon/victim)
@@ -169,4 +169,4 @@
victim.status_flags |= GOTTAGOREALLYFAST
sleep(duration)
victim.status_flags &= ~GOTTAGOREALLYFAST
victim << "<span class='notice'>You slow down.</span>"
victim << "<span class='notice'>You slow down.</span>"
-1
View File
@@ -9,7 +9,6 @@
/obj/effect/beam
name = "beam"
unacidable = 1//Just to be sure.
var/def_zone
pass_flags = PASSTABLE
+451 -209
View File
@@ -1,6 +1,5 @@
/obj/effect/overlay
name = "overlay"
unacidable = 1
var/i_attached//Added for possible image attachments to objects. For hallucinations and the like.
/obj/effect/overlay/singularity_act()
@@ -29,9 +28,8 @@
var/timerid
/obj/effect/overlay/temp/Destroy()
..()
. = ..()
deltimer(timerid)
return QDEL_HINT_PUTINPOOL
/obj/effect/overlay/temp/New()
..()
@@ -41,17 +39,29 @@
timerid = QDEL_IN(src, duration)
/obj/effect/overlay/temp/bloodsplatter
/obj/effect/overlay/temp/ex_act()
return
/obj/effect/overlay/temp/dir_setting
randomdir = FALSE
/obj/effect/overlay/temp/dir_setting/New(loc, set_dir)
if(set_dir)
setDir(set_dir)
..()
/obj/effect/overlay/temp/dir_setting/bloodsplatter
icon = 'icons/effects/blood.dmi'
duration = 5
randomdir = FALSE
layer = BELOW_MOB_LAYER
var/splatter_type = "splatter"
/obj/effect/overlay/temp/bloodsplatter/New(loc, set_dir)
/obj/effect/overlay/temp/dir_setting/bloodsplatter/New(loc, set_dir)
if(set_dir in diagonals)
icon_state = "splatter[pick(1, 2, 6)]"
icon_state = "[splatter_type][pick(1, 2, 6)]"
else
icon_state = "splatter[pick(3, 4, 5)]"
icon_state = "[splatter_type][pick(3, 4, 5)]"
..()
var/target_pixel_x = 0
var/target_pixel_y = 0
@@ -79,9 +89,412 @@
target_pixel_x = -16
target_pixel_y = -16
layer = ABOVE_MOB_LAYER
setDir(set_dir)
animate(src, pixel_x = target_pixel_x, pixel_y = target_pixel_y, alpha = 0, time = duration)
/obj/effect/overlay/temp/dir_setting/bloodsplatter/xenosplatter
splatter_type = "xsplatter"
/obj/effect/overlay/temp/dir_setting/firing_effect
icon = 'icons/effects/effects.dmi'
icon_state = "firing_effect"
duration = 2
/obj/effect/overlay/temp/dir_setting/firing_effect/setDir(newdir)
switch(newdir)
if(NORTH)
layer = BELOW_MOB_LAYER
pixel_x = rand(-3,3)
pixel_y = rand(4,6)
if(SOUTH)
pixel_x = rand(-3,3)
pixel_y = rand(-1,1)
else
pixel_x = rand(-1,1)
pixel_y = rand(-1,1)
..()
/obj/effect/overlay/temp/dir_setting/firing_effect/energy
icon_state = "firing_effect_energy"
duration = 3
/obj/effect/overlay/temp/dir_setting/firing_effect/magic
icon_state = "shieldsparkles"
duration = 3
/obj/effect/overlay/temp/dir_setting/ninja
name = "ninja shadow"
icon = 'icons/mob/mob.dmi'
icon_state = "uncloak"
duration = 9
/obj/effect/overlay/temp/dir_setting/ninja/cloak
icon_state = "cloak"
/obj/effect/overlay/temp/dir_setting/ninja/shadow
icon_state = "shadow"
/obj/effect/overlay/temp/dir_setting/ninja/phase
name = "ninja energy"
icon_state = "phasein"
/obj/effect/overlay/temp/dir_setting/ninja/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/dir_setting/wraith
name = "blood"
icon = 'icons/mob/mob.dmi'
icon_state = "phase_shift2"
duration = 12
/obj/effect/overlay/temp/dir_setting/wraith/out
icon_state = "phase_shift"
/obj/effect/overlay/temp/dir_setting/tailsweep
icon_state = "tailsweep"
duration = 4
/obj/effect/overlay/temp/wizard
name = "water"
icon = 'icons/mob/mob.dmi'
icon_state = "reappear"
duration = 5
/obj/effect/overlay/temp/wizard/out
icon_state = "liquify"
duration = 12
/obj/effect/overlay/temp/monkeyify
icon = 'icons/mob/mob.dmi'
icon_state = "h2monkey"
duration = 22
/obj/effect/overlay/temp/monkeyify/humanify
icon_state = "monkey2h"
/obj/effect/overlay/temp/borgflash
icon = 'icons/mob/mob.dmi'
icon_state = "blspell"
duration = 5
/obj/effect/overlay/temp/guardian
randomdir = 0
/obj/effect/overlay/temp/guardian/phase
duration = 5
icon_state = "phasein"
/obj/effect/overlay/temp/guardian/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/decoy
desc = "It's a decoy!"
duration = 15
/obj/effect/overlay/temp/decoy/New(loc, atom/mimiced_atom)
..()
alpha = initial(alpha)
if(mimiced_atom)
name = mimiced_atom.name
appearance = mimiced_atom.appearance
setDir(mimiced_atom.dir)
mouse_opacity = 0
/obj/effect/overlay/temp/decoy/fading/New(loc, atom/mimiced_atom)
..()
animate(src, alpha = 0, time = duration)
/obj/effect/overlay/temp/decoy/fading/fivesecond
duration = 50
/obj/effect/overlay/temp/small_smoke
icon_state = "smoke"
duration = 50
/obj/effect/overlay/temp/cult
randomdir = 0
duration = 10
/obj/effect/overlay/temp/cult/sparks
randomdir = 1
name = "blood sparks"
icon_state = "bloodsparkles"
/obj/effect/overlay/temp/dir_setting/cult/phase
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/overlay/temp/dir_setting/cult/phase/out
icon_state = "cultout"
/obj/effect/overlay/temp/cult/sac
name = "maw of Nar-Sie"
icon_state = "sacconsume"
/obj/effect/overlay/temp/cult/door
name = "unholy glow"
icon_state = "doorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/cult/door/unruned
icon_state = "unruneddoorglow"
/obj/effect/overlay/temp/cult/turf
name = "unholy glow"
icon_state = "wallglow"
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/cult/turf/floor
icon_state = "floorglow"
duration = 5
/obj/effect/overlay/temp/ratvar
name = "ratvar's light"
icon = 'icons/effects/clockwork_effects.dmi'
duration = 8
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/ratvar/door
icon_state = "ratvardoorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/ratvar/door/window
icon_state = "ratvarwindoorglow"
/obj/effect/overlay/temp/ratvar/beam
icon_state = "ratvarbeamglow"
/obj/effect/overlay/temp/ratvar/beam/door
layer = CLOSED_DOOR_LAYER
/obj/effect/overlay/temp/ratvar/beam/grille
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/itemconsume
layer = HIGH_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/falsewall
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/beam/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/wall
icon_state = "ratvarwallglow"
/obj/effect/overlay/temp/ratvar/wall/false
layer = OBJ_LAYER
/obj/effect/overlay/temp/ratvar/floor
icon_state = "ratvarfloorglow"
/obj/effect/overlay/temp/ratvar/floor/catwalk
layer = LATTICE_LAYER
/obj/effect/overlay/temp/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_WINDOW_LAYER
/obj/effect/overlay/temp/ratvar/gear
icon_state = "ratvargearglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille
icon_state = "ratvargrilleglow"
layer = BELOW_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/grille/broken
icon_state = "ratvarbrokengrilleglow"
/obj/effect/overlay/temp/ratvar/window/single
icon_state = "ratvarwindowglow_s"
/obj/effect/overlay/temp/ratvar/volt_hit
name = "volt blast"
layer = ABOVE_MOB_LAYER
duration = 5
icon_state = "volt_hit"
var/mob/user
var/damage = 20
/obj/effect/overlay/temp/ratvar/volt_hit/New(loc, caster, multiplier)
if(multiplier)
damage *= multiplier
duration = max(round(damage * 0.2), 1)
..()
SetLuminosity(3, 2)
/obj/effect/overlay/temp/ratvar/volt_hit/true/New(loc, caster, multiplier)
..()
user = caster
if(user)
var/matrix/M = new
M.Turn(Get_Angle(src, user))
transform = M
INVOKE_ASYNC(src, .proc/volthit)
/obj/effect/overlay/temp/ratvar/volt_hit/proc/volthit()
if(user)
Beam(get_turf(user), "volt_ray", time=duration, maxdistance=8, beam_type=/obj/effect/ebeam/volt_ray)
var/hit_amount = 0
var/turf/T = get_turf(src)
for(var/mob/living/L in T)
if(is_servant_of_ratvar(L))
continue
var/obj/item/I = L.null_rod_check()
if(I)
L.visible_message("<span class='warning'>Strange energy flows into [L]'s [I.name]!</span>", \
"<span class='userdanger'>Your [I.name] shields you from [src]!</span>")
continue
L.visible_message("<span class='warning'>[L] is struck by a [name]!</span>", "<span class='userdanger'>You're struck by a [name]!</span>")
L.apply_damage(damage, BURN, "chest", L.run_armor_check("chest", "laser", "Your armor absorbs [src]!", "Your armor blocks part of [src]!", 0, "Your armor was penetrated by [src]!"))
add_logs(user, L, "struck with a volt blast")
hit_amount++
for(var/obj/mecha/M in T)
if(M.occupant)
if(is_servant_of_ratvar(M.occupant))
continue
M.occupant << "<span class='userdanger'>Your [M.name] is struck by a [name]!</span>"
M.visible_message("<span class='warning'>[M] is struck by a [name]!</span>")
M.take_damage(damage, BURN, 0, 0)
hit_amount++
if(hit_amount)
playsound(src, 'sound/machines/defib_zap.ogg', damage*hit_amount, 1, -1)
else
playsound(src, "sparks", 50, 1)
/obj/effect/overlay/temp/ratvar/ocular_warden
name = "warden's gaze"
layer = ABOVE_MOB_LAYER
icon_state = "warden_gaze"
duration = 3
/obj/effect/overlay/temp/ratvar/ocular_warden/New()
..()
pixel_x = rand(-8, 8)
pixel_y = rand(-10, 10)
animate(src, alpha = 0, time = 3, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/spearbreak
icon = 'icons/effects/64x64.dmi'
icon_state = "ratvarspearbreak"
layer = BELOW_MOB_LAYER
pixel_y = -16
pixel_x = -16
/obj/effect/overlay/temp/ratvar/geis_binding
icon_state = "geisbinding"
/obj/effect/overlay/temp/ratvar/geis_binding/top
icon_state = "geisbinding_top"
/obj/effect/overlay/temp/ratvar/component
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "belligerent_eye"
layer = ABOVE_MOB_LAYER
duration = 10
/obj/effect/overlay/temp/ratvar/component/New()
..()
transform = matrix()*0.75
pixel_x = rand(-10, 10)
pixel_y = rand(-10, -2)
animate(src, pixel_y = pixel_y + 10, alpha = 50, time = 10, easing = EASE_OUT)
/obj/effect/overlay/temp/ratvar/component/cogwheel
icon_state = "vanguard_cogwheel"
/obj/effect/overlay/temp/ratvar/component/capacitor
icon_state = "geis_capacitor"
/obj/effect/overlay/temp/ratvar/component/alloy
icon_state = "replicant_alloy"
/obj/effect/overlay/temp/ratvar/component/ansible
icon_state = "hierophant_ansible"
/obj/effect/overlay/temp/ratvar/sigil
name = "glowing circle"
icon_state = "sigildull"
/obj/effect/overlay/temp/ratvar/sigil/transgression
color = "#FAE48C"
layer = ABOVE_MOB_LAYER
duration = 70
luminosity = 6
/obj/effect/overlay/temp/ratvar/sigil/transgression/New()
..()
var/oldtransform = transform
animate(src, transform = matrix()*2, time = 5)
animate(transform = oldtransform, alpha = 0, time = 65)
/obj/effect/overlay/temp/ratvar/sigil/vitality
color = "#1E8CE1"
icon_state = "sigilactivepulse"
layer = ABOVE_MOB_LAYER
/obj/effect/overlay/temp/ratvar/sigil/accession
color = "#AF0AAF"
layer = ABOVE_MOB_LAYER
duration = 70
icon_state = "sigilactiveoverlay"
alpha = 0
/obj/effect/overlay/temp/revenant
name = "spooky lights"
icon_state = "purplesparkles"
/obj/effect/overlay/temp/revenant/cracks
name = "glowing cracks"
icon_state = "purplecrack"
duration = 6
/obj/effect/overlay/temp/gravpush
name = "gravity wave"
icon_state = "shieldsparkles"
duration = 5
/obj/effect/overlay/temp/telekinesis
name = "telekinetic force"
icon_state = "empdisable"
duration = 5
/obj/effect/overlay/temp/emp
name = "emp sparks"
icon_state = "empdisable"
/obj/effect/overlay/temp/emp/pulse
name = "emp pulse"
icon_state = "emppulse"
duration = 8
randomdir = 0
/obj/effect/overlay/temp/gib_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/gib_animation/New(loc, gib_icon)
icon_state = gib_icon // Needs to be before ..() so icon is correct
..()
/obj/effect/overlay/temp/gib_animation/ex_act(severity)
return //so the overlay isn't deleted by the explosion that gibbed the mob.
/obj/effect/overlay/temp/gib_animation/animal
icon = 'icons/mob/animal.dmi'
/obj/effect/overlay/temp/dust_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/dust_animation/New(loc, dust_icon)
icon_state = dust_icon // Before ..() so the correct icon is flick()'d
..()
/obj/effect/overlay/temp/heal //color is white by default, set to whatever is needed
name = "healing glow"
@@ -110,6 +523,10 @@
pixel_y = -32
duration = 8
/obj/effect/overlay/temp/explosion/fast
icon_state = "explosionfast"
duration = 4
/obj/effect/overlay/temp/blob
name = "blob"
icon_state = "blob_attack"
@@ -117,219 +534,44 @@
randomdir = 0
duration = 6
/obj/effect/overlay/temp/guardian
randomdir = 0
/obj/effect/overlay/temp/guardian/phase
/obj/effect/overlay/temp/impact_effect
icon_state = "impact_bullet"
duration = 5
icon_state = "phasein"
/obj/effect/overlay/temp/guardian/phase/out
icon_state = "phaseout"
/obj/effect/overlay/temp/decoy
desc = "It's a decoy!"
duration = 15
/obj/effect/overlay/temp/decoy/New(loc, atom/mimiced_atom)
/obj/effect/overlay/temp/impact_effect/New(loc, atom/target, obj/item/projectile/P)
if(target == P.original) //the projectile hit the target originally clicked
pixel_x = P.p_x + target.pixel_x - 16 + rand(-4,4)
pixel_y = P.p_y + target.pixel_y - 16 + rand(-4,4)
else
pixel_x = target.pixel_x + rand(-4,4)
pixel_y = target.pixel_y + rand(-4,4)
..()
alpha = initial(alpha)
if(mimiced_atom)
name = mimiced_atom.name
appearance = mimiced_atom.appearance
setDir(mimiced_atom.dir)
animate(src, alpha = 0, time = duration)
/obj/effect/overlay/temp/cult
randomdir = 0
/obj/effect/overlay/temp/impact_effect/red_laser
icon_state = "impact_laser"
duration = 4
/obj/effect/overlay/temp/impact_effect/red_laser/wall
icon_state = "impact_laser_wall"
duration = 10
/obj/effect/overlay/temp/cult/sparks
randomdir = 1
name = "blood sparks"
icon_state = "bloodsparkles"
/obj/effect/overlay/temp/impact_effect/blue_laser
icon_state = "impact_laser_blue"
duration = 4
/obj/effect/overlay/temp/cult/phase
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/overlay/temp/impact_effect/green_laser
icon_state = "impact_laser_green"
duration = 4
/obj/effect/overlay/temp/cult/phase/New(loc, set_dir)
..()
if(set_dir)
setDir(set_dir)
/obj/effect/overlay/temp/impact_effect/purple_laser
icon_state = "impact_laser_purple"
duration = 4
/obj/effect/overlay/temp/cult/phase/out
icon_state = "cultout"
/obj/effect/overlay/temp/cult/sac
name = "maw of Nar-Sie"
icon_state = "sacconsume"
/obj/effect/overlay/temp/cult/door
name = "unholy glow"
icon_state = "doorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/cult/door/unruned
icon_state = "unruneddoorglow"
/obj/effect/overlay/temp/cult/turf
name = "unholy glow"
icon_state = "wallglow"
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/cult/turf/open/floor
icon_state = "floorglow"
duration = 5
/obj/effect/overlay/temp/ratvar
name = "ratvar's light"
duration = 8
randomdir = 0
layer = ABOVE_NORMAL_TURF_LAYER
/obj/effect/overlay/temp/ratvar/door
icon_state = "ratvardoorglow"
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/ratvar/door/window
icon_state = "ratvarwindoorglow"
/obj/effect/overlay/temp/ratvar/beam
icon_state = "ratvarbeamglow"
/obj/effect/overlay/temp/ratvar/beam/door
layer = CLOSED_FIREDOOR_LAYER //above closed doors
/obj/effect/overlay/temp/ratvar/beam/grille
layer = LOW_ITEM_LAYER //above grilles
/obj/effect/overlay/temp/ratvar/beam/itemconsume
layer = HIGH_OBJ_LAYER
/obj/effect/overlay/temp/ratvar/wall
icon_state = "ratvarwallglow"
/obj/effect/overlay/temp/ratvar/floor
icon_state = "ratvarfloorglow"
/obj/effect/overlay/temp/ratvar/window
icon_state = "ratvarwindowglow"
layer = ABOVE_WINDOW_LAYER //above windows
/obj/effect/overlay/temp/ratvar/grille
icon_state = "ratvargrilleglow"
layer = LOW_ITEM_LAYER //above grilles
/obj/effect/overlay/temp/ratvar/grille/broken
icon_state = "ratvarbrokengrilleglow"
/obj/effect/overlay/temp/ratvar/window/single
icon_state = "ratvarwindowglow_s"
/obj/effect/overlay/temp/ratvar/spearbreak
icon = 'icons/effects/64x64.dmi'
icon_state = "ratvarspearbreak"
layer = BELOW_MOB_LAYER
pixel_y = -16
pixel_x = -16
/obj/effect/overlay/temp/ratvar/sigil
name = "glowing circle"
icon = 'icons/effects/clockwork_effects.dmi'
icon_state = "sigildull"
/obj/effect/overlay/temp/ratvar/sigil/transgression
color = "#FAE48C"
layer = ABOVE_MOB_LAYER
duration = 50
/obj/effect/overlay/temp/ratvar/sigil/transgression/New()
..()
var/oldtransform = transform
animate(src, transform = matrix()*2, time = 5)
animate(transform = oldtransform, alpha = 0, time = 45)
/obj/effect/overlay/temp/ratvar/sigil/vitality
color = "#1E8CE1"
icon_state = "sigilactivepulse"
layer = BELOW_MOB_LAYER
/obj/effect/overlay/temp/ratvar/sigil/accession
color = "#AF0AAF"
layer = ABOVE_MOB_LAYER
duration = 50
icon_state = "sigilactiveoverlay"
alpha = 0
/obj/effect/overlay/temp/revenant
name = "spooky lights"
icon_state = "purplesparkles"
/obj/effect/overlay/temp/revenant/cracks
name = "glowing cracks"
icon_state = "purplecrack"
/obj/effect/overlay/temp/impact_effect/ion
icon_state = "shieldsparkles"
duration = 6
/obj/effect/overlay/temp/emp
name = "emp sparks"
icon_state = "empdisable"
/obj/effect/overlay/temp/emp/pulse
name = "emp pulse"
icon_state = "emp pulse"
duration = 8
randomdir = 0
/obj/effect/overlay/temp/gib_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/gib_animation/New(loc, gib_icon)
icon_state = gib_icon // Needs to be before ..() so icon is correct
..()
/obj/effect/overlay/temp/gib_animation/ex_act(severity)
return //so the overlay isn't deleted by the explosion that gibbed the mob.
/obj/effect/overlay/temp/gib_animation/animal
icon = 'icons/mob/animal.dmi'
/obj/effect/overlay/temp/dust_animation
icon = 'icons/mob/mob.dmi'
duration = 15
/obj/effect/overlay/temp/dust_animation/New(loc, dust_icon)
icon_state = dust_icon // Before ..() so the correct icon is flick()'d
..()
/obj/effect/overlay/temp/sparkle
icon = 'icons/effects/effects.dmi'
icon_state = "shieldsparkles"
mouse_opacity = 0
density = 0
duration = 10
var/atom/movable/attached_to
/obj/effect/overlay/temp/sparkle/New(atom/movable/AM)
..()
if(istype(AM))
attached_to = AM
attached_to.overlays += src
/obj/effect/overlay/temp/sparkle/Destroy()
if(attached_to)
attached_to.overlays -= src
attached_to = null
. = ..()
/obj/effect/overlay/temp/sparkle/tailsweep
icon_state = "tailsweep"
/obj/effect/overlay/palmtree_r
name = "Palm tree"
icon = 'icons/misc/beach2.dmi'
+7 -8
View File
@@ -1,18 +1,15 @@
/obj/effect
icon = 'icons/effects/effects.dmi'
/obj/effect/portal
name = "portal"
desc = "Looks unstable. Best to test it with the clown."
icon = 'icons/obj/stationobjs.dmi'
icon_state = "portal"
density = 1
unacidable = 1//Can't destroy energy portals.
var/obj/item/target = null
var/creator = null
anchored = 1
var/precision = 1 // how close to the portal you will teleport. 0 = on the portal, 1 = adjacent
var/mech_sized = FALSE
/obj/effect/portal/Bumped(mob/M as mob|obj)
teleport(M)
@@ -25,7 +22,8 @@
if(user && Adjacent(user))
teleport(user)
/obj/effect/portal/make_frozen_visual()
return
/obj/effect/portal/New(loc, turf/target, creator=null, lifespan=300)
..()
@@ -55,13 +53,14 @@
/obj/effect/portal/proc/teleport(atom/movable/M as mob|obj)
if(istype(M, /obj/effect)) //sparks don't teleport
return
if(M.anchored&&istype(M, /obj/mecha))
return
if(M.anchored)
if(!(istype(M, /obj/mecha) && mech_sized))
return
if (!( target ))
qdel(src)
return
if (istype(M, /atom/movable))
if(istype(M, /mob/living/simple_animal/hostile/megafauna))
if(ismegafauna(M))
message_admins("[M] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</A>) has teleported through [src].")
do_teleport(M, target, precision) ///You will appear adjacent to the beacon
@@ -1,4 +1,53 @@
/obj/effect/gibspawner
var/sparks = 0 //whether sparks spread
var/virusProb = 20 //the chance for viruses to spread on the gibs
var/list/gibtypes = list() //typepaths of the gib decals to spawn
var/list/gibamounts = list() //amount to spawn for each gib decal type we'll spawn.
var/list/gibdirections = list() //of lists of possible directions to spread each gib decal type towards.
/obj/effect/gibspawner/New(location, list/viruses, datum/dna/MobDNA)
..()
if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len)
world << "<span class='danger'>Gib list length mismatch!</span>"
return
var/obj/effect/decal/cleanable/blood/gibs/gib = null
if(sparks)
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(2, 1, location)
s.start()
for(var/i = 1, i<= gibtypes.len, i++)
if(gibamounts[i])
for(var/j = 1, j<= gibamounts[i], j++)
var/gibType = gibtypes[i]
gib = new gibType(location)
if(istype(location,/mob/living/carbon))
var/mob/living/carbon/digester = location
digester.stomach_contents += gib
if(viruses && viruses.len > 0)
for(var/datum/disease/D in viruses)
if(prob(virusProb))
var/datum/disease/viruus = D.Copy(1)
gib.viruses += viruus
viruus.holder = gib
if(MobDNA)
gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type
else if(istype(src, /obj/effect/gibspawner/generic)) // Probably a monkey
gib.blood_DNA["Non-human DNA"] = "A+"
var/list/directions = gibdirections[i]
if(isturf(loc))
if(directions.len)
gib.streak(directions)
qdel(src)
/obj/effect/gibspawner/generic
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs,/obj/effect/decal/cleanable/blood/gibs/core)
@@ -16,17 +65,55 @@
/obj/effect/gibspawner/human/New()
playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
gibamounts[6] = pick(0,1,2)
..()
/obj/effect/gibspawner/humanbodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core,/obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/core, /obj/effect/decal/cleanable/blood/gibs, /obj/effect/decal/cleanable/blood/gibs/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/humanbodypartless/New()
playsound(src, 'sound/effects/blobattack.ogg', 50, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, list())
..()
/obj/effect/gibspawner/xeno
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up,/obj/effect/decal/cleanable/xenoblood/xgibs/down,/obj/effect/decal/cleanable/xenoblood/xgibs,/obj/effect/decal/cleanable/xenoblood/xgibs,/obj/effect/decal/cleanable/xenoblood/xgibs/body,/obj/effect/decal/cleanable/xenoblood/xgibs/limb,/obj/effect/decal/cleanable/xenoblood/xgibs/core)
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/up,/obj/effect/decal/cleanable/xenoblood/xgibs/down,/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/body, /obj/effect/decal/cleanable/xenoblood/xgibs/limb, /obj/effect/decal/cleanable/xenoblood/xgibs/core)
gibamounts = list(1,1,1,1,1,1,1)
/obj/effect/gibspawner/xeno/New()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, alldirs, list())
gibamounts[6] = pick(0,1,2)
..()
/obj/effect/gibspawner/xenobodypartless //only the gibs that don't look like actual full bodyparts (except torso).
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core,/obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/core, /obj/effect/decal/cleanable/xenoblood/xgibs, /obj/effect/decal/cleanable/xenoblood/xgibs/torso)
gibamounts = list(1, 1, 1, 1, 1, 1)
/obj/effect/gibspawner/xenobodypartless/New()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST),list(WEST, NORTHWEST, SOUTHWEST),list(EAST, NORTHEAST, SOUTHEAST), alldirs, list())
..()
/obj/effect/gibspawner/larva
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body, /obj/effect/decal/cleanable/xenoblood/xgibs/larva/body)
gibamounts = list(1, 1, 1, 1)
/obj/effect/gibspawner/larva/New()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list(), alldirs)
..()
/obj/effect/gibspawner/larvabodypartless
gibtypes = list(/obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva, /obj/effect/decal/cleanable/xenoblood/xgibs/larva)
gibamounts = list(1, 1, 1)
/obj/effect/gibspawner/larvabodypartless/New()
playsound(src, 'sound/effects/blobattack.ogg', 60, 1)
gibdirections = list(list(NORTH, NORTHEAST, NORTHWEST),list(SOUTH, SOUTHEAST, SOUTHWEST), list())
..()
/obj/effect/gibspawner/robot
@@ -23,16 +23,16 @@
lootdoubles = 0
loot = list(
/obj/item/weapon/gun/projectile/automatic/pistol = 8,
/obj/item/weapon/gun/projectile/shotgun/automatic/combat = 5,
/obj/item/weapon/gun/projectile/revolver/mateba,
/obj/item/weapon/gun/projectile/automatic/pistol/deagle
/obj/item/weapon/gun/ballistic/automatic/pistol = 8,
/obj/item/weapon/gun/ballistic/shotgun/automatic/combat = 5,
/obj/item/weapon/gun/ballistic/revolver/mateba,
/obj/item/weapon/gun/ballistic/automatic/pistol/deagle
)
/obj/effect/spawner/lootdrop/gambling
name = "gambling valuables spawner"
loot = list(
/obj/item/weapon/gun/projectile/revolver/russian = 5,
/obj/item/weapon/gun/ballistic/revolver/russian = 5,
/obj/item/weapon/storage/box/syndie_kit/throwing_weapons = 1,
/obj/item/toy/cards/deck/syndicate = 2
)
@@ -121,7 +121,7 @@
/obj/item/weapon/crowbar = 1,
/obj/item/weapon/crowbar/red = 1,
/obj/item/weapon/extinguisher = 11,
//obj/item/weapon/gun/projectile/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
//obj/item/weapon/gun/ballistic/revolver/russian = 1, //disabled until lootdrop is a proper world proc.
/obj/item/weapon/hand_labeler = 1,
/obj/item/weapon/paper/crumpled = 1,
/obj/item/weapon/pen = 1,
@@ -143,7 +143,7 @@
/obj/item/weapon/wirecutters = 1,
/obj/item/weapon/wrench = 4,
/obj/item/weapon/relic = 3,
/obj/item/weaponcrafting/reciever = 1,
/obj/item/weaponcrafting/reciever = 2,
/obj/item/clothing/head/cone = 2,
/obj/item/weapon/grenade/smokebomb = 2,
/obj/item/device/geiger_counter = 3,
@@ -157,7 +157,7 @@
/obj/item/clothing/gloves/color/random = 8,
/obj/item/clothing/shoes/laceup = 1,
/obj/item/weapon/storage/secure/briefcase = 3,
"" = 4
"" = 3
)
/obj/effect/spawner/lootdrop/crate_spawner
+50 -58
View File
@@ -1,62 +1,45 @@
//generic procs copied from obj/effect/alien
/obj/effect/spider
/obj/structure/spider
name = "web"
icon = 'icons/effects/effects.dmi'
desc = "it's stringy and sticky"
anchored = 1
density = 0
var/health = 15
obj_integrity = 15
//similar to weeds, but only barfed out by nurses manually
/obj/effect/spider/ex_act(severity, target)
switch(severity)
if(1)
qdel(src)
if(2)
if (prob(50))
qdel(src)
if(3)
if (prob(5))
qdel(src)
/obj/effect/spider/attacked_by(obj/item/I, mob/user)
..()
var/damage = I.force
take_damage(damage, I.damtype, 1)
/obj/effect/spider/bullet_act(obj/item/projectile/P)
/obj/structure/spider/play_attack_sound(damage_amount, damage_type = BRUTE, damage_flag = 0)
if(damage_type == BURN)//the stickiness of the web mutes all attack sounds except fire damage type
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
/obj/structure/spider/run_obj_armor(damage_amount, damage_type, damage_flag = 0, attack_dir)
if(damage_flag == "melee")
switch(damage_type)
if(BURN)
damage_amount *= 2
if(BRUTE)
damage_amount *= 0.25
. = ..()
take_damage(P.damage, P.damage_type, 0)
/obj/effect/spider/proc/take_damage(damage, damage_type = BRUTE, sound_effect = 1)
switch(damage_type)
if(BURN)
damage *= 2
if(sound_effect)
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
if(BRUTE)//the stickiness of the web mutes all attack sounds except fire damage type
damage *= 0.25
else
return
health -= damage
if(health <= 0)
qdel(src)
/obj/effect/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
/obj/structure/spider/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature > 300)
take_damage(5, BURN, 0)
take_damage(5, BURN, 0, 0)
/obj/effect/spider/stickyweb
/obj/structure/spider/stickyweb
icon_state = "stickyweb1"
/obj/effect/spider/stickyweb/New()
/obj/structure/spider/stickyweb/New()
if(prob(50))
icon_state = "stickyweb2"
. = ..()
/obj/effect/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0)
/obj/structure/spider/stickyweb/CanPass(atom/movable/mover, turf/target, height=0)
if(height==0) return 1
if(istype(mover, /mob/living/simple_animal/hostile/poison/giant_spider))
return 1
else if(istype(mover, /mob/living))
else if(isliving(mover))
if(prob(50))
mover << "<span class='danger'>You get stuck in \the [src] for a moment.</span>"
return 0
@@ -64,7 +47,7 @@
return prob(30)
return 1
/obj/effect/spider/eggcluster
/obj/structure/spider/eggcluster
name = "egg cluster"
desc = "They seem to pulse slightly with an inner life"
icon_state = "eggs"
@@ -74,17 +57,18 @@
var/poison_per_bite = 5
var/list/faction = list("spiders")
/obj/effect/spider/eggcluster/New()
/obj/structure/spider/eggcluster/New()
pixel_x = rand(3,-3)
pixel_y = rand(3,-3)
START_PROCESSING(SSobj, src)
. = ..()
/obj/effect/spider/eggcluster/process()
/obj/structure/spider/eggcluster/process()
amount_grown += rand(0,2)
if(amount_grown >= 100)
var/num = rand(3,12)
for(var/i=0, i<num, i++)
var/obj/effect/spider/spiderling/S = new /obj/effect/spider/spiderling(src.loc)
var/obj/structure/spider/spiderling/S = new /obj/structure/spider/spiderling(src.loc)
S.poison_type = poison_type
S.poison_per_bite = poison_per_bite
S.faction = faction.Copy()
@@ -92,13 +76,13 @@
S.player_spiders = 1
qdel(src)
/obj/effect/spider/spiderling
/obj/structure/spider/spiderling
name = "spiderling"
desc = "It never stays still for long."
icon_state = "spiderling"
anchored = 0
layer = PROJECTILE_HIT_THRESHHOLD_LAYER
health = 3
obj_integrity = 3
var/amount_grown = 0
var/grow_as = null
var/obj/machinery/atmospherics/components/unary/vent_pump/entry_vent
@@ -108,20 +92,27 @@
var/poison_per_bite = 5
var/list/faction = list("spiders")
/obj/effect/spider/spiderling/New()
/obj/structure/spider/spiderling/New()
pixel_x = rand(6,-6)
pixel_y = rand(6,-6)
START_PROCESSING(SSobj, src)
. = ..()
/obj/effect/spider/spiderling/Bump(atom/user)
/obj/structure/spider/spiderling/hunter
grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/hunter
/obj/structure/spider/spiderling/nurse
grow_as = /mob/living/simple_animal/hostile/poison/giant_spider/nurse
/obj/structure/spider/spiderling/Bump(atom/user)
if(istype(user, /obj/structure/table))
src.loc = user.loc
else
..()
/obj/effect/spider/spiderling/process()
/obj/structure/spider/spiderling/process()
if(travelling_in_vent)
if(istype(src.loc, /turf))
if(isturf(loc))
travelling_in_vent = 0
entry_vent = null
else if(entry_vent)
@@ -193,18 +184,18 @@
/obj/effect/spider/cocoon
/obj/structure/spider/cocoon
name = "cocoon"
desc = "Something wrapped in silky spider web"
icon_state = "cocoon1"
health = 60
obj_integrity = 60
/obj/effect/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
/obj/structure/spider/cocoon/New()
icon_state = pick("cocoon1","cocoon2","cocoon3")
. = ..()
/obj/effect/spider/cocoon/container_resist()
var/mob/living/user = usr
var/breakout_time = 2
/obj/structure/spider/cocoon/container_resist(mob/living/user)
var/breakout_time = 1
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user << "<span class='notice'>You struggle against the tight bonds... (This will take about [breakout_time] minutes.)</span>"
@@ -216,8 +207,9 @@
/obj/effect/spider/cocoon/Destroy()
/obj/structure/spider/cocoon/Destroy()
var/turf/T = get_turf(src)
src.visible_message("<span class='warning'>\The [src] splits open.</span>")
for(var/atom/movable/A in contents)
A.loc = src.loc
A.forceMove(T)
return ..()
+3 -2
View File
@@ -3,7 +3,7 @@
/obj/effect/step_trigger
var/affect_ghosts = 0
var/stopper = 1 // stops throwers
var/mobs_only = 0
var/mobs_only = FALSE
invisibility = INVISIBILITY_ABSTRACT // nope cant see this shit
anchored = 1
@@ -14,7 +14,7 @@
..()
if(!H)
return
if(istype(H, /mob/dead/observer) && !affect_ghosts)
if(isobserver(H) && !affect_ghosts)
return
if(!istype(H, /mob) && mobs_only)
return
@@ -25,6 +25,7 @@
/obj/effect/step_trigger/message
var/message //the message to give to the mob
var/once = 1
mobs_only = TRUE
/obj/effect/step_trigger/message/Trigger(mob/M)
if(M.client)
+2 -2
View File
@@ -1,7 +1,7 @@
/proc/empulse(turf/epicenter, heavy_range, light_range, log=0)
if(!epicenter) return
if(!istype(epicenter, /turf))
if(!isturf(epicenter))
epicenter = get_turf(epicenter.loc)
if(log)
@@ -9,7 +9,7 @@
log_game("EMP with size ([heavy_range], [light_range]) in area [epicenter.loc.name] ")
if(heavy_range > 1)
PoolOrNew(/obj/effect/overlay/temp/emp/pulse, epicenter)
new /obj/effect/overlay/temp/emp/pulse(epicenter)
if(heavy_range > light_range)
light_range = heavy_range
+76 -46
View File
@@ -1,9 +1,24 @@
//TODO: Flash range does nothing currently
var/explosionid = 1
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0)
/proc/explosion(turf/epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, adminlog = 1, ignorecap = 0, flame_range = 0 ,silent = 0, smoke = 1)
set waitfor = 0
src = null //so we don't abort once src is deleted
src = null //so we don't abort once src is deleted
epicenter = get_turf(epicenter)
if(!epicenter)
return
// Archive the uncapped explosion for the doppler array
var/orig_dev_range = devastation_range
var/orig_heavy_range = heavy_impact_range
var/orig_light_range = light_impact_range
if(!ignorecap && epicenter.z != ZLEVEL_MINING)
//Clamp all values to MAX_EXPLOSION_RANGE
devastation_range = min(MAX_EX_DEVESTATION_RANGE, devastation_range)
heavy_impact_range = min(MAX_EX_HEAVY_RANGE, heavy_impact_range)
light_impact_range = min(MAX_EX_LIGHT_RANGE, light_impact_range)
flash_range = min(MAX_EX_FLASH_RANGE, flash_range)
flame_range = min(MAX_EX_FLAME_RANGE, flame_range)
//DO NOT REMOVE THIS SLEEP, IT BREAKS THINGS
//not sleeping causes us to ex_act() the thing that triggered the explosion
@@ -14,21 +29,8 @@
//and somethings expect us to ex_act them so they can qdel()
sleep(1) //tldr, let the calling proc call qdel(src) before we explode
// Archive the uncapped explosion for the doppler array
var/orig_dev_range = devastation_range
var/orig_heavy_range = heavy_impact_range
var/orig_light_range = light_impact_range
if(!ignorecap)
// Clamp all values to MAX_EXPLOSION_RANGE
devastation_range = min (MAX_EX_DEVESTATION_RANGE, devastation_range)
heavy_impact_range = min (MAX_EX_HEAVY_RANGE, heavy_impact_range)
light_impact_range = min (MAX_EX_LIGHT_RANGE, light_impact_range)
flash_range = min (MAX_EX_FLASH_RANGE, flash_range)
flame_range = min (MAX_EX_FLAME_RANGE, flame_range)
var/id = explosionid++
var/start = world.timeofday
if(!epicenter) return
var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range)
var/list/cached_exp_block = list()
@@ -43,8 +45,6 @@
// Calculate far explosion sound range. Only allow the sound effect for heavy/devastating explosions.
// 3/7/14 will calculate to 80 + 35
var/skip_shake = 0 //Will not shake screen
var/explosion_shake_message_cooldown = 0 //Will not display shaking-related messages
var/far_dist = 0
far_dist += heavy_impact_range * 5
far_dist += devastation_range * 20
@@ -64,22 +64,7 @@
else if(dist <= far_dist)
var/far_volume = Clamp(far_dist, 30, 50) // Volume is based on explosion size and dist
far_volume += (dist <= far_dist * 0.5 ? 50 : 0) // add 50 volume if the mob is pretty close to the explosion
if(devastation_range > 1)
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
shake_camera(M, 3, 1)
else
M.playsound_local(epicenter, 'sound/effects/explosionsmallfar.ogg', far_volume, 1, frequency, falloff = 5)
skip_shake = 1
if(!explosion_shake_message_cooldown && devastation_range > 1 && !skip_shake && M.stat == CONSCIOUS && !istype(get_turf(M), /turf/open/space))
if(istype(get_turf(M), /turf/open/floor/plasteel/asteroid | /turf/open/floor/plating/ash))
M << "<span class='danger'>You feel the ground shaking below you.</span>"
else
M << "<span class='danger'>You feel the station's structure shaking all around you.</span>"
explosion_shake_message_cooldown = 1
spawn(50)
explosion_shake_message_cooldown = 0
M.playsound_local(epicenter, 'sound/effects/explosionfar.ogg', far_volume, 1, frequency, falloff = 5)
//postpone processing for a bit
var/postponeCycles = max(round(devastation_range/8),1)
@@ -87,9 +72,14 @@
SSmachine.postpone(postponeCycles)
if(heavy_impact_range > 1)
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
E.set_up(epicenter)
E.start()
if(smoke)
var/datum/effect_system/explosion/smoke/E = new/datum/effect_system/explosion/smoke()
E.set_up(epicenter)
E.start()
else
var/datum/effect_system/explosion/E = new/datum/effect_system/explosion()
E.set_up(epicenter)
E.start()
var/x0 = epicenter.x
var/y0 = epicenter.y
@@ -111,15 +101,24 @@
if(W.reinf && W.fulltile)
cached_exp_block[T] += W.explosion_block
for(var/obj/effect/blob/B in T)
for(var/obj/structure/blob/B in T)
cached_exp_block[T] += B.explosion_block
CHECK_TICK
//flash mobs
if(flash_range)
for(var/mob/living/L in viewers(flash_range, epicenter))
L.flash_act()
CHECK_TICK
var/list/exploded_this_tick = list() //open turfs that need to be blocked off while we sleep
for(var/turf/T in affected_turfs)
if (!T)
continue
var/dist = cheap_hypotenuse(T.x, T.y, x0, y0)
var/init_dist = cheap_hypotenuse(T.x, T.y, x0, y0)
var/dist = init_dist
if(config.reactionary_explosions)
var/turf/Trajectory = T
@@ -142,13 +141,16 @@
else
dist = 0
//------- TURF FIRES -------
//------- EX_ACT AND TURF FIRES -------
if(T)
if(flame_dist && prob(40) && !istype(T, /turf/open/space) && !T.density)
PoolOrNew(/obj/effect/hotspot, T) //Mostly for ambience!
if(flame_dist && prob(40) && !isspaceturf(T) && !T.density)
new /obj/effect/hotspot(T) //Mostly for ambience!
if(dist > 0)
T.explosion_level = max(T.explosion_level, dist) //let the bigger one have it
T.explosion_id = id
T.ex_act(dist)
exploded_this_tick += T
//--- THROW ITEMS AROUND ---
@@ -158,9 +160,21 @@
var/throw_range = rand(throw_dist, max_range)
var/turf/throw_at = get_ranged_target_turf(I, throw_dir, throw_range)
I.throw_speed = 4 //Temporarily change their throw_speed for embedding purposes (Reset when it finishes throwing, regardless of hitting anything)
I.throw_at_fast(throw_at, throw_range, 2)//Throw it at 2 speed, this is purely visual anyway.
I.throw_at(throw_at, throw_range, I.throw_speed)
CHECK_TICK
if(TICK_CHECK)
var/circumference = (PI * init_dist * 2) + 8 //+8 to prevent shit gaps
if(exploded_this_tick.len > circumference) //only do this every revolution
for(var/Unexplode in exploded_this_tick)
var/turf/UnexplodeT = Unexplode
UnexplodeT.explosion_level = 0
exploded_this_tick.Cut()
//unfuck the shit
for(var/Unexplode in exploded_this_tick)
var/turf/UnexplodeT = Unexplode
UnexplodeT.explosion_level = 0
exploded_this_tick.Cut()
var/took = (world.timeofday-start)/10
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
@@ -238,7 +252,7 @@
if(W.explosion_block && W.fulltile)
dist += W.explosion_block
for(var/obj/effect/blob/B in T)
for(var/obj/structure/blob/B in T)
dist += B.explosion_block
if(dist < dev)
@@ -257,3 +271,19 @@
for(var/turf/T in wipe_colours)
T.color = null
T.maptext = ""
/proc/dyn_explosion(turf/epicenter, power, flash_range, adminlog = 1, ignorecap = 1, flame_range = 0 ,silent = 0, smoke = 1)
if(!power)
return
var/range = 0
range = round((2 * power)**DYN_EX_SCALE)
explosion(epicenter, round(range * 0.25), round(range * 0.5), round(range), flash_range*range, adminlog, ignorecap, flame_range*range, silent, smoke)
// Using default dyn_ex scale:
// 100 explosion power is a (5, 10, 20) explosion.
// 75 explosion power is a (4, 8, 17) explosion.
// 50 explosion power is a (3, 7, 14) explosion.
// 25 explosion power is a (2, 5, 10) explosion.
// 10 explosion power is a (1, 3, 6) explosion.
// 5 explosion power is a (0, 1, 3) explosion.
// 1 explosion power is a (0, 0, 1) explosion.
+160 -133
View File
@@ -20,13 +20,17 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/icon/alternate_worn_icon = null//If this is set, update_icons() will find on mob (WORN, NOT INHANDS) states in this file instead, primary use: badminnery/events
var/alternate_worn_layer = null//If this is set, update_icons() will force the on mob state (WORN, NOT INHANDS) onto this layer, instead of it's default
obj_integrity = 200
max_integrity = 200
var/hitsound = null
var/usesound = null
var/throwhitsound = null
var/w_class = 3
var/w_class = WEIGHT_CLASS_NORMAL
var/slot_flags = 0 //This is used to determine on which slots an item can fit.
pass_flags = PASSTABLE
pressure_resistance = 3
pressure_resistance = 4
var/obj/item/master = null
var/heat_protection = 0 //flags which determine which body parts are protected from heat. Use the HEAD, CHEST, GROIN, etc. flags. See setup.dm
@@ -34,8 +38,8 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/max_heat_protection_temperature //Set this variable to determine up to which temperature (IN KELVIN) the item protects against heat damage. Keep at null to disable protection. Only protects areas set by heat_protection flags
var/min_cold_protection_temperature //Set this variable to determine down to which temperature (IN KELVIN) the item protects against cold damage. 0 is NOT an acceptable number due to if(varname) tests!! Keep at null to disable protection. Only protects areas set by cold_protection flags
var/list/actions = list() //list of /datum/action's that this item has.
var/list/actions_types = list() //list of paths of action datums to give to the item on New().
var/list/actions //list of /datum/action's that this item has.
var/list/actions_types //list of paths of action datums to give to the item on New().
//Since any item can now be a piece of clothing, this has to be put here so all items share it.
var/flags_inv //This flag is used to determine when items in someone's inventory cover others. IE helmets making it so you can't see glasses, etc.
@@ -48,18 +52,17 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
var/permeability_coefficient = 1 // for chemicals/diseases
var/siemens_coefficient = 1 // for electrical admittance/conductance (electrocution checks and shit)
var/slowdown = 0 // How much clothing is slowing you down. Negative values speeds you up
var/list/armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0)
var/armour_penetration = 0 //percentage of armour effectiveness to remove
var/list/allowed = null //suit storage stuff.
var/obj/item/device/uplink/hidden_uplink = null
var/strip_delay = 40
var/put_on_delay = 20
var/breakouttime = 0
var/list/materials = list()
var/list/materials
var/origin_tech = null //Used by R&D to determine what research bonuses it grants.
var/needs_permit = 0 //Used by security bots to determine if this item is safe for public use.
var/list/attack_verb = list() //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
var/list/attack_verb //Used in attackby() to say how something was attacked "[x] has been [z.attack_verb] by [y] with [z]"
var/list/species_exception = null // list() of species types, if a species cannot put items in a certain slot, but species type is in list, it will be able to wear that item
var/suittoggled = 0
@@ -95,37 +98,35 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
// non-clothing items
var/datum/dog_fashion/dog_fashion = null
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
if(((src in target) && !target_self) || (!istype(target.loc, /turf) && !istype(target, /turf) && not_inside))
return 0
else
return 1
/obj/item/device
icon = 'icons/obj/device.dmi'
/obj/item/New()
if (!materials)
materials = list()
..()
for(var/path in actions_types)
new path(src)
actions_types = null
/obj/item/Destroy()
flags &= ~DROPDEL //prevent reqdels
if(ismob(loc))
var/mob/m = loc
m.unEquip(src, 1)
m.temporarilyRemoveItemFromInventory(src, TRUE)
for(var/X in actions)
qdel(X)
return ..()
/obj/item/blob_act(obj/effect/blob/B)
qdel(src)
/obj/item/device
icon = 'icons/obj/device.dmi'
/obj/item/ex_act(severity, target)
if(severity == 1 || target == src)
/obj/item/proc/check_allowed_items(atom/target, not_inside, target_self)
if(((src in target) && !target_self) || (!isturf(target.loc) && !isturf(target) && not_inside))
return 0
else
return 1
/obj/item/blob_act(obj/structure/blob/B)
if(B && B.loc == loc)
qdel(src)
if(!qdeleted(src))
contents_explosion(severity, target)
//user: The mob that is suiciding
//damagetype: The type of damage the item will inflict on the user
@@ -142,7 +143,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
set category = "Object"
set src in oview(1)
if(!istype(src.loc, /turf) || usr.stat || usr.restrained() || !usr.canmove)
if(!isturf(loc) || usr.stat || usr.restrained() || !usr.canmove)
return
var/turf/T = src.loc
@@ -153,29 +154,12 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
/obj/item/examine(mob/user) //This might be spammy. Remove?
..()
var/size
switch(src.w_class)
if(1)
size = "tiny"
if(2)
size = "small"
if(3)
size = "normal-sized"
if(4)
size = "bulky"
if(5)
size = "huge"
if(6)
size = "gigantic"
else
//if ((CLUMSY in usr.mutations) && prob(50)) t = "funny-looking"
var/pronoun
if(src.gender == PLURAL)
pronoun = "They are"
else
pronoun = "It is"
var/size = weightclass2text(src.w_class)
user << "[pronoun] a [size] item." //e.g. They are a small item. or It is a bulky item.
if(user.research_scanner) //Mob has a research scanner active.
@@ -220,22 +204,31 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
if(anchored)
return
if(burn_state == ON_FIRE)
var/mob/living/carbon/human/H = user
if(istype(H))
if(H.gloves && (H.gloves.max_heat_protection_temperature > 360))
if(resistance_flags & ON_FIRE)
var/mob/living/carbon/C = user
if(istype(C))
if(C.gloves && (C.gloves.max_heat_protection_temperature > 360))
extinguish()
user << "<span class='notice'>You put out the fire on [src].</span>"
else
user << "<span class='warning'>You burn your hand on [src]!</span>"
var/obj/item/bodypart/affecting = H.get_bodypart("[user.hand ? "l" : "r" ]_arm")
if(affecting && affecting.take_damage( 0, 5 )) // 5 burn damage
H.update_damage_overlays(0)
H.updatehealth()
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
C.update_damage_overlays()
return
else
extinguish()
if(acid_level > 20 && !ismob(loc))// so we can still remove the clothes on us that have acid.
var/mob/living/carbon/C = user
if(istype(C))
if(!C.gloves || (!(C.gloves.resistance_flags & (UNACIDABLE|ACID_PROOF))))
user << "<span class='warning'>The acid on [src] burns your hand!</span>"
var/obj/item/bodypart/affecting = C.get_bodypart("[(user.active_hand_index % 2 == 0) ? "r" : "l" ]_arm")
if(affecting && affecting.receive_damage( 0, 5 )) // 5 burn damage
C.update_damage_overlays()
if(istype(loc, /obj/item/weapon/storage))
//If the item is in a storage item, take it out
var/obj/item/weapon/storage/S = loc
@@ -243,7 +236,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
throwing = 0
if(loc == user)
if(!user.unEquip(src))
if(!user.dropItemToGround(src))
return
pickup(user)
@@ -264,7 +257,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
throwing = 0
if(loc == user)
if(!user.unEquip(src))
if(!user.dropItemToGround(src))
return
pickup(user)
@@ -277,7 +270,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
if(!A.has_fine_manipulation)
if(src in A.contents) // To stop Aliens having items stuck in their pockets
A.unEquip(src)
A.dropItemToGround(src)
user << "<span class='warning'>Your claws aren't capable of such fine manipulation!</span>"
return
attack_paw(A)
@@ -285,7 +278,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
/obj/item/attack_ai(mob/user)
if(istype(src.loc, /obj/item/weapon/robot_module))
//If the item is part of a cyborg module, equip it
if(!isrobot(user))
if(!iscyborg(user))
return
var/mob/living/silicon/robot/R = user
if(!R.low_power_mode) //can't equip modules with an empty cell.
@@ -294,38 +287,44 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
// Due to storage type consolidation this should get used more now.
// I have cleaned it up a little, but it could probably use more. -Sayu
// The lack of ..() is intentional, do not add one
/obj/item/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
if(S.use_to_pickup)
if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one.
if(isturf(src.loc))
var/list/rejections = list()
var/success = 0
var/failure = 0
if(unique_rename && istype(W, /obj/item/weapon/pen))
rewrite(user)
else
if(istype(W,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = W
if(S.use_to_pickup)
if(S.collection_mode) //Mode is set to collect multiple items on a tile and we clicked on a valid one.
if(isturf(src.loc))
var/list/rejections = list()
var/success = 0
var/failure = 0
for(var/obj/item/I in src.loc)
if(S.collection_mode == 2 && !istype(I,src.type)) // We're only picking up items of the target type
failure = 1
continue
if(I.type in rejections) // To limit bag spamming: any given type only complains once
continue
if(!S.can_be_inserted(I)) // Note can_be_inserted still makes noise when the answer is no
rejections += I.type // therefore full bags are still a little spammy
failure = 1
continue
for(var/obj/item/I in src.loc)
if(S.collection_mode == 2 && !istype(I,src.type)) // We're only picking up items of the target type
failure = 1
continue
if(I.type in rejections) // To limit bag spamming: any given type only complains once
continue
if(!S.can_be_inserted(I, stop_messages = 1)) // Note can_be_inserted still makes noise when the answer is no
if(S.contents.len >= S.storage_slots)
break
rejections += I.type // therefore full bags are still a little spammy
failure = 1
continue
success = 1
S.handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
if(success && !failure)
user << "<span class='notice'>You put everything [S.preposition] [S].</span>"
else if(success)
user << "<span class='notice'>You put some things [S.preposition] [S].</span>"
else
user << "<span class='warning'>You fail to pick anything up with [S]!</span>"
success = 1
S.handle_item_insertion(I, 1) //The 1 stops the "You put the [src] into [S]" insertion message from being displayed.
if(success && !failure)
user << "<span class='notice'>You put everything [S.preposition] [S].</span>"
else if(success)
user << "<span class='notice'>You put some things [S.preposition] [S].</span>"
else
user << "<span class='warning'>You fail to pick anything up with [S]!</span>"
else if(S.can_be_inserted(src))
S.handle_item_insertion(src)
else if(S.can_be_inserted(src))
S.handle_item_insertion(src)
// afterattack() and attack() prototypes moved to _onclick/item_attack.dm for consistency
@@ -337,7 +336,7 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
return 0
/obj/item/proc/talk_into(mob/M, input, channel, spans)
return
return ITALICS | REDUCE_RANGE
/obj/item/proc/dropped(mob/user)
for(var/X in actions)
@@ -375,13 +374,16 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s
A.Grant(user)
//sometimes we only want to grant the item's action if it's equipped in a specific slot.
obj/item/proc/item_action_slot_check(slot, mob/user)
return 1
/obj/item/proc/item_action_slot_check(slot, mob/user)
if(slot == slot_in_backpack || slot == slot_legcuffed) //these aren't true slots, so avoid granting actions there
return FALSE
return TRUE
//the mob M is attempting to equip this item into the slot passed through as 'slot'. Return 1 if it can do this and 0 if it can't.
//if this is being done by a mob other than M, it will include the mob equipper, who is trying to equip the item to mob M. equipper will be null otherwise.
//If you are making custom procs but would like to retain partial or complete functionality of this one, include a 'return ..()' to where you want this to happen.
//Set disable_warning to 1 if you wish it to not give you outputs.
/obj/item/proc/mob_can_equip(mob/M, slot, disable_warning = 0)
/obj/item/proc/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
if(!M)
return 0
@@ -395,7 +397,7 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
if(usr.incapacitated() || !Adjacent(usr) || usr.lying)
return
if(usr.get_active_hand() == null) // Let me know if this has any problems -Yota
if(usr.get_active_held_item() == null) // Let me know if this has any problems -Yota
usr.UnarmedAttack(src)
//This proc is executed when someone clicks the on-screen UI button.
@@ -442,10 +444,11 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
playsound(loc, src.hitsound, 30, 1, -1)
user.do_attack_animation(M)
if(M != user)
M.visible_message("<span class='danger'>[user] has stabbed [M] in the eye with [src]!</span>", \
"<span class='userdanger'>[user] stabs you in the eye with [src]!</span>")
user.do_attack_animation(M)
else
user.visible_message( \
"<span class='danger'>[user] has stabbed themself in the eyes with [src]!</span>", \
@@ -453,11 +456,10 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
)
if(is_human_victim)
var/mob/living/carbon/human/U = M
if(affecting.take_damage(7))
U.update_damage_overlays(0)
U.apply_damage(7, BRUTE, affecting)
else
M.take_organ_damage(7)
M.take_bodypart_damage(7)
add_logs(user, M, "attacked", "[src.name]", "(INTENT: [uppertext(user.a_intent)])")
@@ -497,51 +499,27 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
/obj/item/singularity_pull(S, current_size)
if(current_size >= STAGE_FOUR)
throw_at_fast(S,14,3, spin=0)
throw_at(S,14,3, spin=0)
else ..()
/obj/item/acid_act(acidpwr, acid_volume)
. = 1
if(unacidable)
return
var/meltingpwr = acid_volume*acidpwr
var/melting_threshold = 100
if(meltingpwr <= melting_threshold) // so a single unit can't melt items. You need 5.1+ unit for fluoro and 10.1+ for sulphuric
return
for(var/V in armor)
if(armor[V] > 0)
.-- //it survives the acid...
break
if(. && prob(min(meltingpwr/10,90))) //chance to melt depends on acid power and volume.
var/turf/T = get_turf(src)
if(T)
var/obj/effect/decal/cleanable/molten_item/I = new (T)
I.pixel_x = rand(-16,16)
I.pixel_y = rand(-16,16)
I.desc = "Looks like this was \an [src] some time ago."
if(istype(src,/obj/item/weapon/storage))
var/obj/item/weapon/storage/S = src
S.do_quick_empty() //melted storage item drops its content.
qdel(src)
else
for(var/armour_value in armor) //but is weakened
armor[armour_value] = max(armor[armour_value]-min(acidpwr,meltingpwr/10),0)
if(!findtext(desc, "it looks slightly melted...")) //it looks slightly melted... it looks slightly melted... it looks slightly melted... etc.
desc += " it looks slightly melted..." //needs a space at the start, formatting
/obj/item/throw_impact(atom/A)
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
return A.hitby(src, 0, itempush)
if(A && !qdeleted(A))
var/itempush = 1
if(w_class < 4)
itempush = 0 //too light to push anything
return A.hitby(src, 0, itempush)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1)
/obj/item/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
thrownby = thrower
. = ..()
throw_speed = initial(throw_speed) //explosions change this.
callback = CALLBACK(src, .proc/after_throw, callback) //replace their callback with our own
. = ..(target, range, speed, thrower, spin, diagonals_first, callback)
/obj/item/proc/after_throw(datum/callback/callback)
if (callback) //call the original callback
. = callback.Invoke()
throw_speed = initial(throw_speed) //explosions change this.
/obj/item/proc/remove_item_from_storage(atom/newLoc) //please use this if you're going to snowflake an item out of a obj/item/weapon/storage
if(!newLoc)
return 0
@@ -568,11 +546,60 @@ obj/item/proc/item_action_slot_check(slot, mob/user)
else
. = pick('sound/misc/desceration-01.ogg', 'sound/misc/desceration-02.ogg', 'sound/misc/desceration-03.ogg')
/obj/item/proc/open_flame()
/obj/item/proc/open_flame(flame_heat=700)
var/turf/location = loc
if(ismob(location))
var/mob/M = location
if(M.l_hand == src || M.r_hand == src)
var/success = FALSE
if(src == M.get_item_by_slot(slot_wear_mask))
success = TRUE
if(success)
location = get_turf(M)
if(isturf(location))
location.hotspot_expose(700, 5)
location.hotspot_expose(flame_heat, 5)
/obj/item/proc/ignition_effect(atom/A, mob/user)
if(is_hot())
. = "<span class='notice'>[user] lights [A] with [src].</span>"
else
. = ""
//when an item modify our speech spans when in our active hand. Override this to modify speech spans.
/obj/item/proc/get_held_item_speechspans(mob/living/carbon/user)
return
/obj/item/hitby(atom/movable/AM)
return
/obj/item/attack_hulk(mob/living/carbon/human/user)
return 0
/obj/item/attack_animal(mob/living/simple_animal/M)
return 0
/obj/item/mech_melee_attack(obj/mecha/M)
return 0
/obj/item/burn()
if(!qdeleted(src))
var/turf/T = get_turf(src)
var/ash_type = /obj/effect/decal/cleanable/ash
if(w_class == WEIGHT_CLASS_HUGE || w_class == WEIGHT_CLASS_GIGANTIC)
ash_type = /obj/effect/decal/cleanable/ash/large
var/obj/effect/decal/cleanable/ash/A = new ash_type(T)
A.desc += "\nLooks like this used to be \an [name] some time ago."
..()
/obj/item/acid_melt()
if(!qdeleted(src))
var/turf/T = get_turf(src)
var/obj/effect/decal/cleanable/molten_object/MO = new(T)
MO.pixel_x = rand(-16,16)
MO.pixel_y = rand(-16,16)
MO.desc = "Looks like this was \an [src] some time ago."
..()
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
if(M && M.dirty < 100)
M.dirty++
+4 -4
View File
@@ -3,7 +3,7 @@
flags = CONDUCT
origin_tech = "materials=1;engineering=1"
item_state = "syringe_kit"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/result_path
var/inverse = 0
// For inverse dir frames like light fixtures.
@@ -16,7 +16,7 @@
return
var/turf/loc = get_turf(usr)
var/area/A = loc.loc
if(!istype(loc, /turf/open/floor))
if(!isfloorturf(loc))
usr << "<span class='warning'>You cannot place [src] on this spot!</span>"
return
if(A.requires_power == 0 || istype(A, /area/space))
@@ -51,7 +51,7 @@
if(istype(W, /obj/item/weapon/screwdriver))
// For camera-building borgs
var/turf/T = get_step(get_turf(user), user.dir)
if(istype(T, /turf/closed/wall))
if(iswallturf(T))
T.attackby(src, user, params)
var/metal_amt = round(materials[MAT_METAL]/MINERAL_MATERIAL_AMOUNT)
@@ -103,6 +103,6 @@
icon_state = "door_electronics"
item_state = "electronic"
flags = CONDUCT
w_class = 2
w_class = WEIGHT_CLASS_SMALL
origin_tech = "engineering=2;programming=1"
materials = list(MAT_METAL=50, MAT_GLASS=50)
+91 -90
View File
@@ -1,3 +1,18 @@
#define AREA_ERRNONE 0
#define AREA_STATION 1
#define AREA_SPACE 2
#define AREA_SPECIAL 3
#define BORDER_ERROR 0
#define BORDER_NONE 1
#define BORDER_BETWEEN 2
#define BORDER_2NDTILE 3
#define BORDER_SPACE 4
#define ROOM_ERR_LOLWAT 0
#define ROOM_ERR_SPACE 1
#define ROOM_ERR_TOOLARGE 2
/obj/item/areaeditor
name = "area modification item"
icon = 'icons/obj/items.dmi'
@@ -5,22 +20,6 @@
attack_verb = list("attacked", "bapped", "hit")
var/fluffnotice = "Nobody's gonna read this stuff!"
var/const/AREA_ERRNONE = 0
var/const/AREA_STATION = 1
var/const/AREA_SPACE = 2
var/const/AREA_SPECIAL = 3
var/const/BORDER_ERROR = 0
var/const/BORDER_NONE = 1
var/const/BORDER_BETWEEN = 2
var/const/BORDER_2NDTILE = 3
var/const/BORDER_SPACE = 4
var/const/ROOM_ERR_LOLWAT = 0
var/const/ROOM_ERR_SPACE = -1
var/const/ROOM_ERR_TOOLARGE = -2
/obj/item/areaeditor/attack_self(mob/user)
add_fingerprint(user)
var/text = "<BODY><HTML><head><title>[src]</title></head> \
@@ -43,37 +42,9 @@
return
if(href_list["create_area"])
if(get_area_type()==AREA_SPACE)
create_area()
create_area(usr)
updateUsrDialog()
//One-use area creation permits.
/obj/item/areaeditor/permit
name = "construction permit"
icon_state = "permit"
desc = "This is a one-use permit that allows the user to offically declare a built room as new addition to the station."
fluffnotice = "Nanotrasen Engineering requires all on-station construction projects to be approved by a head of staff, as detailed in Nanotrasen Company Regulation 512-C (Mid-Shift Modifications to Company Property). \
By submitting this form, you accept any fines, fees, or personal injury/death that may occur during construction."
w_class = 1
/obj/item/areaeditor/permit/attack_self(mob/user)
. = ..()
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
onclose(usr, "blueprints")
/obj/item/areaeditor/permit/create_area()
var/success = ..()
if(success)
qdel(src)
//Station blueprints!!!
/obj/item/areaeditor/blueprints
name = "station blueprints"
@@ -81,27 +52,38 @@
icon = 'icons/obj/items.dmi'
icon_state = "blueprints"
fluffnotice = "Property of Nanotrasen. For heads of staff only. Store in high-secure storage."
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/list/image/showing = list()
var/client/viewing
var/legend = FALSE //Viewing the wire legend
/obj/item/areaeditor/blueprints/Destroy()
clear_viewer()
return ..()
/obj/item/areaeditor/blueprints/attack_self(mob/user)
. = ..()
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p>You may <a href='?src=\ref[src];edit_area=1'>make an amendment</a> to the drawing.</p>"
if(!viewing)
. += "<p><a href='?src=\ref[src];view_blueprints=1'>View structural data</a></p>"
if(!legend)
var/area/A = get_area()
if(get_area_type() == AREA_STATION)
. += "<p>According to \the [src], you are now in <b>\"[html_encode(A.name)]\"</b>.</p>"
. += "<p>You may <a href='?src=\ref[src];edit_area=1'>make an amendment</a> to the drawing.</p>"
. += "<p><a href='?src=\ref[src];view_legend=1'>View wire colour legend</a></p>"
if(!viewing)
. += "<p><a href='?src=\ref[src];view_blueprints=1'>View structural data</a></p>"
else
. += "<p><a href='?src=\ref[src];refresh=1'>Refresh structural data</a></p>"
. += "<p><a href='?src=\ref[src];hide_blueprints=1'>Hide structural data</a></p>"
else
. += "<p><a href='?src=\ref[src];refresh=1'>Refresh structural data</a></p>"
. += "<p><a href='?src=\ref[src];hide_blueprints=1'>Hide structural data</a></p>"
if(legend == TRUE)
. += "<a href='?src=\ref[src];exit_legend=1'><< Back</a>"
. += view_wire_devices(user);
else
//legend is a wireset
. += "<a href='?src=\ref[src];view_legend=1'><< Back</a>"
. += view_wire_set(user, legend)
var/datum/browser/popup = new(user, "blueprints", "[src]", 700, 500)
popup.set_content(.)
popup.open()
@@ -114,6 +96,12 @@
if(get_area_type()!=AREA_STATION)
return
edit_area()
if(href_list["exit_legend"])
legend = FALSE;
if(href_list["view_legend"])
legend = TRUE;
if(href_list["view_wireset"])
legend = href_list["view_wireset"];
if(href_list["view_blueprints"])
set_viewer(usr, "<span class='notice'>You flip the blueprints over to view the complex information diagram.</span>")
if(href_list["hide_blueprints"])
@@ -152,6 +140,7 @@
/obj/item/areaeditor/blueprints/dropped(mob/user)
..()
clear_viewer()
legend = FALSE
/obj/item/areaeditor/proc/get_area()
@@ -179,29 +168,48 @@
return AREA_SPECIAL
return AREA_STATION
/obj/item/areaeditor/blueprints/proc/view_wire_devices(mob/user)
var/message = "<br>You examine the wire legend.<br>"
for(var/wireset in wire_color_directory)
message += "<br><a href='?src=\ref[src];view_wireset=[wireset]'>[wire_name_directory[wireset]]</a>"
message += "</p>"
return message
/obj/item/areaeditor/proc/create_area()
var/res = detect_room(get_turf(usr))
/obj/item/areaeditor/blueprints/proc/view_wire_set(mob/user, wireset)
//for some reason you can't use wireset directly as a derefencer so this is the next best :/
for(var/device in wire_color_directory)
if("[device]" == wireset) //I know... don't change it...
var/message = "<p><b>[wire_name_directory[device]]:</b>"
for(var/Col in wire_color_directory[device])
var/wire_name = wire_color_directory[device][Col]
if(!findtext(wire_name, WIRE_DUD_PREFIX)) //don't show duds
message += "<p><span style='color: [Col]'>[Col]</span>: [wire_name]</p>"
message += "</p>"
return message
return ""
/proc/create_area(mob/living/creator)
var/res = detect_room(get_turf(creator))
if(!istype(res,/list))
switch(res)
if(ROOM_ERR_SPACE)
usr << "<span class='warning'>The new area must be completely airtight.</span>"
creator << "<span class='warning'>The new area must be completely airtight.</span>"
return
if(ROOM_ERR_TOOLARGE)
usr << "<span class='warning'>The new area is too large.</span>"
creator << "<span class='warning'>The new area is too large.</span>"
return
else
usr << "<span class='warning'>Error! Please notify administration.</span>"
creator << "<span class='warning'>Error! Please notify administration.</span>"
return
var/list/turfs = res
var/str = trim(stripped_input(usr,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
var/str = trim(stripped_input(creator,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
if(!str || !length(str)) //cancel
return
if(length(str) > 50)
usr << "<span class='warning'>The given name is too long. The area remains undefined.</span>"
creator << "<span class='warning'>The given name is too long. The area remains undefined.</span>"
return
var/area/old = get_area(get_turf(src))
var/area/old = get_area(get_turf(creator))
var/old_gravity = old.has_gravity
var/area/A
@@ -213,21 +221,21 @@
turfs -= key
if(A)
A.contents += turfs
A.set_dynamic_lighting()
A.SetDynamicLighting()
else
A = new
A.setup(str)
A.contents += turfs
A.set_dynamic_lighting()
A.SetDynamicLighting()
A.has_gravity = old_gravity
interact()
creator << "<span class='notice'>You have created a new area, named [str]. It is now weather proof, and constructing an APC will allow it to be powered.</span>"
return 1
/obj/item/areaeditor/proc/edit_area()
var/area/A = get_area()
var/prevname = "[A.name]"
var/str = trim(stripped_input(usr,"New area name:", "Blueprint Editing", "", MAX_NAME_LEN))
var/str = trim(stripped_input(usr,"New area name:", "Area Creation", "", MAX_NAME_LEN))
if(!str || !length(str) || str==prevname) //cancel
return
if(length(str) > 50)
@@ -258,33 +266,26 @@
//TODO: much much more. Unnamed airlocks, cameras, etc.
/obj/item/areaeditor/proc/check_tile_is_border(turf/T2,dir)
if (istype(T2, /turf/open/space))
return BORDER_SPACE //omg hull breach we all going to die here
if (get_area_type(T2.loc)!=AREA_SPACE)
return BORDER_BETWEEN
if (istype(T2, /turf/closed/wall))
return BORDER_2NDTILE
if (!istype(T2, /turf))
return BORDER_BETWEEN
/turf/proc/check_tile_is_border()
return BORDER_NONE
for (var/obj/structure/window/W in T2)
if(turn(dir,180) == W.dir)
return BORDER_BETWEEN
if (W.dir in list(NORTHEAST,SOUTHEAST,NORTHWEST,SOUTHWEST))
/turf/open/space/check_tile_is_border()
return BORDER_SPACE
/turf/closed/check_tile_is_border()
return BORDER_2NDTILE
/turf/open/check_tile_is_border()
for(var/atom/movable/AM in src)
if(!CANATMOSPASS(AM, src))
return BORDER_2NDTILE
for(var/obj/machinery/door/window/D in T2)
if(turn(dir,180) == D.dir)
return BORDER_BETWEEN
if (locate(/obj/machinery/door) in T2)
return BORDER_2NDTILE
if (locate(/obj/structure/falsewall) in T2)
return BORDER_2NDTILE
return BORDER_NONE
/turf/closed/mineral/check_tile_is_border()
return BORDER_NONE
/obj/item/areaeditor/proc/detect_room(turf/first)
/proc/detect_room(turf/first)
var/list/turf/found = new
var/list/turf/pending = list(first)
var/list/border = list()
@@ -312,7 +313,7 @@
if (!isturf(NT) || (NT in found) || (NT in pending))
continue
switch(check_tile_is_border(NT,dir))
switch(NT.check_tile_is_border())
if(BORDER_NONE)
pending+=NT
if(BORDER_BETWEEN)
@@ -333,7 +334,7 @@
var/turf/U = get_step(F, direction)
if((U in border) || (U in found))
continue
if(check_tile_is_border(U, direction) == BORDER_2NDTILE)
if(U.check_tile_is_border() == BORDER_2NDTILE)
found += U
found |= F
return found
@@ -347,4 +348,4 @@
desc = "A digital copy of the station blueprints stored in your memory."
icon = 'icons/obj/items.dmi'
icon_state = "blueprints"
fluffnotice = "Intellectual Property of Nanotrasen. For use in engineering cyborgs only. Wipe from memory upon departure from the station."
fluffnotice = "Intellectual Property of Nanotrasen. For use in engineering cyborgs only. Wipe from memory upon departure from the station."
+2 -2
View File
@@ -20,14 +20,14 @@
owner.status_flags |= XENO_HOST
START_PROCESSING(SSobj, src)
owner.med_hud_set_status()
addtimer(src, "AddInfectionImages", 0, FALSE, owner)
INVOKE_ASYNC(src, .proc/AddInfectionImages, owner)
/obj/item/organ/body_egg/Remove(var/mob/living/carbon/M, special = 0)
STOP_PROCESSING(SSobj, src)
if(owner)
owner.status_flags &= ~(XENO_HOST)
owner.med_hud_set_status()
addtimer(src, "RemoveInfectionImages", 0, FALSE, owner)
INVOKE_ASYNC(src, .proc/RemoveInfectionImages, owner)
..()
/obj/item/organ/body_egg/process()
+47 -74
View File
@@ -1,4 +1,3 @@
//Also contains /obj/structure/closet/body_bag because I doubt anyone would think to look for bodybags in /object/structures
/obj/item/bodybag
name = "body bag"
@@ -6,14 +5,22 @@
icon = 'icons/obj/bodybag.dmi'
icon_state = "bodybag_folded"
var/unfoldedbag_path = /obj/structure/closet/body_bag
w_class = 2
w_class = WEIGHT_CLASS_SMALL
/obj/item/bodybag/attack_self(mob/user)
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(user.loc)
deploy_bodybag(user, user.loc)
/obj/item/bodybag/afterattack(atom/target, mob/user, proximity)
if(proximity)
if(isopenturf(target))
deploy_bodybag(user, target)
/obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location)
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location)
R.open(user)
R.add_fingerprint(user)
qdel(src)
/obj/item/weapon/storage/box/bodybags
name = "body bags"
desc = "The label indicates that it contains body bags."
@@ -25,66 +32,6 @@
new /obj/item/bodybag(src)
/obj/structure/closet/body_bag
name = "body bag"
desc = "A plastic bag designed for the storage and transportation of cadavers."
icon = 'icons/obj/bodybag.dmi'
icon_state = "bodybag"
var/foldedbag_path = /obj/item/bodybag
var/tagged = 0 // so closet code knows to put the tag overlay back
density = 0
mob_storage_capacity = 2
open_sound = 'sound/items/zip.ogg'
close_sound = 'sound/items/zip.ogg'
/obj/structure/closet/body_bag/attackby(obj/item/I, mob/user, params)
if (istype(I, /obj/item/weapon/pen) || istype(I, /obj/item/toy/crayon))
var/t = stripped_input(user, "What would you like the label to be?", name, null, 53)
if(user.get_active_hand() != I)
return
if(!in_range(src, user) && loc != user)
return
if(t)
name = "body bag - [t]"
tagged = 1
update_icon()
else
name = "body bag"
return
else if(istype(I, /obj/item/weapon/wirecutters))
user << "<span class='notice'>You cut the tag off [src].</span>"
name = "body bag"
tagged = 0
update_icon()
/obj/structure/closet/body_bag/update_icon()
..()
if (tagged)
add_overlay("bodybag_label")
/obj/structure/closet/body_bag/close()
if(..())
density = 0
return 1
return 0
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
..()
if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src)))
if(!ishuman(usr))
return 0
if(opened)
return 0
if(contents.len)
return 0
visible_message("<span class='notice'>[usr] folds up [src].</span>")
var/obj/item/bodybag/B = new foldedbag_path(get_turf(src))
usr.put_in_hands(B)
qdel(src)
// Bluespace bodybag
/obj/item/bodybag/bluespace
@@ -93,15 +40,41 @@
icon = 'icons/obj/bodybag.dmi'
icon_state = "bluebodybag_folded"
unfoldedbag_path = /obj/structure/closet/body_bag/bluespace
w_class = 2
w_class = WEIGHT_CLASS_SMALL
origin_tech = "bluespace=4;materials=4;plasmatech=4"
/obj/structure/closet/body_bag/bluespace
name = "bluespace body bag"
desc = "A bluespace body bag designed for the storage and transportation of cadavers."
icon = 'icons/obj/bodybag.dmi'
icon_state = "bluebodybag"
foldedbag_path = /obj/item/bodybag/bluespace
density = 0
mob_storage_capacity = 15
max_mob_size = MOB_SIZE_LARGE
/obj/item/bodybag/bluespace/examine(mob/user)
..()
if(contents.len)
user << "<span class='notice'>You can make out the shapes of [contents.len] objects through the fabric.</span>"
/obj/item/bodybag/bluespace/Destroy()
for(var/atom/movable/A in contents)
A.forceMove(get_turf(src))
if(isliving(A))
A << "<span class='notice'>You suddenly feel the space around you torn apart! You're free!</span>"
return ..()
/obj/item/bodybag/bluespace/deploy_bodybag(mob/user, atom/location)
var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location)
for(var/atom/movable/A in contents)
A.forceMove(R)
if(isliving(A))
A << "<span class='notice'>You suddenly feel air around you! You're free!</span>"
R.open(user)
R.add_fingerprint(user)
qdel(src)
/obj/item/bodybag/bluespace/container_resist(mob/living/user)
if(user.incapacitated())
user << "<span class='warning'>You can't get out while you're restrained like this!</span>"
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
user << "<span class='notice'>You claw at the fabric of [src], trying to tear it open...</span>"
loc << "<span class='warning'>Someone starts trying to break free of [src]!</span>"
if(!do_after(user, 200, target = src))
loc << "<span class='warning'>The pressure subsides. It seems that they've stopped resisting...</span>"
return
loc.visible_message("<span class='warning'>[user] suddenly appears in front of [loc]!</span>", "<span class='userdanger'>[user] breaks free of [src]!</span>")
qdel(src)
+24 -30
View File
@@ -6,7 +6,7 @@
icon = 'icons/obj/candle.dmi'
icon_state = "candle1"
item_state = "candle1"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/wax = 200
var/lit = FALSE
var/infinite = FALSE
@@ -31,40 +31,22 @@
/obj/item/candle/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = W
if(WT.isOn()) //Badasses dont get blinded by lighting their candle with a welding tool
light("<span class='danger'>[user] casually lights the [name] with [W], what a badass.</span>")
else if(istype(W, /obj/item/weapon/lighter))
var/obj/item/weapon/lighter/L = W
if(L.lit)
light()
else if(istype(W, /obj/item/weapon/match))
var/obj/item/weapon/match/M = W
if(M.lit)
light()
else if(istype(W, /obj/item/candle))
var/obj/item/candle/C = W
if(C.lit)
light()
else if(istype(W, /obj/item/clothing/mask/cigarette))
var/obj/item/clothing/mask/cigarette/M = W
if(M.lit)
light()
var/msg = W.ignition_effect(src, user)
if(msg)
light(msg)
/obj/item/candle/fire_act()
/obj/item/candle/fire_act(exposed_temperature, exposed_volume)
if(!src.lit)
light() //honk
return
..()
/obj/item/candle/proc/light(show_message)
if(!src.lit)
src.lit = TRUE
//src.damtype = "fire"
if(show_message)
usr.visible_message(
"<span class='danger'>[usr] lights the [name].</span>")
set_light(CANDLE_LUMINOSITY)
usr.visible_message(show_message)
SetLuminosity(CANDLE_LUMINOSITY)
START_PROCESSING(SSobj, src)
update_icon()
@@ -76,9 +58,6 @@
wax--
if(!wax)
new/obj/item/trash/candle(src.loc)
if(istype(src.loc, /mob))
var/mob/M = src.loc
M.unEquip(src, 1) //src is being deleted anyway
qdel(src)
update_icon()
open_flame()
@@ -89,7 +68,22 @@
"<span class='notice'>[user] snuffs [src].</span>")
lit = FALSE
update_icon()
set_light(0)
SetLuminosity(0)
user.AddLuminosity(-CANDLE_LUMINOSITY)
/obj/item/candle/pickup(mob/user)
..()
if(lit)
SetLuminosity(0)
user.AddLuminosity(CANDLE_LUMINOSITY)
/obj/item/candle/dropped(mob/user)
..()
if(lit)
user.AddLuminosity(-CANDLE_LUMINOSITY)
SetLuminosity(CANDLE_LUMINOSITY)
/obj/item/candle/is_hot()
return lit * heat
+61 -13
View File
@@ -4,21 +4,34 @@
desc = "A vaguely humanoid cardboard cutout. It's completely blank."
icon = 'icons/obj/cardboard_cutout.dmi'
icon_state = "cutout_basic"
w_class = 4
var/list/possible_appearances = list("Assistant", "Clown", "Mime", "Traitor", "Nuke Op", "Cultist", "Clockwork Cultist", "Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer", \
"Ash Walker", "Deathsquad Officer", "Ian") //Possible restyles for the cutout; add an entry in change_appearance() if you add to here
w_class = WEIGHT_CLASS_BULKY
resistance_flags = FLAMMABLE
// Possible restyles for the cutout;
// add an entry in change_appearance() if you add to here
var/list/possible_appearances = list("Assistant", "Clown", "Mime",
"Traitor", "Nuke Op", "Cultist", "Clockwork Cultist",
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer",
"Ash Walker", "Deathsquad Officer", "Ian", "Slaughter Demon",
"Laughter Demon")
var/pushed_over = FALSE //If the cutout is pushed over and has to be righted
var/deceptive = FALSE //If the cutout actually appears as what it portray and not a discolored version
var/lastattacker = null
/obj/item/cardboard_cutout/attack_hand(mob/living/user)
if(user.a_intent == "help" || pushed_over)
if(user.a_intent == INTENT_HELP || pushed_over)
return ..()
user.visible_message("<span class='warning'>[user] pushes over [src]!</span>", "<span class='danger'>You push over [src]!</span>")
playsound(src, 'sound/weapons/Genhit.ogg', 50, 1)
push_over()
/obj/item/cardboard_cutout/proc/push_over()
name = initial(name)
desc = "[initial(desc)] It's been pushed over."
icon = initial(icon)
icon_state = "cutout_pushed_over"
color = initial(color)
remove_atom_colour(FIXED_COLOUR_PRIORITY)
alpha = initial(alpha)
pushed_over = TRUE
/obj/item/cardboard_cutout/attack_self(mob/living/user)
@@ -26,24 +39,38 @@
return
user << "<span class='notice'>You right [src].</span>"
desc = initial(desc)
icon = initial(icon)
icon_state = initial(icon_state) //This resets a cutout to its blank state - this is intentional to allow for resetting
pushed_over = FALSE
/obj/item/cardboard_cutout/attackby(obj/item/I, mob/living/user, params)
if(istype(I, /obj/item/toy/crayon))
change_appearance(I, user)
else
return ..()
return
// Why yes, this does closely resemble mob and object attack code.
if(I.flags & NOBLUDGEON)
return
if(!I.force)
playsound(loc, 'sound/weapons/tap.ogg', get_clamped_volume(), 1, -1)
else if(I.hitsound)
playsound(loc, I.hitsound, get_clamped_volume(), 1, -1)
user.changeNext_move(CLICK_CD_MELEE)
user.do_attack_animation(src)
if(I.force)
user.visible_message("<span class='danger'>[user] has hit \
[src] with [I]!</span>", "<span class='danger'>You hit [src] \
with [I]!</span>")
if(prob(I.force))
push_over()
/obj/item/cardboard_cutout/bullet_act(obj/item/projectile/P)
visible_message("<span class='danger'>[src] has been hit by [P]!</span>")
playsound(src, 'sound/weapons/slice.ogg', 50, 1)
if(prob(P.damage))
name = initial(name)
desc = "[initial(desc)] It's been pushed over."
icon_state = "cutout_pushed_over"
color = initial(color)
pushed_over = TRUE
push_over()
/obj/item/cardboard_cutout/proc/change_appearance(obj/item/toy/crayon/crayon, mob/living/user)
if(!crayon || !user)
@@ -51,15 +78,23 @@
if(pushed_over)
user << "<span class='warning'>Right [src] first!</span>"
return
if(crayon.check_empty(user))
return
if(crayon.is_capped)
user << "<span class='warning'>Take the cap off first!</span>"
return
var/new_appearance = input(user, "Choose a new appearance for [src].", "26th Century Deception") as null|anything in possible_appearances
if(!new_appearance || !crayon || !user.canUseTopic(src))
return
if(!do_after(user, 10, FALSE, src, TRUE))
return
user.visible_message("<span class='notice'>[user] gives [src] a new look.</span>", "<span class='notice'>Voila! You give [src] a new look.</span>")
crayon.use_charges(1)
crayon.check_empty(user)
alpha = 255
icon = initial(icon)
if(!deceptive)
color = "#FFD7A7"
add_atom_colour("#FFD7A7", FIXED_COLOUR_PRIORITY)
switch(new_appearance)
if("Assistant")
name = "[pick(first_names_male)] [pick(last_names)]"
@@ -123,7 +158,20 @@
name = "Ian"
desc = "A cardboard cutout of the HoP's beloved corgi."
icon_state = "cutout_ian"
if("Slaughter Demon")
name = "slaughter demon"
desc = "A cardboard cutout of a slaughter demon."
icon = 'icons/mob/mob.dmi'
icon_state = "daemon"
if("Laughter Demon")
name = "laughter demon"
desc = "A cardboard cutout of a laughter demon."
icon = 'icons/mob/mob.dmi'
icon_state = "bowmon"
return 1
/obj/item/cardboard_cutout/setDir(newdir)
dir = SOUTH
/obj/item/cardboard_cutout/adaptive //Purchased by Syndicate agents, these cutouts are indistinguishable from normal cutouts but aren't discolored when their appearance is changed
deceptive = TRUE
+10 -8
View File
@@ -59,9 +59,8 @@
user << "Your name has been sent to your employers for approval."
// Autoapproves after a certain time
response_timer_id = addtimer(src, "rename_station", approval_time, \
FALSE, new_name, user)
admins << "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[key_name_admin(user)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) proposes to rename the station to [new_name] (will autoapprove in [approval_time / 10] seconds). (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[user]'>BSA</A>) (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>)</span>"
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user), approval_time, TIMER_STOPPABLE)
admins << "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[key_name_admin(user)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[user]'>?</A>) proposes to rename the station to [new_name] (will autoapprove in [approval_time / 10] seconds). (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[user]'>BSA</A>) (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>) (<a href='?_src_=holder;CentcommReply=\ref[user]'>RPLY</a>)</span>"
/obj/item/station_charter/proc/reject_proposed(user)
if(!user)
@@ -80,14 +79,17 @@
response_timer_id = null
/obj/item/station_charter/proc/rename_station(designation, mob/user)
world.name = designation
if(config && config.server_name)
world.name = "[config.server_name]: [designation]"
else
world.name = designation
station_name = designation
minor_announce("[user.real_name] has designated your station as [world.name]", "Captain's Charter", 0)
log_game("[key_name(user)] has renamed the station as [world.name]")
minor_announce("[user.real_name] has designated your station as [station_name()]", "Captain's Charter", 0)
log_game("[key_name(user)] has renamed the station as [station_name()].")
name = "station charter for [world.name]"
name = "station charter for [station_name()]"
desc = "An official document entrusting the governance of \
[world.name] and surrounding space to Captain [user]."
[station_name()] and surrounding space to Captain [user]."
if(!unlimited_uses)
used = TRUE
+1 -1
View File
@@ -8,7 +8,7 @@
icon = 'icons/obj/device.dmi'
name = "control wand"
desc = "Remotely controls airlocks."
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/mode = WAND_OPEN
var/region_access = 1 //See access.dm
var/obj/item/weapon/card/id/ID
+45 -50
View File
@@ -24,7 +24,7 @@
var/use_overlays = FALSE
item_color = "red"
w_class = 1
w_class = WEIGHT_CLASS_TINY
attack_verb = list("attacked", "coloured")
var/paint_color = "#FF0000" //RGB
@@ -38,7 +38,7 @@
var/list/runes = list("rune1","rune2","rune3","rune4","rune5","rune6")
var/list/randoms = list(RANDOM_ANY, RANDOM_RUNE, RANDOM_ORIENTED,
RANDOM_NUMBER, RANDOM_GRAFFITI, RANDOM_LETTER)
var/list/graffiti_large_h = list("yiffhell", "secborg", "paint", "madworld1", "madworld2")
var/list/graffiti_large_h = list("yiffhell", "secborg", "paint")
var/list/all_drawables
@@ -69,7 +69,7 @@
var/post_noise = FALSE
/obj/item/toy/crayon/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is jamming the [src.name] up \his nose and into \his brain. It looks like \he's trying to commit suicide.</span>")
user.visible_message("<span class='suicide'>[user] is jamming [src] up [user.p_their()] nose and into [user.p_their()] brain. It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS|OXYLOSS)
/obj/item/toy/crayon/New()
@@ -88,11 +88,6 @@
refill()
/obj/item/toy/crayon/Destroy()
if(reagents)
qdel(reagents)
. = ..()
/obj/item/toy/crayon/proc/refill()
if(charges == -1)
charges_left = 100
@@ -129,22 +124,21 @@
/obj/item/toy/crayon/proc/check_empty(mob/user)
// When eating a crayon, check_empty() can be called twice producing
// two messages unless we check for being deleted first
if(!qdeleted(src))
. = TRUE
if(qdeleted(src))
return TRUE
. = FALSE
// -1 is unlimited charges
if(charges == -1)
. = FALSE
else if(!charges_left)
user << "<span class='warning'>There is no more of [src.name] \
left!</span>"
user << "<span class='warning'>There is no more of \the [src.name] left!</span>"
if(self_contained)
qdel(src)
. = TRUE
/obj/item/toy/crayon/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = hands_state)
// god bless tgui and all of its arguments
// tgui is a plague upon this codebase
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -155,8 +149,7 @@
/obj/item/toy/crayon/spraycan/AltClick(mob/user)
if(has_cap)
is_capped = !is_capped
user << "<span class='notice'>The cap on [src] is now \
[is_capped ? "on" : "off"].</span>"
user << "<span class='notice'>The cap on [src] is now [is_capped ? "on" : "off"].</span>"
update_icon()
/obj/item/toy/crayon/ui_data()
@@ -241,7 +234,7 @@
update_icon()
/obj/item/toy/crayon/proc/crayon_text_strip(text)
var/list/base = char_split(lowertext(text))
var/list/base = string2charlist(lowertext(text))
var/list/out = list()
for(var/a in base)
if(a in (letters|numerals))
@@ -305,9 +298,8 @@
else
graf_rot = 0
user << "<span class='notice'>You start \
[instant ? "spraying" : "drawing"] a [temp] on the \
[target.name]...</span>"
if(!instant)
user << "<span class='notice'>You start drawing a [temp] on the [target.name]...</span>"
if(pre_noise)
audible_message("<span class='notice'>You hear spraying.</span>")
@@ -337,6 +329,7 @@
if(!can_claim_for_gang(user, target))
return
tag_for_gang(user, target)
affected_turfs += target
else
switch(paint_mode)
if(PAINT_NORMAL)
@@ -354,8 +347,10 @@
user << "<span class='warning'>There isn't enough space to paint!</span>"
return
user << "<span class='notice'>You finish \
[instant ? "spraying" : "drawing"] \the [temp].</span>"
if(!instant)
user << "<span class='notice'>You finish drawing \the [temp].</span>"
else
user << "<span class='notice'>You spray a [temp] on \the [target.name]</span>"
if(length(text_buffer))
text_buffer = copytext(text_buffer,2)
@@ -369,9 +364,8 @@
cost = 5
. = use_charges(cost)
var/fraction = min(1, . / reagents.maximum_volume)
if(!affected_turfs.len)
return
fraction /= affected_turfs.len
if(affected_turfs.len)
fraction /= affected_turfs.len
for(var/t in affected_turfs)
reagents.reaction(t, TOUCH, fraction * volume_multiplier)
reagents.trans_to(t, ., volume_multiplier)
@@ -381,6 +375,8 @@
if(edible && (M == user))
user << "You take a bite of the [src.name]. Delicious!"
var/eaten = use_charges(5)
if(check_empty(user)) //Prevents divsion by zero
return
var/fraction = min(eaten / reagents.total_volume, 1)
reagents.reaction(M, INGEST, fraction * volume_multiplier)
reagents.trans_to(M, eaten, volume_multiplier)
@@ -393,8 +389,7 @@
// Reject space, player-created areas, and non-station z-levels.
var/area/A = get_area(target)
if(!A || (A.z != ZLEVEL_STATION) || !A.valid_territory)
user << "<span class='warning'>[A] is unsuitable for \
tagging.</span>"
user << "<span class='warning'>[A] is unsuitable for tagging.</span>"
return FALSE
var/spraying_over = FALSE
@@ -468,6 +463,11 @@
item_color = "purple"
reagent_contents = list("nutriment" = 1, "purplecrayonpowder" = 1)
/obj/item/toy/crayon/black
icon_state = "crayonblack"
paint_color = "#1C1C1C" //Not completely black because total black looks bad. So Mostly Black.
item_color = "black"
/obj/item/toy/crayon/white
icon_state = "crayonwhite"
paint_color = "#FFFFFF"
@@ -503,8 +503,8 @@
desc = "A box of crayons for all your rune drawing needs."
icon = 'icons/obj/crayons.dmi'
icon_state = "crayonbox"
w_class = 2
storage_slots = 6
w_class = WEIGHT_CLASS_SMALL
storage_slots = 7
can_hold = list(
/obj/item/toy/crayon
)
@@ -517,6 +517,7 @@
new /obj/item/toy/crayon/green(src)
new /obj/item/toy/crayon/blue(src)
new /obj/item/toy/crayon/purple(src)
new /obj/item/toy/crayon/black(src)
update_icon()
/obj/item/weapon/storage/crayons/update_icon()
@@ -532,8 +533,7 @@
usr << "This crayon is too sad to be contained in this box."
return
if("rainbow")
usr << "This crayon is too powerful to be contained in this \
box."
usr << "This crayon is too powerful to be contained in this box."
return
if(istype(W, /obj/item/toy/crayon/spraycan))
user << "Spraycans are not crayons."
@@ -552,8 +552,7 @@
paint_color = null
item_state = "spraycan"
desc = "A metallic container containing tasty paint.\n\
Alt-click to toggle the cap."
desc = "A metallic container containing tasty paint.\n Alt-click to toggle the cap."
instant = TRUE
edible = FALSE
@@ -565,18 +564,17 @@
validSurfaces = list(/turf/open/floor,/turf/closed/wall)
reagent_contents = list("welding_fuel" = 1, "ethanol" = 1)
pre_noise = TRUE
post_noise = FALSE
/obj/item/toy/crayon/spraycan/suicide_act(mob/user)
var/mob/living/carbon/human/H = user
if(is_capped || !actually_paints)
user.visible_message("<span class='suicide'>[user] shakes up the \
[src] with a rattle and lifts it to their mouth, but nothing \
happens!</span>")
user.visible_message("<span class='suicide'>[user] shakes up [src] with a rattle and lifts it to [user.p_their()] mouth, but nothing happens!</span>")
user.say("MEDIOCRE!!")
return SHAME
else
user.visible_message("<span class='suicide'>[user] shakes up the \
[src] with a rattle and lifts it to their mouth, spraying \
paint across their teeth!</span>")
user.visible_message("<span class='suicide'>[user] shakes up [src] with a rattle and lifts it to [user.p_their()] mouth, spraying paint across [user.p_their()] teeth!</span>")
user.say("WITNESS ME!!")
if(pre_noise || post_noise)
playsound(loc, 'sound/effects/spray.ogg', 5, 1, 5)
@@ -624,18 +622,16 @@
if(iscarbon(target))
if(pre_noise || post_noise)
playsound(user.loc, 'sound/effects/spray.ogg', 5, 1, 5)
playsound(user.loc, 'sound/effects/spray.ogg', 25, 1, 5)
var/mob/living/carbon/C = target
user.visible_message("<span class='danger'>[user] sprays [src] \
into the face of [target]!</span>")
target << "<span class='userdanger'>[user] sprays [src] into your \
face!</span>"
user.visible_message("<span class='danger'>[user] sprays [src] into the face of [target]!</span>")
target << "<span class='userdanger'>[user] sprays [src] into your face!</span>"
if(C.client)
C.blur_eyes(3)
C.blind_eyes(1)
if(C.check_eye_prot() <= 0) // no eye protection? ARGH IT BURNS.
if(C.get_eye_protection() <= 0) // no eye protection? ARGH IT BURNS.
C.confused = max(C.confused, 3)
C.Weaken(3)
if(ishuman(C) && actually_paints)
@@ -653,11 +649,11 @@
if(istype(target, /obj/structure/window))
if(actually_paints)
target.color = paint_color
target.add_atom_colour(paint_color, WASHABLE_COLOUR_PRIORITY)
if(color_hex2num(paint_color) < 255)
target.set_opacity(255)
target.SetOpacity(255)
else
target.set_opacity(initial(target.opacity))
target.SetOpacity(initial(target.opacity))
. = use_charges(2)
var/fraction = min(1, . / reagents.maximum_volume)
reagents.reaction(target, TOUCH, fraction * volume_multiplier)
@@ -695,8 +691,7 @@
/obj/item/toy/crayon/spraycan/gang/examine(mob/user)
. = ..()
if((user.mind && user.mind.gang_datum) || isobserver(user))
user << "This spraycan has \
been specially modified for tagging territory."
user << "This spraycan has been specially modified for tagging territory."
/obj/item/toy/crayon/spraycan/borg
name = "cyborg spraycan"
@@ -705,7 +700,7 @@
/obj/item/toy/crayon/spraycan/borg/afterattack(atom/target,mob/user,proximity)
var/diff = ..()
if(!isrobot(user))
if(!iscyborg(user))
user << "<span class='notice'>How did you get this?</span>"
qdel(src)
return FALSE
+3 -1
View File
@@ -36,6 +36,8 @@
flick("carp_swell", src)
//Wait for animation to end
sleep(6)
if(!src || qdeleted(src))//we got toasted while animating
return
//Make space carp
var/mob/living/M = new mobtype(get_turf(src))
//Make carp non-hostile to user, and their allies
@@ -49,4 +51,4 @@
visible_message("<span class='warning'>You have a bad feeling about this.</span>") //welcome to the hostile carp enjoy your die
else
visible_message("<span class='notice'>The newly grown [M.name] looks up at you with friendly eyes.</span>")
qdel(src)
qdel(src)
+135 -65
View File
@@ -11,9 +11,12 @@ var/global/list/obj/item/device/pda/PDAs = list()
icon_state = "pda"
item_state = "electronic"
flags = NOBLUDGEON
w_class = 1
w_class = WEIGHT_CLASS_TINY
slot_flags = SLOT_ID | SLOT_BELT
origin_tech = "programming=2"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 100)
resistance_flags = FIRE_PROOF | ACID_PROOF
//Main variables
var/owner = null // String name of owner
@@ -50,14 +53,35 @@ var/global/list/obj/item/device/pda/PDAs = list()
var/image/photo = null //Scanned photo
var/list/contained_item = list(/obj/item/weapon/pen, /obj/item/toy/crayon, /obj/item/weapon/lipstick, /obj/item/device/flashlight/pen, /obj/item/clothing/mask/cigarette)
var/obj/item/inserted_item //Used for pen, crayon, and lipstick insertion or removal. Same as above.
var/overlays_x_offset = 0 //x offset to use for certain overlays
/obj/item/device/pda/pickup(mob/user)
..()
if(fon)
SetLuminosity(0)
user.AddLuminosity(f_lum)
/obj/item/device/pda/dropped(mob/user)
..()
if(fon)
user.AddLuminosity(-f_lum)
SetLuminosity(f_lum)
/obj/item/device/pda/New()
..()
if(fon)
set_light(f_lum)
if(!isturf(loc))
loc.AddLuminosity(f_lum)
SetLuminosity(0)
else
SetLuminosity(f_lum)
PDAs += src
if(default_cartridge)
cartridge = new default_cartridge(src)
new /obj/item/weapon/pen(src)
inserted_item = new /obj/item/weapon/pen(src)
update_icon()
/obj/item/device/pda/proc/update_label()
name = "PDA-[owner] ([ownjob])" //Name generalisation
@@ -71,6 +95,25 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/GetID()
return id
/obj/item/device/pda/update_icon()
cut_overlays()
if(id)
var/image/I = image(icon_state = "id_overlay", pixel_x = overlays_x_offset)
add_overlay(I)
if(inserted_item)
var/image/I = image(icon_state = "insert_overlay", pixel_x = overlays_x_offset)
add_overlay(I)
if(fon)
var/image/I = image(icon_state = "light_overlay", pixel_x = overlays_x_offset)
add_overlay(I)
if(pai)
if(pai.pai)
var/image/I = image(icon_state = "pai_overlay", pixel_x = overlays_x_offset)
add_overlay(I)
else
var/image/I = image(icon_state = "pai_off_overlay", pixel_x = overlays_x_offset)
add_overlay(I)
/obj/item/device/pda/MouseDrop(obj/over_object, src_location, over_location)
var/mob/M = usr
if((!istype(over_object, /obj/screen)) && usr.canUseTopic(src))
@@ -170,11 +213,14 @@ var/global/list/obj/item/device/pda/PDAs = list()
dat += "<li><a href='byond://?src=\ref[src];choice=Gas Scan'><img src=pda_reagent.png> [scanmode == 5 ? "Disable" : "Enable"] Gas Scanner</a></li>"
if (cartridge.access_remote_door)
dat += "<li><a href='byond://?src=\ref[src];choice=Toggle Door'><img src=pda_rdoor.png> Toggle Remote Door</a></li>"
if (cartridge.access_dronephone)
dat += "<li><a href='byond://?src=\ref[src];choice=Drone Phone'><img src=pda_dronephone.png> Drone Phone</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=3'><img src=pda_atmos.png> Atmospheric Scan</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=Light'><img src=pda_flashlight.png> [fon ? "Disable" : "Enable"] Flashlight</a></li>"
if (pai)
if(pai.loc != src)
pai = null
update_icon()
else
dat += "<li><a href='byond://?src=\ref[src];choice=pai;option=1'>pAI Device Configuration</a></li>"
dat += "<li><a href='byond://?src=\ref[src];choice=pai;option=2'>Eject pAI Device</a></li>"
@@ -257,7 +303,6 @@ var/global/list/obj/item/device/pda/PDAs = list()
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<br>"
else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub.
dat += cart
@@ -290,20 +335,21 @@ var/global/list/obj/item/device/pda/PDAs = list()
cartridge.mode = mode
cartridge.unlock()
if ("Authenticate")//Checks for ID
id_check(U, 1)
id_check(U)
if("UpdateInfo")
ownjob = id.assignment
if(istype(id, /obj/item/weapon/card/id/syndicate))
owner = id.registered_name
update_label()
if("Eject")//Ejects the cart, only done from hub.
if (!isnull(cartridge))
var/turf/T = loc
if(ismob(T))
T = T.loc
cartridge.loc = T
U.put_in_hands(cartridge)
U << "<span class='notice'>You remove [cartridge] from [src].</span>"
scanmode = 0
if (cartridge.radio)
cartridge.radio.hostpda = null
cartridge = null
update_icon()
//MENU FUNCTIONS===================================
@@ -326,10 +372,17 @@ var/global/list/obj/item/device/pda/PDAs = list()
if("Light")
if(fon)
fon = 0
set_light(0)
if(src in U.contents)
U.AddLuminosity(-f_lum)
else
SetLuminosity(0)
else
fon = 1
set_light(f_lum)
if(src in U.contents)
U.AddLuminosity(f_lum)
else
SetLuminosity(f_lum)
update_icon()
if("Medical Scan")
if(scanmode == 1)
scanmode = 0
@@ -358,6 +411,14 @@ var/global/list/obj/item/device/pda/PDAs = list()
scanmode = 0
else if((!isnull(cartridge)) && (cartridge.access_atmos))
scanmode = 5
if("Drone Phone")
var/area/A = get_area(U)
var/alert_s = input(U,"Alert severity level","Ping Drones",null) as null|anything in list("Low","Medium","High","Critical")
if(A && alert_s)
var/msg = "<span class='boldnotice'>NON-DRONE PING: [U.name]: [alert_s] priority alert in [A.name]!</span>"
_alert_drones(msg, 1)
U << msg
//NOTEKEEPER FUNCTIONS===================================
@@ -441,6 +502,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
M.close()
if("Detonate")//Detonate PDA
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
var/obj/item/device/pda/P = locate(href_list["target"])
@@ -497,7 +559,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
//EXTRA FUNCTIONS===================================
if (mode == 2||mode == 21)//To clear message overlays.
cut_overlays()
update_icon()
if ((honkamt > 0) && (prob(60)))//For clown virus.
honkamt--
@@ -519,6 +581,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
else
id.loc = get_turf(src)
id = null
update_icon()
/obj/item/device/pda/proc/msg_input(mob/living/U = usr)
var/t = stripped_input(U, "Please enter message", name, null, MAX_MESSAGE_LEN)
@@ -590,7 +653,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(L && L.stat != UNCONSCIOUS)
L << "\icon[src] <b>Message from [source.owner] ([source.ownjob]), </b>\"[msg.message]\"[msg.get_photo_ref()] (<a href='byond://?src=\ref[src];choice=Message;skiprefresh=1;target=\ref[source]'>Reply</a>)"
cut_overlays()
update_icon()
add_overlay(image(icon, icon_alert))
/obj/item/device/pda/proc/show_to_ghosts(mob/living/user, datum/data_pda_msg/msg,multiple = 0)
@@ -646,7 +709,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
if(id)
remove_id()
else
usr << "<span class='warning'>This PDA does not have an ID in it!</span>"
remove_pen()
/obj/item/device/pda/verb/verb_remove_id()
set category = "Object"
@@ -671,50 +734,52 @@ var/global/list/obj/item/device/pda/PDAs = list()
return
if (usr.canUseTopic(src))
var/obj/item/weapon/pen/O = locate() in src
if(O)
if (istype(loc, /mob))
var/mob/M = loc
if(M.get_active_hand() == null)
M.put_in_hands(O)
usr << "<span class='notice'>You remove \the [O] from \the [src].</span>"
return
O.loc = get_turf(src)
else
usr << "<span class='warning'>This PDA does not have a pen in it!</span>"
remove_pen()
/obj/item/device/pda/proc/id_check(mob/user, choice as num)//To check for IDs; 1 for in-pda use, 2 for out of pda use.
if(choice == 1)
if (id)
remove_id()
/obj/item/device/pda/proc/remove_pen()
if(inserted_item)
if(ismob(loc))
var/mob/M = loc
M.put_in_hands(inserted_item)
else
var/obj/item/I = user.get_active_hand()
if (istype(I, /obj/item/weapon/card/id))
if(!user.unEquip(I))
return 0
I.loc = src
id = I
inserted_item.forceMove(loc)
usr << "<span class='notice'>You remove \the [inserted_item] from \the [src].</span>"
inserted_item = null
update_icon()
else
var/obj/item/weapon/card/I = user.get_active_hand()
if (istype(I, /obj/item/weapon/card/id) && I:registered_name)
if(!user.unEquip(I))
return 0
var/obj/old_id = id
I.loc = src
id = I
usr << "<span class='warning'>This PDA does not have a pen in it!</span>"
//trying to insert or remove an id
/obj/item/device/pda/proc/id_check(mob/user, obj/item/weapon/card/id/I)
if(!I)
if(id)
remove_id()
return 1
else
var/obj/item/weapon/card/id/C = user.get_active_held_item()
if(istype(C))
I = C
if(I && I.registered_name)
if(!user.transferItemToLoc(I, src))
return 0
var/obj/old_id = id
id = I
if(old_id)
user.put_in_hands(old_id)
update_icon()
return 1
// access to status display signals
/obj/item/device/pda/attackby(obj/item/C, mob/user, params)
if(istype(C, /obj/item/weapon/cartridge) && !cartridge)
cartridge = C
if(!user.unEquip(C))
if(!user.transferItemToLoc(C, src))
return
cartridge.loc = src
cartridge = C
user << "<span class='notice'>You insert [cartridge] into [src].</span>"
if(cartridge.radio)
cartridge.radio.hostpda = src
update_icon()
else if(istype(C, /obj/item/weapon/card/id))
var/obj/item/weapon/card/id/idcard = C
@@ -728,33 +793,35 @@ var/global/list/obj/item/device/pda/PDAs = list()
user << "<span class='notice'>Card scanned.</span>"
else
//Basic safety check. If either both objects are held by user or PDA is on ground and card is in hand.
if(((src in user.contents) && (C in user.contents)) || (istype(loc, /turf) && in_range(src, user) && (C in user.contents)) )
if(!id_check(user, 2))
if(((src in user.contents) || (isturf(loc) && in_range(src, user))) && (C in user.contents))
if(!id_check(user, idcard))
return
user << "<span class='notice'>You put the ID into \the [src]'s slot.</span>"
updateSelfDialog()//Update self dialog on success.
return //Return in case of failed check or when successful.
updateSelfDialog()//For the non-input related code.
else if(istype(C, /obj/item/device/paicard) && !src.pai)
if(!user.unEquip(C))
if(!user.transferItemToLoc(C, src))
return
C.loc = src
pai = C
user << "<span class='notice'>You slot \the [C] into [src].</span>"
update_icon()
updateUsrDialog()
else if(istype(C, /obj/item/weapon/pen))
var/obj/item/weapon/pen/O = locate() in src
if(O)
user << "<span class='warning'>There is already a pen in \the [src]!</span>"
else if(is_type_in_list(C, contained_item)) //Checks if there is a pen
if(inserted_item)
user << "<span class='warning'>There is already \a [inserted_item] in \the [src]!</span>"
else
if(!user.unEquip(C))
if(!user.transferItemToLoc(C, src))
return
C.loc = src
user << "<span class='notice'>You slide \the [C] into \the [src].</span>"
inserted_item = C
update_icon()
else if(istype(C, /obj/item/weapon/photo))
var/obj/item/weapon/photo/P = C
photo = P.img
user << "<span class='notice'>You scan \the [C].</span>"
else if(hidden_uplink && hidden_uplink.active)
hidden_uplink.attackby(C, user, params)
else
return ..()
@@ -850,12 +917,23 @@ var/global/list/obj/item/device/pda/PDAs = list()
/obj/item/device/pda/Destroy()
PDAs -= src
if(id)
qdel(id)
id = null
if(cartridge)
qdel(cartridge)
cartridge = null
if(pai)
qdel(pai)
pai = null
if(inserted_item)
qdel(inserted_item)
inserted_item = null
return ..()
//AI verb and proc for sending PDA messages.
/mob/living/silicon/ai/proc/cmd_send_pdamesg(mob/user)
var/list/names = list()
var/list/plist = list()
var/list/namecounts = list()
@@ -872,15 +950,7 @@ var/global/list/obj/item/device/pda/PDAs = list()
else if (P == src.aiPDA)
continue
var/name = P.owner
if (name in names)
namecounts[name]++
name = text("[name] ([namecounts[name]])")
else
names.Add(name)
namecounts[name] = 1
plist[text("[name]")] = P
plist[avoid_assoc_duplicate_keys(P.owner, namecounts)] = P
var/c = input(user, "Please select a PDA") as null|anything in sortList(plist)
@@ -166,14 +166,15 @@
icon_state = "pda-library"
icon_alert = "pda-r-library"
default_cartridge = /obj/item/weapon/cartridge/librarian
desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a WGW-11 series e-reader."
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a WGW-11 series e-reader."
note = "Congratulations, your station has chosen the Thinktronic 5290 WGW-11 Series E-reader and Personal Data Assistant!"
silent = 1 //Quiet in the library!
overlays_x_offset = -3
/obj/item/device/pda/clear
name = "clear PDA"
icon_state = "pda-clear"
desc = "A portable microcomputer by Thinktronic Systems, LTD. This is model is a special edition with a transparent case."
desc = "A portable microcomputer by Thinktronic Systems, LTD. This model is a special edition with a transparent case."
note = "Congratulations, you have chosen the Thinktronic 5230 Personal Data Assistant Deluxe Special Max Turbo Limited Edition!"
/obj/item/device/pda/cook
+10 -1
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/pda.dmi'
icon_state = "cart"
item_state = "electronic"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/obj/item/radio/integrated/radio = null
var/access_security = 0
@@ -23,6 +23,7 @@
var/access_status_display = 0
var/access_quartermaster = 0
var/access_hydroponics = 0
var/access_dronephone = 0
var/bot_access_flags = 0 //Bit flags. Selection: SEC_BOT|MULE_BOT|FLOOR_BOT|CLEAN_BOT|MED_BOT
var/spam_enabled = 0 //Enables "Send to All" Option
@@ -45,12 +46,14 @@
name = "\improper Power-ON cartridge"
icon_state = "cart-e"
access_engine = 1
access_dronephone = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/atmos
name = "\improper BreatheDeep cartridge"
icon_state = "cart-a"
access_atmos = 1
access_dronephone = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/medical
@@ -84,6 +87,7 @@
desc = "The ultimate in clean-room design."
icon_state = "cart-j"
access_janitor = 1
access_dronephone = 1
bot_access_flags = CLEAN_BOT
/obj/item/weapon/cartridge/lawyer
@@ -120,6 +124,7 @@
name = "\improper B.O.O.P. Remote Control cartridge"
desc = "Packed with heavy duty triple-bot interlink!"
bot_access_flags = FLOOR_BOT|CLEAN_BOT|MED_BOT
access_dronephone = 1
/obj/item/weapon/cartridge/signal
name = "generic signaler cartridge"
@@ -161,6 +166,7 @@
access_security = 1
access_newscaster = 1
access_quartermaster = 1
access_dronephone = 1
/obj/item/weapon/cartridge/hos
name = "\improper R.O.B.U.S.T. DELUXE cartridge"
@@ -178,6 +184,7 @@
access_status_display = 1
access_engine = 1
access_atmos = 1
access_dronephone = 1
bot_access_flags = FLOOR_BOT
/obj/item/weapon/cartridge/cmo
@@ -196,6 +203,7 @@
access_status_display = 1
access_reagent_scanner = 1
access_atmos = 1
access_dronephone = 1
bot_access_flags = FLOOR_BOT|CLEAN_BOT|MED_BOT
/obj/item/weapon/cartridge/rd/New()
@@ -216,6 +224,7 @@
access_newscaster = 1
access_quartermaster = 1
access_janitor = 1
access_dronephone = 1
bot_access_flags = SEC_BOT|MULE_BOT|FLOOR_BOT|CLEAN_BOT|MED_BOT
spam_enabled = 1
+2 -6
View File
@@ -28,18 +28,14 @@
var/last_transmission
var/datum/radio_frequency/radio_connection
/obj/item/radio/integrated/signal/New()
..()
if(SSradio)
initialize()
/obj/item/radio/integrated/signal/Destroy()
if(SSradio)
SSradio.remove_object(src, frequency)
radio_connection = null
return ..()
/obj/item/radio/integrated/signal/initialize()
/obj/item/radio/integrated/signal/Initialize()
..()
if (src.frequency < 1200 || src.frequency > 1600)
src.frequency = sanitize_frequency(src.frequency)
+15 -13
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/aicards.dmi'
icon_state = "aicard" // aicard-full
item_state = "electronic"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
flags = NOBLUDGEON
var/flush = FALSE
@@ -53,7 +53,7 @@
data["wireless"] = !AI.control_disabled //todo disabled->enabled
data["radio"] = AI.radio_enabled
data["isDead"] = AI.stat == DEAD
data["isBraindead"] = AI.client ? TRUE : FALSE
data["isBraindead"] = AI.client ? FALSE : TRUE
data["wiping"] = flush
return data
@@ -62,17 +62,19 @@
return
switch(action)
if("wipe")
var/confirm = alert("Are you sure you want to wipe this card's memory? This cannot be undone once started.", name, "Yes", "No")
if(confirm == "Yes" && !..())
flush = TRUE
if(AI && AI.loc == src)
AI.suiciding = TRUE
AI << "Your core files are being wiped!"
while(AI.stat != DEAD)
AI.adjustOxyLoss(2)
AI.updatehealth()
sleep(10)
flush = FALSE
if(flush)
flush = FALSE
else
var/confirm = alert("Are you sure you want to wipe this card's memory?", name, "Yes", "No")
if(confirm == "Yes" && !..())
flush = TRUE
if(AI && AI.loc == src)
AI << "Your core files are being wiped!"
while(AI.stat != DEAD && flush)
AI.adjustOxyLoss(1)
AI.updatehealth()
sleep(5)
flush = FALSE
. = TRUE
if("wireless")
AI.control_disabled = !AI.control_disabled
@@ -1,25 +0,0 @@
/obj/item/device/boobytrap
name = "booby trap"
desc = null //Different examine for traitors
item_state = "electronic"
icon_state = "boobytrap"
w_class = 1
throw_range = 4
throw_speed = 1
flags = NOBLUDGEON
force = 3
attack_verb = list("trapped", "rused", "tricked")
materials = list(MAT_METAL=50, MAT_GLASS=30)
origin_tech = "syndicate=1;combat=3;engineering=3"
/obj/item/device/boobytrap/proc/blow()
explosion(src.loc,0,0,2,4,flame_range = 4)
qdel(src)
/obj/item/device/boobytrap/examine(mob/user)
..()
if(user.mind in ticker.mode.traitors) //No nuke ops because the device is excluded from nuclear
user << "A small device used to rig lockers and boxes with an explosive surprise. \
To use, simply attach it to a box or a locker."
else
user << "A suspicious array of delicate wires and parts."
+32 -18
View File
@@ -10,7 +10,7 @@
desc = "For illicit snooping through the camera network."
icon = 'icons/obj/device.dmi'
icon_state = "camera_bug"
w_class = 1
w_class = WEIGHT_CLASS_TINY
item_state = "camera_bug"
throw_speed = 4
throw_range = 20
@@ -60,13 +60,14 @@
/obj/item/device/camera_bug/check_eye(mob/user)
if ( loc != user || user.incapacitated() || user.eye_blind || !current )
user.unset_machine()
return
return 0
var/turf/T = get_turf(user.loc)
if(T.z != current.z || !current.can_use())
user << "<span class='danger'>[src] has lost the signal.</span>"
current = null
user.unset_machine()
return 0
return 1
/obj/item/device/camera_bug/on_unset_machine(mob/user)
user.reset_perspective(null)
@@ -135,11 +136,16 @@
return .(cameras)
return html
/obj/item/device/camera_bug/proc/get_seens()
if(current && current.can_use())
var/list/seen = current.can_see()
return seen
/obj/item/device/camera_bug/proc/camera_report()
// this should only be called if current exists
var/dat = ""
if(current && current.can_use())
var/list/seen = current.can_see()
var/list/seen = get_seens()
if(seen && seen.len >= 1)
var/list/names = list()
for(var/obj/singularity/S in seen) // god help you if you see more than one
if(S.name in names)
@@ -189,23 +195,29 @@
if("mode" in href_list)
track_mode = text2num(href_list["mode"])
if("monitor" in href_list)
var/obj/machinery/camera/C = locate(href_list["monitor"])
if(C)
//You can't locate on a list with keys
var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["monitor"]) in cameras
if(C && istype(C))
track_mode = BUGMODE_MONITOR
current = C
usr.reset_perspective(null)
interact()
if("track" in href_list)
var/atom/A = locate(href_list["track"])
if(A)
tracking = A
tracked_name = A.name
last_found = current.c_tag
last_seen = world.time
track_mode = BUGMODE_TRACK
var/list/seen = get_seens()
if(seen && seen.len >= 1)
var/atom/A = locate(href_list["track"]) in seen
if(A && istype(A))
tracking = A
tracked_name = A.name
last_found = current.c_tag
last_seen = world.time
track_mode = BUGMODE_TRACK
if("emp" in href_list)
var/obj/machinery/camera/C = locate(href_list["emp"])
if(istype(C) && C.bug == src)
//You can't locate on a list with keys
var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["emp"]) in cameras
if(C && istype(C) && C.bug == src)
C.emp_act(1)
C.bug = null
bugged_cameras -= C.c_tag
@@ -216,8 +228,10 @@
current = null
return
if("view" in href_list)
var/obj/machinery/camera/C = locate(href_list["view"])
if(istype(C))
//You can't locate on a list with keys
var/list/cameras = flatten_list(bugged_cameras)
var/obj/machinery/camera/C = locate(href_list["view"]) in cameras
if(C && istype(C))
if(!C.can_use())
usr << "<span class='warning'>Something's wrong with that camera! You can't get a feed.</span>"
return
@@ -7,7 +7,7 @@
throwforce = 5
throw_speed = 3
throw_range = 5
w_class = 2
w_class = WEIGHT_CLASS_SMALL
origin_tech = "syndicate=4;magnets=4"
var/can_use = 1
var/obj/effect/dummy/chameleon/active_dummy = null
@@ -23,6 +23,7 @@
disrupt()
/obj/item/device/chameleon/equipped()
..()
disrupt()
/obj/item/device/chameleon/attack_self()
@@ -37,6 +38,7 @@
var/obj/temp = new/obj()
temp.appearance = target.appearance
temp.layer = initial(target.layer) // scanning things in your inventory
temp.plane = initial(target.plane)
saved_appearance = temp.appearance
/obj/item/device/chameleon/proc/toggle()
@@ -47,13 +49,13 @@
qdel(active_dummy)
active_dummy = null
usr << "<span class='notice'>You deactivate \the [src].</span>"
PoolOrNew(/obj/effect/overlay/temp/emp/pulse, get_turf(src))
new /obj/effect/overlay/temp/emp/pulse(get_turf(src))
else
playsound(get_turf(src), 'sound/effects/pop.ogg', 100, 1, -6)
var/obj/effect/dummy/chameleon/C = new/obj/effect/dummy/chameleon(usr.loc)
C.activate(usr, saved_appearance, src)
usr << "<span class='notice'>You activate \the [src].</span>"
PoolOrNew(/obj/effect/overlay/temp/emp/pulse, get_turf(src))
new /obj/effect/overlay/temp/emp/pulse(get_turf(src))
/obj/item/device/chameleon/proc/disrupt(delete_dummy = 1)
if(active_dummy)
@@ -114,7 +116,7 @@
master.disrupt()
/obj/effect/dummy/chameleon/relaymove(mob/user, direction)
if(istype(loc, /turf/open/space) || !direction)
if(isspaceturf(loc) || !direction)
return //No magical space movement!
if(can_move)
@@ -3,7 +3,7 @@
desc = null //Different examine for traitors
item_state = "electronic"
icon_state = "doorCharge"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
throw_range = 4
throw_speed = 1
flags = NOBLUDGEON
@@ -25,6 +25,13 @@
if(prob(25))
ex_act(1)
/obj/item/device/doorCharge/Destroy()
if(istype(loc, /obj/machinery/door/airlock))
var/obj/machinery/door/airlock/A = loc
if(A.charge == src)
A.charge = null
return ..()
/obj/item/device/doorCharge/examine(mob/user)
..()
if(user.mind in ticker.mode.traitors) //No nuke ops because the device is excluded from nuclear
+60 -30
View File
@@ -4,7 +4,7 @@
icon = 'icons/obj/lighting.dmi'
icon_state = "flashlight"
item_state = "flashlight"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
materials = list(MAT_METAL=50, MAT_GLASS=20)
@@ -12,21 +12,32 @@
var/on = 0
var/brightness_on = 4 //luminosity when on
/obj/item/device/flashlight/initialize()
/obj/item/device/flashlight/Initialize()
..()
update_brightness()
/obj/item/device/flashlight/proc/update_brightness()
if(on)
icon_state = "[initial(icon_state)]-on"
set_light(brightness_on)
SetLuminosity(brightness_on)
else
icon_state = initial(icon_state)
set_light(0)
SetLuminosity(0)
/obj/item/device/flashlight/proc/update_brightness(mob/user = null)
if(on)
icon_state = "[initial(icon_state)]-on"
if(loc == user)
user.AddLuminosity(brightness_on)
else if(isturf(loc))
SetLuminosity(brightness_on)
else
icon_state = initial(icon_state)
if(loc == user)
user.AddLuminosity(-brightness_on)
else if(isturf(loc))
SetLuminosity(0)
/obj/item/device/flashlight/attack_self(mob/user)
on = !on
update_brightness()
update_brightness(user)
for(var/X in actions)
var/datum/action/A = X
A.UpdateButtonIcon()
@@ -45,17 +56,15 @@
return
var/mob/living/carbon/human/H = M //mob has protective eyewear
if(istype(M, /mob/living/carbon/human) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
if(ishuman(M) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags_cover & GLASSESCOVERSEYES)))
user << "<span class='notice'>You're going to need to remove that [(H.head && H.head.flags_cover & HEADCOVERSEYES) ? "helmet" : (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) ? "mask": "glasses"] first.</span>"
return
if(M == user) //they're using it on themselves
if(M.flash_eyes(visual = 1))
M.visible_message("[M] directs [src] to \his eyes.", \
"<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
if(M.flash_act(visual = 1))
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes! Trippy!</span>")
else
M.visible_message("[M] directs [src] to \his eyes.", \
"<span class='notice'>You wave the light in front of your eyes.</span>")
M.visible_message("[M] directs [src] to [M.p_their()] eyes.", "<span class='notice'>You wave the light in front of your eyes.</span>")
else
user.visible_message("<span class='warning'>[user] directs [src] to [M]'s eyes.</span>", \
"<span class='danger'>You direct [src] to [M]'s eyes.</span>")
@@ -66,11 +75,26 @@
else if(C.dna.check_mutation(XRAY)) //mob has X-RAY vision
user << "<span class='danger'>[C] pupils give an eerie glow!</span>"
else //they're okay!
if(C.flash_eyes(visual = 1))
if(C.flash_act(visual = 1))
user << "<span class='notice'>[C]'s pupils narrow.</span>"
else
return ..()
/obj/item/device/flashlight/pickup(mob/user)
..()
if(on)
user.AddLuminosity(brightness_on)
SetLuminosity(0)
/obj/item/device/flashlight/dropped(mob/user)
..()
if(on)
user.AddLuminosity(-brightness_on)
SetLuminosity(brightness_on)
/obj/item/device/flashlight/pen
name = "penlight"
desc = "A pen-sized light, used by medical staff. It can also be used to create a hologram to alert people of incoming medical assistance."
@@ -87,7 +111,7 @@
return
var/T = get_turf(target)
if(locate(/mob/living) in T)
PoolOrNew(/obj/effect/overlay/temp/medical_holosign, list(T,user)) //produce a holographic glow
new /obj/effect/overlay/temp/medical_holosign(T,user) //produce a holographic glow
holo_cooldown = world.time + 100
return
..()
@@ -121,7 +145,7 @@
icon_state = "lamp"
item_state = "lamp"
brightness_on = 5
w_class = 4
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
materials = list()
on = 1
@@ -144,7 +168,7 @@
attack_self(usr)
//Bananalamp
obj/item/device/flashlight/lamp/bananalamp
/obj/item/device/flashlight/lamp/bananalamp
name = "banana lamp"
desc = "Only a clown would think to make a ghetto banana-shaped lamp. Even has a goofy pullstring."
icon_state = "bananalamp"
@@ -155,7 +179,7 @@ obj/item/device/flashlight/lamp/bananalamp
/obj/item/device/flashlight/flare
name = "flare"
desc = "A red Nanotrasen issued flare. There are instructions on the side, it reads 'pull cord, make light'."
w_class = 2
w_class = WEIGHT_CLASS_SMALL
brightness_on = 7 // Pretty bright.
icon_state = "flare"
item_state = "flare"
@@ -164,16 +188,13 @@ obj/item/device/flashlight/lamp/bananalamp
var/on_damage = 7
var/produce_heat = 1500
heat = 1000
light_color = LIGHT_COLOR_FLARE
/obj/item/device/flashlight/flare/New()
fuel = rand(800, 1000) // Sorry for changing this so much but I keep under-estimating how long X number of ticks last in seconds.
..()
/obj/item/device/flashlight/flare/process()
var/turf/pos = get_turf(src)
if(pos)
pos.hotspot_expose(produce_heat, 5)
open_flame(heat)
fuel = max(fuel - 1, 0)
if(!fuel || !on)
turn_off()
@@ -181,13 +202,24 @@ obj/item/device/flashlight/lamp/bananalamp
icon_state = "[initial(icon_state)]-empty"
STOP_PROCESSING(SSobj, src)
/obj/item/device/flashlight/flare/ignition_effect(atom/A, mob/user)
if(fuel && on)
. = "<span class='notice'>[user] lights [A] with [src] like a real \
badass.</span>"
else
. = ""
/obj/item/device/flashlight/flare/proc/turn_off()
on = 0
force = initial(src.force)
damtype = initial(src.damtype)
update_brightness()
if(ismob(loc))
var/mob/U = loc
update_brightness(U)
else
update_brightness(null)
/obj/item/device/flashlight/flare/update_brightness()
/obj/item/device/flashlight/flare/update_brightness(mob/user = null)
..()
if(on)
item_state = "[initial(item_state)]-on"
@@ -217,7 +249,7 @@ obj/item/device/flashlight/lamp/bananalamp
/obj/item/device/flashlight/flare/torch
name = "torch"
desc = "A torch fashioned from some leaves and a log."
w_class = 4
w_class = WEIGHT_CLASS_BULKY
brightness_on = 4
icon_state = "torch"
item_state = "torch"
@@ -230,7 +262,6 @@ obj/item/device/flashlight/lamp/bananalamp
item_state = "lantern"
desc = "A mining lantern."
brightness_on = 6 // luminosity when on
light_color = LIGHT_COLOR_FIRE
/obj/item/device/flashlight/slime
@@ -240,14 +271,13 @@ obj/item/device/flashlight/lamp/bananalamp
icon = 'icons/obj/lighting.dmi'
icon_state = "slime"
item_state = "slime"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
materials = list()
brightness_on = 6 //luminosity when on
light_color = LIGHT_COLOR_SLIME_LAMP
/obj/item/device/flashlight/emp
origin_tech = "magnets=3;syndicate=1"
origin_tech = "magnets=3;syndicate=1"
var/emp_max_charges = 4
var/emp_cur_charges = 4
var/charge_tick = 0
@@ -9,7 +9,7 @@
desc = "A handheld device used for detecting and measuring radiation pulses."
icon_state = "geiger_off"
item_state = "multitool"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
materials = list(MAT_METAL = 150, MAT_GLASS = 150)
var/scanning = 0
@@ -99,7 +99,7 @@
user << "<span class='notice'>\icon[src] You switch [scanning ? "on" : "off"] [src].</span>"
/obj/item/device/geiger_counter/attack(mob/living/M, mob/user)
if(user.a_intent == "help")
if(user.a_intent == INTENT_HELP)
if(!emagged)
user.visible_message("<span class='notice'>[user] scans [M] with [src].</span>", "<span class='notice'>You scan [M]'s radiation levels with [src]...</span>")
if(!M.radiation)
@@ -122,7 +122,7 @@
return 0
user.visible_message("<span class='notice'>[user] unscrews [src]'s maintenance panel and begins fiddling with its innards...</span>", "<span class='notice'>You begin resetting [src]...</span>")
playsound(user, I.usesound, 50, 1)
if(!do_after(user, 40/I.toolspeed, target = user))
if(!do_after(user, 40*I.toolspeed, target = user))
return 0
user.visible_message("<span class='notice'>[user] refastens [src]'s maintenance panel!</span>", "<span class='notice'>You reset [src] to its factory settings!</span>")
playsound(user, 'sound/items/Screwdriver2.ogg', 50, 1)
+17 -7
View File
@@ -1,8 +1,9 @@
//copy pasta of the space piano, don't hurt me -Pete
/obj/item/device/instrument
name = "generic instrument"
burn_state = FLAMMABLE
burntime = 20
resistance_flags = FLAMMABLE
obj_integrity = 100
max_integrity = 100
var/datum/song/handheld/song
var/instrumentId = "generic"
var/instrumentExt = "ogg"
@@ -10,6 +11,7 @@
/obj/item/device/instrument/New()
song = new(instrumentId, src)
song.instrumentExt = instrumentExt
..()
/obj/item/device/instrument/Destroy()
qdel(song)
@@ -17,12 +19,13 @@
return ..()
/obj/item/device/instrument/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like \he's trying to commit suicide..</span>")
user.visible_message("<span class='suicide'>[user] begins to play 'Gloomy Sunday'! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (BRUTELOSS)
/obj/item/device/instrument/initialize()
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/item/device/instrument/Initialize(mapload)
..()
if(mapload)
song.tempo = song.sanitize_tempo(song.tempo) // tick_lag isn't set when the map is loaded
/obj/item/device/instrument/attack_self(mob/user)
if(!user.IsAdvancedToolUser())
@@ -50,6 +53,13 @@
hitsound = "swing_hit"
instrumentId = "violin"
/obj/item/device/instrument/violin/golden
name = "golden violin"
desc = "A golden musical instrument with four strings and a bow. \"The devil went down to space, he was looking for an assistant to grief.\""
icon_state = "golden_violin"
item_state = "golden_violin"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/device/instrument/guitar
name = "guitar"
desc = "It's made of wood and has bronze strings."
@@ -62,7 +72,7 @@
instrumentId = "guitar"
/obj/item/device/instrument/eguitar
name = "eletric guitar"
name = "electric guitar"
desc = "Makes all your shredding needs possible."
icon = 'icons/obj/musician.dmi'
icon_state = "eguitar"
@@ -70,4 +80,4 @@
force = 12
attack_verb = list("played metal on", "shredded", "crashed", "smashed")
hitsound = 'sound/weapons/stringsmash.ogg'
instrumentId = "eguitar"
instrumentId = "eguitar"
@@ -8,7 +8,7 @@
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
materials = list(MAT_METAL=500, MAT_GLASS=500)
w_class = 2 //Increased to 2, because diodes are w_class 2. Conservation of matter.
w_class = WEIGHT_CLASS_SMALL
origin_tech = "combat=1;magnets=2"
var/turf/pointer_loc
var/energy = 5
@@ -41,9 +41,8 @@
/obj/item/device/laser_pointer/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/micro_laser))
if(!diode)
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
diode = W
user << "<span class='notice'>You install a [diode.name] in [src].</span>"
else
@@ -71,7 +70,7 @@
return
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.dna.check_mutation(HULK) || (NOGUNS in H.dna.species.specflags))
if(H.dna.check_mutation(HULK) || (NOGUNS in H.dna.species.species_traits))
user << "<span class='warning'>Your fingers can't press the button!</span>"
return
@@ -98,19 +97,17 @@
severity = 0
//20% chance to actually hit the eyes
if(prob(effectchance * diode.rating) && C.flash_eyes(severity))
if(prob(effectchance * diode.rating) && C.flash_act(severity))
outmsg = "<span class='notice'>You blind [C] by shining [src] in their eyes.</span>"
if(C.weakeyes)
C.Stun(1)
else
outmsg = "<span class='warning'>You fail to blind [C] by shining [src] at their eyes!</span>"
//robots
else if(isrobot(target))
else if(iscyborg(target))
var/mob/living/silicon/S = target
//20% chance to actually hit the sensors
if(prob(effectchance * diode.rating))
S.flash_eyes(affect_silicon = 1)
S.flash_act(affect_silicon = 1)
S.Weaken(rand(5,10))
S << "<span class='danger'>Your sensors were overloaded by a laser!</span>"
outmsg = "<span class='notice'>You overload [S] by shining [src] at their sensors.</span>"
@@ -130,10 +127,6 @@
//laser pointer image
icon_state = "pointer_[pointer_icon_state]"
var/list/showto = list()
for(var/mob/M in viewers(7,targloc))
if(M.client)
showto.Add(M.client)
var/image/I = image('icons/obj/projectiles.dmi',targloc,pointer_icon_state,10)
var/list/click_params = params2list(params)
if(click_params)
@@ -159,7 +152,7 @@
user << "<span class='warning'>[src]'s battery is overused, it needs time to recharge!</span>"
recharge_locked = 1
flick_overlay(I, showto, 10)
flick_overlay_view(I, targloc, 10)
icon_state = "pointer"
/obj/item/device/laser_pointer/process()
@@ -89,23 +89,31 @@
else
user << "<span class='warning'>You need one sheet of glass to replace lights!</span>"
if(istype(W, /obj/item/weapon/shard))
if(uses >= max_uses)
user << "<span class='warning'>[src.name] is full.</span>"
return
if(!user.temporarilyRemoveItemFromInventory(W))
return
AddUses(round(increment*0.75))
user << "<span class='notice'>You insert a shard of glass into the [src.name]. You have [uses] light\s remaining.</span>"
qdel(W)
return
if(istype(W, /obj/item/weapon/light))
var/new_bulbs = 0
var/obj/item/weapon/light/L = W
if(L.status == 0) // LIGHT OKAY
if(uses < max_uses)
if(!user.unEquip(W))
if(!user.temporarilyRemoveItemFromInventory(W))
return
AddUses(1)
qdel(L)
else
if(!user.unEquip(W))
if(!user.temporarilyRemoveItemFromInventory(W))
return
new_bulbs += AddShards(1)
user << "<span class='notice'>You insert the [L.name] into the [src.name]</span>"
AddShards(1, user)
qdel(L)
if(new_bulbs != 0)
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
user << "<span class='notice'>You insert the [L.name] into the [src.name]. " + status_string() + "</span>"
return
if(istype(W, /obj/item/weapon/storage))
@@ -126,7 +134,7 @@
else if(L.status == LIGHT_BROKEN || L.status == LIGHT_BURNED)
replaced_something = TRUE
AddShards(1)
AddShards(1, user)
qdel(L)
if(!found_lightbulbs)
@@ -146,7 +154,6 @@
/obj/item/device/lightreplacer/attack_self(mob/user)
user << status_string()
/obj/item/device/lightreplacer/update_icon()
icon_state = "lightreplacer[emagged]"
@@ -154,7 +161,6 @@
return "It has [uses] light\s remaining (plus [bulb_shards] fragment\s)."
/obj/item/device/lightreplacer/proc/Use(mob/user)
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
AddUses(-1)
return 1
@@ -163,12 +169,15 @@
/obj/item/device/lightreplacer/proc/AddUses(amount = 1)
uses = Clamp(uses + amount, 0, max_uses)
/obj/item/device/lightreplacer/proc/AddShards(amount = 1)
/obj/item/device/lightreplacer/proc/AddShards(amount = 1, user)
bulb_shards += amount
var/new_bulbs = round(bulb_shards / shards_required)
if(new_bulbs > 0)
AddUses(new_bulbs)
bulb_shards = bulb_shards % shards_required
if(new_bulbs != 0)
user << "<span class='notice'>\The [src] has fabricated a new bulb from the broken glass it has stored. It now has [uses] uses.</span>"
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
return new_bulbs
/obj/item/device/lightreplacer/proc/Charge(var/mob/user)
@@ -185,11 +194,7 @@
U << "<span class='notice'>You replace the [target.fitting] with \the [src].</span>"
if(target.status != LIGHT_EMPTY)
var/new_bulbs = AddShards(1)
if(new_bulbs != 0)
U << "<span class='notice'>\The [src] has fabricated a new bulb from the broken bulbs it has stored. It now has [uses] uses.</span>"
playsound(src.loc, 'sound/machines/ding.ogg', 50, 1)
AddShards(1, U)
target.status = LIGHT_EMPTY
target.update()
@@ -223,11 +228,8 @@
name = initial(name)
update_icon()
//Can you use it?
/obj/item/device/lightreplacer/proc/CanUse(mob/living/user)
src.add_fingerprint(user)
//Not sure what else to check for. Maybe if clumsy?
if(uses > 0)
return 1
else
+7 -39
View File
@@ -3,57 +3,25 @@
desc = "A device used to project your voice. Loudly."
icon_state = "megaphone"
item_state = "radio"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
flags = FPRINT
siemens_coefficient = 1
var/spamcheck = 0
var/emagged = 0
var/insults = 0
var/voicespan = "command_headset" // sic
var/list/insultmsg = list("FUCK EVERYONE!", "DEATH TO LIZARDS!", "ALL SECURITY TO SHOOT ME ON SIGHT!", "I HAVE A BOMB!", "CAPTAIN IS A COMDOM!", "FOR THE SYNDICATE!", "VIVA!", "HONK!")
/obj/item/device/megaphone/attack_self(mob/living/carbon/human/user)
if(user.client)
if(user.client.prefs.muted & MUTE_IC)
src << "<span class='warning'>You cannot speak in IC (muted).</span>"
return
if(!ishuman(user))
user << "<span class='warning'>You don't know how to use this!</span>"
return
var/list/voicespan = list(SPAN_COMMAND)
/obj/item/device/megaphone/get_held_item_speechspans(mob/living/carbon/user)
if(spamcheck > world.time)
user << "<span class='warning'>\The [src] needs to recharge!</span>"
return
var/message = copytext(sanitize(input(user, "Shout a message?", "Megaphone", null) as text),1,MAX_MESSAGE_LEN)
if(!message)
return
message = capitalize(message)
if(!user.can_speak(message))
user << "<span class='warning'>You find yourself unable to speak at all!</span>"
return
if ((src.loc == user && user.stat == 0))
if(emagged)
if(insults)
user.say(pick(insultmsg),"machine", list(voicespan))
insults--
else
user << "<span class='warning'>*BZZZZzzzzzt*</span>"
else
user.say(message,"machine", list(voicespan))
else
playsound(loc, 'sound/items/megaphone.ogg', 100, 0, 1)
spamcheck = world.time + 50
return
return voicespan
/obj/item/device/megaphone/emag_act(mob/user)
user << "<span class='warning'>You overload \the [src]'s voice synthesizer.</span>"
emagged = 1
insults = rand(1, 3) //to prevent dickflooding
voicespan = list(SPAN_REALLYBIG, "userdanger")
/obj/item/device/megaphone/sec
name = "security megaphone"
@@ -71,4 +39,4 @@
name = "clown's megaphone"
desc = "Something that should not exist."
icon_state = "megaphone-clown"
voicespan = "clown"
voicespan = list(SPAN_CLOWN)
@@ -1,35 +0,0 @@
/obj/item/modkit
name = "modification kit"
desc = "A one-use kit, which enables kinetic accelerators to retain their \
charge when away from a bioelectric source, renders them immune to \
interference with other accelerators, as well as allowing less \
dextrous races to use the tool."
icon = 'icons/obj/objects.dmi'
icon_state = "modkit"
origin_tech = "programming=2;materials=2;magnets=4"
var/uses = 1
/obj/item/modkit/afterattack(obj/item/weapon/gun/energy/kinetic_accelerator/C, mob/user)
..()
if(!uses)
qdel(src)
return
if(!istype(C))
user << "<span class='warning'>This kit can only modify kinetic \
accelerators!</span>"
return ..()
// RIP the 'improved improved improved improved kinetic accelerator
if(C.holds_charge && C.unique_frequency)
user << "<span class='warning'>This kinetic accelerator already has \
these upgrades.</span>"
return ..()
user <<"<span class='notice'>You modify the [C], adjusting the trigger \
guard and internal capacitor.</span>"
C.name = "improved [C.name]"
C.holds_charge = TRUE
C.unique_frequency = TRUE
C.trigger_guard = TRIGGER_GUARD_ALLOW_ALL
uses--
if(!uses)
qdel(src)
+10 -3
View File
@@ -13,7 +13,7 @@
desc = "Used for pulsing wires to test which to cut. Not recommended by doctors."
icon_state = "multitool"
force = 5
w_class = 2
w_class = WEIGHT_CLASS_SMALL
throwforce = 0
throw_range = 7
throw_speed = 3
@@ -88,5 +88,12 @@
/obj/item/device/multitool/cyborg
name = "multitool"
desc = "Optimised and stripped-down version of a regular multitool."
icon = 'icons/obj/items_cyborg.dmi'
toolspeed = 2
toolspeed = 0.5
/obj/item/device/multitool/abductor
name = "alien multitool"
desc = "An omni-technological interface."
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
origin_tech = "magnets=5;engineering=5;abductor=3"
+27 -17
View File
@@ -3,19 +3,20 @@
icon = 'icons/obj/aicards.dmi'
icon_state = "pai"
item_state = "electronic"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = "programming=2"
var/obj/item/device/radio/radio
var/looking_for_personality = 0
var/mob/living/silicon/pai/pai
resistance_flags = FIRE_PROOF | ACID_PROOF | INDESTRUCTIBLE
/obj/item/device/paicard/New()
..()
pai_card_list += src
add_overlay("pai-off")
/obj/item/device/paicard/Destroy()
//Will stop people throwing friend pAIs into the singularity so they can respawn
pai_card_list -= src
if(!isnull(pai))
pai.death(0)
return ..()
@@ -35,22 +36,22 @@
dat += "<a href='byond://?src=\ref[src];setlaws=1'>Configure Directives</a><br>"
dat += "<br>"
dat += "<h3>Device Settings</h3><br>"
if(radio)
if(pai.radio)
dat += "<b>Radio Uplink</b><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Transmit: <A href='byond://?src=\ref[src];wires=[WIRE_TX]'>[(pai.radio.wires.is_cut(WIRE_TX)) ? "Disabled" : "Enabled"]</A><br>"
dat += "Receive: <A href='byond://?src=\ref[src];wires=[WIRE_RX]'>[(pai.radio.wires.is_cut(WIRE_RX)) ? "Disabled" : "Enabled"]</A><br>"
else
dat += "<b>Radio Uplink</b><br>"
dat += "<font color=red><i>Radio firmware not loaded. Please install a pAI personality to load firmware.</i></font><br>"
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(H.real_name == pai.master || H.dna.unique_enzymes == pai.master_dna)
dat += "<A href='byond://?src=\ref[src];toggle_holo=1'>\[[pai.canholo? "Disable" : "Enable"] holomatrix projectors\]</a><br>"
dat += "<A href='byond://?src=\ref[src];wipe=1'>\[Wipe current pAI personality\]</a><br>"
else
if(looking_for_personality)
dat += "Searching for a personality..."
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
else
dat += "No personality is installed.<br>"
dat += "<A href='byond://?src=\ref[src];request=1'>\[Request personal AI personality\]</a><br>"
dat += "Each time this button is pressed, a request will be sent out to any available personalities. Check back often and give a lot of time for personalities to respond. This process could take anywhere from 15 seconds to several minutes, depending on the available personalities' timeliness."
dat += "No personality installed.<br>"
dat += "Searching for a personality... Press view available personalities to notify potential candidates."
dat += "<A href='byond://?src=\ref[src];request=1'>\[View available personalities\]</a><br>"
user << browse(dat, "window=paicard")
onclose(user, "paicard")
return
@@ -61,7 +62,6 @@
return
if(href_list["request"])
src.looking_for_personality = 1
SSpai.findPAI(src, usr)
if(pai)
@@ -75,6 +75,7 @@
pai.master = M.real_name
pai.master_dna = M.dna.unique_enzymes
pai << "<span class='notice'>You have been bound to a new master.</span>"
pai.emittersemicd = FALSE
if(href_list["wipe"])
var/confirm = input("Are you CERTAIN you wish to delete the current personality? This action cannot be undone.", "Personality Wipe") in list("Yes", "No")
if(confirm == "Yes")
@@ -84,11 +85,10 @@
pai << "<span class='userdanger'>Your mental faculties leave you.</span>"
pai << "<span class='rose'>oblivion... </span>"
pai.death(0)
removePersonality()
if(href_list["wires"])
var/wire = text2num(href_list["wires"])
if(radio)
radio.wires.cut(wire)
if(pai.radio)
pai.radio.wires.cut(wire)
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
if(newlaws && pai)
@@ -97,6 +97,16 @@
pai << "Prime Directive : <br>[pai.laws.zeroth]"
for(var/slaws in pai.laws.supplied)
pai << "Supplemental Directives: <br>[slaws]"
if(href_list["toggle_holo"])
if(pai.canholo)
pai << "<span class='userdanger'>Your owner has disabled your holomatrix projectors!</span>"
pai.canholo = FALSE
usr << "<span class='warning'>You disable your pAI's holomatrix!</span>"
else
pai << "<span class='boldnotice'>Your owner has enabled your holomatrix projectors!</span>"
pai.canholo = TRUE
usr << "<span class='notice'>You enable your pAI's holomatrix!</span>"
attack_self(usr)
// WIRE_SIGNAL = 1
@@ -27,9 +27,8 @@
return
var/obj/machinery/atmospherics/pipe/P = A
P.color = modes[mode]
P.add_atom_colour(modes[mode], FIXED_COLOUR_PRIORITY)
P.pipe_color = modes[mode]
P.stored.color = modes[mode]
user.visible_message("<span class='notice'>[user] paints \the [P] [mode].</span>","<span class='notice'>You paint \the [P] [mode].</span>")
P.update_node_icon() //updates the neighbors
+3 -3
View File
@@ -5,7 +5,7 @@
name = "power sink"
icon_state = "powersink0"
item_state = "electronic"
w_class = 4
w_class = WEIGHT_CLASS_BULKY
flags = CONDUCT
throwforce = 5
throw_speed = 1
@@ -52,7 +52,7 @@
mode = value
update_icon()
set_light(0)
SetLuminosity(0)
/obj/item/device/powersink/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/screwdriver))
@@ -113,7 +113,7 @@
var/datum/powernet/PN = attached.powernet
if(PN)
set_light(5)
SetLuminosity(5)
// found a powernet, so drain up to max power from it
@@ -7,6 +7,14 @@
origin_tech = "bluespace=1"
dog_fashion = null
/obj/item/device/radio/beacon/New()
..()
teleportbeacons += src
/obj/item/device/radio/beacon/Destroy()
teleportbeacons.Remove(src)
return ..()
/obj/item/device/radio/beacon/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans)
return
@@ -6,7 +6,7 @@
item_state = "electropack"
flags = CONDUCT
slot_flags = SLOT_BACK
w_class = 5
w_class = WEIGHT_CLASS_HUGE
materials = list(MAT_METAL=10000, MAT_GLASS=2500)
var/on = 1
var/code = 2
@@ -14,12 +14,12 @@
var/shock_cooldown = 0
/obj/item/device/electropack/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] hooks \himself to the electropack and spams the trigger! It looks like \he's trying to commit suicide..</span>")
user.visible_message("<span class='suicide'>[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/device/electropack/initialize()
if(SSradio)
SSradio.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/electropack/Initialize()
..()
SSradio.add_object(src, frequency, RADIO_CHAT)
/obj/item/device/electropack/Destroy()
if(SSradio)
@@ -39,15 +39,13 @@
var/obj/item/assembly/shock_kit/A = new /obj/item/assembly/shock_kit( user )
A.icon = 'icons/obj/assemblies.dmi'
if(!user.unEquip(W))
user << "<span class='warning'>\the [W] is stuck to your hand, you cannot attach it to \the [src]!</span>"
if(!user.transferItemToLoc(W, A))
user << "<span class='warning'>[W] is stuck to your hand, you cannot attach it to [src]!</span>"
return
W.loc = A
W.master = A
A.part1 = W
user.unEquip(src)
loc = A
user.transferItemToLoc(src, A, TRUE)
master = A
A.part2 = src
@@ -63,7 +61,7 @@
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if(((istype(usr, /mob/living/carbon/human) && ((!( ticker ) || (ticker && ticker.mode != "monkey")) && usr.contents.Find(src))) || (usr.contents.Find(master) || (in_range(src, usr) && istype(loc, /turf)))))
if((ishuman(usr) && usr.contents.Find(src)) || usr.contents.Find(master) || (in_range(src, usr) && isturf(loc)))
usr.set_machine(src)
if(href_list["freq"])
SSradio.remove_object(src, frequency)
@@ -124,7 +122,7 @@
/obj/item/device/electropack/attack_self(mob/user)
if(!istype(user, /mob/living/carbon/human))
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"<TT>Turned [on ? "On" : "Off"] -
@@ -1,10 +1,10 @@
/obj/item/device/encryptionkey/
/obj/item/device/encryptionkey
name = "standard encryption key"
desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
w_class = 1
w_class = WEIGHT_CLASS_TINY
origin_tech = "engineering=2;bluespace=1"
var/translate_binary = 0
var/translate_hive = 0
@@ -13,7 +13,9 @@
var/list/channels = list()
/obj/item/device/encryptionkey/syndicate
icon_state = "cypherkey"
name = "syndicate encryption key"
desc = "An encryption key for a radio headset. To access the syndicate channel, use :t."
icon_state = "syn_cypherkey"
channels = list("Syndicate" = 1)
origin_tech = "syndicate=1;engineering=3;bluespace=2"
syndie = 1//Signifies that it de-crypts Syndicate transmissions
@@ -21,7 +23,7 @@
/obj/item/device/encryptionkey/binary
name = "binary translator key"
desc = "An encryption key for a radio headset. To access the binary channel, use :b."
icon_state = "cypherkey"
icon_state = "bin_cypherkey"
translate_binary = 1
origin_tech = "syndicate=3;engineering=4;bluespace=3"
@@ -109,6 +111,12 @@
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1)
/obj/item/device/encryptionkey/headset_mining
name = "mining radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u. For science, use :n."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1, "Science" = 1)
/obj/item/device/encryptionkey/headset_service
name = "service radio encryption key"
desc = "An encryption key for a radio headset. To access the service channel, use :v."
@@ -24,8 +24,8 @@
/obj/item/device/radio/headset/talk_into(mob/living/M, message, channel, list/spans)
if (!listening)
return
..()
return ITALICS | REDUCE_RANGE
return ..()
/obj/item/device/radio/headset/receive_range(freq, level, AIuser)
if(ishuman(src.loc))
@@ -173,8 +173,9 @@
/obj/item/device/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners. \nTo access the supply channel, use :u."
desc = "Headset used by shaft miners. \nTo access the supply channel, use :u. For science, use :n."
icon_state = "mine_headset"
keyslot = new /obj/item/device/encryptionkey/headset_mining
/obj/item/device/radio/headset/headset_srv
name = "service radio headset"
@@ -245,15 +246,13 @@
return
if(!keyslot)
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
keyslot = W
else
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
keyslot2 = W
@@ -3,7 +3,7 @@
desc = "Talk through this."
icon_state = "intercom"
anchored = 1
w_class = 4
w_class = WEIGHT_CLASS_BULKY
canhear_range = 2
var/number = 0
var/anyai = 1
+10 -8
View File
@@ -34,7 +34,7 @@
languages_understood = HUMAN | ROBOT
throw_speed = 3
throw_range = 7
w_class = 2
w_class = WEIGHT_CLASS_SMALL
materials = list(MAT_METAL=75, MAT_GLASS=25)
var/const/TRANSMISSION_DELAY = 5 // only 2/second/radio
@@ -54,8 +54,6 @@
wires.cut(WIRE_TX) // OH GOD WHY
secure_radio_connections = new
..()
if(SSradio)
initialize()
/obj/item/device/radio/proc/recalculateChannels()
channels = list()
@@ -100,7 +98,8 @@
keyslot = null
return ..()
/obj/item/device/radio/initialize()
/obj/item/device/radio/Initialize()
..()
frequency = sanitize_frequency(frequency, freerange)
set_frequency(frequency)
@@ -110,7 +109,7 @@
/obj/item/device/radio/interact(mob/user)
if (..())
return
if(b_stat && !istype(user, /mob/living/silicon/ai))
if(b_stat && !isAI(user))
wires.interact(user)
else
ui_interact(user)
@@ -197,6 +196,10 @@
. = TRUE
/obj/item/device/radio/talk_into(atom/movable/M, message, channel, list/spans)
INVOKE_ASYNC(src, .proc/talk_into_impl, M, message, channel, spans)
return ITALICS | REDUCE_RANGE
/obj/item/device/radio/proc/talk_into_impl(atom/movable/M, message, channel, list/spans)
if(!on) return // the device has to be on
// Fix for permacell radios, but kinda eh about actually fixing them.
if(!M || !message) return
@@ -277,7 +280,7 @@
jobname = "AI"
// --- Cyborg ---
else if(isrobot(M))
else if(iscyborg(M))
var/mob/living/silicon/robot/B = M
jobname = "[B.designation] Cyborg"
@@ -578,9 +581,8 @@
return
if(!keyslot)
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
keyslot = W
recalculateChannels()
+27 -20
View File
@@ -14,7 +14,7 @@ MASS SPECTROMETER
icon_state = "t-ray0"
var/on = 0
slot_flags = SLOT_BELT
w_class = 2
w_class = WEIGHT_CLASS_SMALL
item_state = "electronic"
materials = list(MAT_METAL=150)
origin_tech = "magnets=1;engineering=1"
@@ -30,11 +30,7 @@ MASS SPECTROMETER
/obj/item/device/t_scanner/proc/flick_sonar(obj/pipe)
var/image/I = image('icons/effects/effects.dmi', pipe, "blip", pipe.layer+1)
I.alpha = 128
var/list/nearby = list()
for(var/mob/M in viewers(pipe))
if(M.client)
nearby |= M.client
flick_overlay(I,nearby,8)
flick_overlay_view(I, pipe, 8)
/obj/item/device/t_scanner/process()
if(!on)
@@ -74,7 +70,7 @@ MASS SPECTROMETER
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 3
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
materials = list(MAT_METAL=200)
@@ -114,7 +110,7 @@ MASS SPECTROMETER
// Used by the PDA medical scanner too
/proc/healthscan(mob/living/user, mob/living/M, mode = 1)
if(user.stat || user.eye_blind)
if(user.incapacitated() || user.eye_blind)
return
//Damage specifics
var/oxy_loss = M.getOxyLoss()
@@ -131,6 +127,12 @@ MASS SPECTROMETER
var/mob/living/carbon/human/H = M
if(H.heart_attack && H.stat != DEAD)
user << "<span class='danger'>Subject suffering from heart attack: Apply defibrillator immediately!</span>"
if(iscarbon(M))
var/mob/living/carbon/C = M
if(C.has_brain_worms())
user << "<span class='danger'>Foreign organism detected in subject's cranium. Recommended treatment: Dosage of sucrose solution and removal of object via surgery.</span>"
user << "<span class='info'>Analyzing results for [M]:\n\tOverall status: [mob_status]</span>"
// Damage descriptions
@@ -156,9 +158,9 @@ MASS SPECTROMETER
user << "\t<span class='alert'>Brain damage detected. Subject may have had a concussion.</span>"
// Organ damage report
if(istype(M, /mob/living/carbon/human) && mode == 1)
var/mob/living/carbon/human/H = M
var/list/damaged = H.get_damaged_bodyparts(1,1)
if(iscarbon(M) && mode == 1)
var/mob/living/carbon/C = M
var/list/damaged = C.get_damaged_bodyparts(1,1)
if(length(damaged)>0 || oxy_loss>0 || tox_loss>0 || fire_loss>0)
user << "<span class='info'>\tDamage: <span class='info'><font color='red'>Brute</font></span>-<font color='#FF8000'>Burn</font>-<font color='green'>Toxin</font>-<font color='blue'>Suffocation</font>\n\t\tSpecifics: <font color='red'>[brute_loss]</font>-<font color='#FF8000'>[fire_loss]</font>-<font color='green'>[tox_loss]</font>-<font color='blue'>[oxy_loss]</font></span>"
for(var/obj/item/bodypart/org in damaged)
@@ -194,7 +196,11 @@ MASS SPECTROMETER
var/blood_percent = round((C.blood_volume / BLOOD_VOLUME_NORMAL)*100)
var/blood_type = C.dna.blood_type
if(blood_id != "blood")//special blood substance
blood_type = blood_id
var/datum/reagent/R = chemical_reagents_list[blood_id]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.blood_volume <= BLOOD_VOLUME_SAFE && C.blood_volume > BLOOD_VOLUME_OKAY)
user << "<span class='danger'>LOW blood level [blood_percent] %, [C.blood_volume] cl,</span> <span class='info'>type: [blood_type]</span>"
else if(C.blood_volume <= BLOOD_VOLUME_OKAY)
@@ -202,13 +208,13 @@ MASS SPECTROMETER
else
user << "<span class='info'>Blood level [blood_percent] %, [C.blood_volume] cl, type: [blood_type]</span>"
var/implant_detect
var/cyberimp_detect
for(var/obj/item/organ/cyberimp/CI in C.internal_organs)
if(CI.status == ORGAN_ROBOTIC)
implant_detect += "[C.name] is modified with a [CI.name].<br>"
if(implant_detect)
cyberimp_detect += "[C.name] is modified with a [CI.name].<br>"
if(cyberimp_detect)
user << "<span class='notice'>Detected cybernetic modifications:</span>"
user << "<span class='notice'>[implant_detect]</span>"
user << "<span class='notice'>[cyberimp_detect]</span>"
/proc/chemscan(mob/living/user, mob/living/M)
if(ishuman(M))
@@ -247,7 +253,7 @@ MASS SPECTROMETER
name = "analyzer"
icon_state = "atmos"
item_state = "analyzer"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT | NOBLUDGEON
slot_flags = SLOT_BELT
throwforce = 0
@@ -321,9 +327,10 @@ MASS SPECTROMETER
name = "mass-spectrometer"
icon_state = "spectrometer"
item_state = "analyzer"
w_class = 2
flags = CONDUCT | OPENCONTAINER
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
slot_flags = SLOT_BELT
container_type = OPENCONTAINER
throwforce = 0
throw_speed = 3
throw_range = 7
@@ -382,7 +389,7 @@ MASS SPECTROMETER
icon_state = "adv_spectrometer"
item_state = "analyzer"
origin_tech = "biotech=2"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
flags = CONDUCT
throwforce = 0
throw_speed = 3
@@ -3,7 +3,7 @@
desc = "A miniature machine that tracks suit sensors across the station."
icon = 'icons/obj/device.dmi'
icon_state = "scanner"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
slot_flags = SLOT_BELT
origin_tech = "programming=3;materials=3;magnets=3"
+15 -10
View File
@@ -3,7 +3,7 @@
desc = "A device that can record to cassette tapes, and play them. It automatically translates the content in playback."
icon_state = "taperecorder_empty"
item_state = "analyzer"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
flags = HEAR
slot_flags = SLOT_BELT
languages_spoken = ALL //this is a translator, after all.
@@ -22,6 +22,7 @@
/obj/item/device/taperecorder/New()
mytape = new /obj/item/device/tape/random(src)
update_icon()
..()
/obj/item/device/taperecorder/examine(mob/user)
@@ -31,9 +32,8 @@
/obj/item/device/taperecorder/attackby(obj/item/I, mob/user, params)
if(!mytape && istype(I, /obj/item/device/tape))
if(!user.unEquip(I))
if(!user.transferItemToLoc(I,src))
return
I.loc = src
mytape = I
user << "<span class='notice'>You insert [I] into [src].</span>"
update_icon()
@@ -47,14 +47,14 @@
mytape = null
update_icon()
/obj/item/device/taperecorder/fire_act()
/obj/item/device/taperecorder/fire_act(exposed_temperature, exposed_volume)
mytape.ruin() //Fires destroy the tape
return()
..()
/obj/item/device/taperecorder/attack_hand(mob/user)
if(loc == user)
if(mytape)
if(user.l_hand != src && user.r_hand != src)
if(!user.is_holding(src))
..()
return
eject(user)
@@ -238,7 +238,7 @@
desc = "A magnetic tape that can hold up to ten minutes of content."
icon_state = "tape_white"
item_state = "analyzer"
w_class = 1
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL=20, MAT_GLASS=5)
force = 1
throwforce = 0
@@ -248,8 +248,9 @@
var/list/timestamp = list()
var/ruined = 0
/obj/item/device/tape/fire_act()
/obj/item/device/tape/fire_act(exposed_temperature, exposed_volume)
ruin()
..()
/obj/item/device/tape/attack_self(mob/user)
if(!ruined)
@@ -258,7 +259,10 @@
/obj/item/device/tape/proc/ruin()
add_overlay("ribbonoverlay")
//Lets not add infinite amounts of overlays when our fireact is called
//repeatedly
if(!ruined)
add_overlay("ribbonoverlay")
ruined = 1
@@ -270,7 +274,7 @@
/obj/item/device/tape/attackby(obj/item/I, mob/user, params)
if(ruined && istype(I, /obj/item/weapon/screwdriver))
user << "<span class='notice'>You start winding the tape back in...</span>"
if(do_after(user, 120/I.toolspeed, target = src))
if(do_after(user, 120*I.toolspeed, target = src))
user << "<span class='notice'>You wound the tape back in.</span>"
fix()
@@ -278,3 +282,4 @@
//Random colour tapes
/obj/item/device/tape/random/New()
icon_state = "tape_[pick("white", "blue", "red", "yellow", "purple")]"
..()
@@ -20,7 +20,7 @@ effective or pretty fucking useless.
desc = "A strange device with twin antennas."
icon_state = "batterer"
throwforce = 5
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
flags = CONDUCT
@@ -218,7 +218,7 @@ effective or pretty fucking useless.
var/turf/T = get_turf(src)
if(on)
var/lumcount = T.get_lumcount()
if(lumcount > 0.3)
if(lumcount > 3)
charge = max(0,charge - 25)//Quick decrease in light
else
charge = min(max_charge,charge + 50) //Charge in the dark
@@ -22,18 +22,16 @@
return
if(!tank_one)
if(!user.unEquip(item))
if(!user.transferItemToLoc(item, src))
return
tank_one = item
item.loc = src
user << "<span class='notice'>You attach the tank to the transfer valve.</span>"
if(item.w_class > w_class)
w_class = item.w_class
else if(!tank_two)
if(!user.unEquip(item))
if(!user.transferItemToLoc(item, src))
return
tank_two = item
item.loc = src
user << "<span class='notice'>You attach the tank to the transfer valve.</span>"
if(item.w_class > w_class)
w_class = item.w_class
@@ -48,9 +46,9 @@
if(attached_device)
user << "<span class='warning'>There is already a device attached to the valve, remove it first!</span>"
return
user.remove_from_mob(item)
if(!user.transferItemToLoc(item, src))
return
attached_device = A
A.loc = src
user << "<span class='notice'>You attach the [item] to the valve controls and secure it.</span>"
A.holder = src
A.toggle_secure() //this calls update_icon(), which calls update_icon() on the holder (i.e. the bomb).
@@ -85,16 +83,16 @@
tank_one.loc = get_turf(src)
tank_one = null
update_icon()
if((!tank_two || tank_two.w_class < 4) && (w_class > 3))
w_class = 3
if((!tank_two || tank_two.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
w_class = WEIGHT_CLASS_NORMAL
else if(tank_two && href_list["tanktwo"])
split_gases()
valve_open = 0
tank_two.loc = get_turf(src)
tank_two = null
update_icon()
if((!tank_one || tank_one.w_class < 4) && (w_class > 3))
w_class = 3
if((!tank_one || tank_one.w_class < WEIGHT_CLASS_BULKY) && (w_class > WEIGHT_CLASS_NORMAL))
w_class = WEIGHT_CLASS_NORMAL
else if(href_list["open"])
toggle_valve()
else if(attached_device)
+3 -2
View File
@@ -5,11 +5,12 @@
icon_state = "docs_generic"
item_state = "paper"
throwforce = 0
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_range = 1
throw_speed = 1
layer = MOB_LAYER
pressure_resistance = 1
pressure_resistance = 2
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
/obj/item/documents/nanotrasen
desc = "\"Top Secret\" Nanotrasen documents, filled with complex diagrams and lists of names, dates and coordinates."
+5 -7
View File
@@ -5,7 +5,7 @@
item_state = "lgloves"
force = 0
throwforce = 0
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 1
throw_range = 7
var/state
@@ -16,8 +16,7 @@
return
icon_state = "latexballon_blow"
item_state = "latexballon"
user.update_inv_r_hand()
user.update_inv_l_hand()
user.update_inv_hands()
user << "<span class='notice'>You blow up [src] with [tank].</span>"
air_contents = tank.remove_air_volume(3)
@@ -27,10 +26,9 @@
playsound(src, 'sound/weapons/Gunshot.ogg', 100, 1)
icon_state = "latexballon_bursted"
item_state = "lgloves"
if(istype(src.loc, /mob/living))
if(isliving(loc))
var/mob/living/user = src.loc
user.update_inv_r_hand()
user.update_inv_l_hand()
user.update_inv_hands()
loc.assume_air(air_contents)
/obj/item/latexballon/ex_act(severity, target)
@@ -54,5 +52,5 @@
var/obj/item/weapon/tank/T = W
blow(T, user)
return
if (is_sharp(W) || W.is_hot() || is_pointed(W))
if (W.is_sharp() || W.is_hot() || is_pointed(W))
burst()
+5 -4
View File
@@ -7,6 +7,7 @@
icon = 'icons/obj/nuke_tools.dmi'
icon_state = "plutonium_core"
item_state = "plutoniumcore"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/pulse = 0
var/cooldown = 0
@@ -38,11 +39,11 @@
/obj/item/nuke_core_container/proc/load(obj/item/nuke_core/ncore, mob/user)
if(core || !istype(ncore))
return 0
ncore.loc = src
ncore.forceMove(src)
core = ncore
icon_state = "core_container_loaded"
user << "<span class='warning'>Container is sealing...</span>"
addtimer(src, "seal", 50)
addtimer(CALLBACK(src, .proc/seal), 50)
return 1
/obj/item/nuke_core_container/proc/seal()
@@ -55,7 +56,7 @@
/obj/item/nuke_core_container/attackby(obj/item/nuke_core/core, mob/user)
if(istype(core))
if(!user.unEquip(core))
if(!user.temporarilyRemoveItemFromInventory(core))
user << "<span class='warning'>The [core] is stuck to your hand!</span>"
return
else
@@ -69,7 +70,7 @@
desc = "A screwdriver with an ultra thin tip."
icon = 'icons/obj/nuke_tools.dmi'
icon_state = "screwdriver_nuke"
toolspeed = 2
toolspeed = 0.5
/obj/item/weapon/paper/nuke_instructions
info = "How to break into a Nanotrasen self-destruct terminal and remove its plutonium core:<br>\
+189
View File
@@ -0,0 +1,189 @@
/obj/item/weapon/banner
name = "banner"
icon = 'icons/obj/items.dmi'
icon_state = "banner"
item_state = "banner"
desc = "A banner with Nanotrasen's logo on it."
var/moralecooldown = 0
var/moralewait = 600
/obj/item/weapon/banner/attack_self(mob/living/carbon/human/user)
if(moralecooldown + moralewait > world.time)
return
user << "<span class='notice'>You increase the morale of your fellows!</span>"
moralecooldown = world.time
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
H << "<span class='notice'>Your morale is increased by [user]'s banner!</span>"
H.adjustBruteLoss(-15)
H.adjustFireLoss(-15)
H.AdjustStunned(-2)
H.AdjustWeakened(-2)
H.AdjustParalysis(-2)
/obj/item/weapon/banner/red
name = "red banner"
icon_state = "banner-red"
item_state = "banner-red"
desc = "A banner with the logo of the red deity."
/obj/item/weapon/banner/blue
name = "blue banner"
icon_state = "banner-blue"
item_state = "banner-blue"
desc = "A banner with the logo of the blue deity"
/obj/item/weapon/storage/backpack/bannerpack
name = "nanotrasen banner backpack"
desc = "It's a backpack with lots of extra room. A banner with Nanotrasen's logo is attached, that can't be removed."
max_combined_w_class = 27 //6 more then normal, for the tradeoff of declaring yourself an antag at all times.
icon_state = "bannerpack"
/obj/item/weapon/storage/backpack/bannerpack/red
name = "red banner backpack"
desc = "It's a backpack with lots of extra room. A red banner is attached, that can't be removed."
icon_state = "bannerpack-red"
/obj/item/weapon/storage/backpack/bannerpack/blue
name = "blue banner backpack"
desc = "It's a backpack with lots of extra room. A blue banner is attached, that can't be removed."
icon_state = "bannerpack-blue"
//this is all part of one item set
/obj/item/clothing/suit/armor/plate/crusader
name = "Crusader's Armour"
desc = "Armour that's comprised of metal and cloth."
icon_state = "crusader"
w_class = WEIGHT_CLASS_BULKY
slowdown = 2.0 //gotta pretend we're balanced.
body_parts_covered = CHEST|GROIN|LEGS|FEET|ARMS|HANDS
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0, fire = 60, acid = 60)
/obj/item/clothing/suit/armor/plate/crusader/red
icon_state = "crusader-red"
/obj/item/clothing/suit/armor/plate/crusader/blue
icon_state = "crusader-blue"
/obj/item/clothing/head/helmet/plate/crusader
name = "Crusader's Hood"
desc = "A brownish hood."
icon_state = "crusader"
w_class = WEIGHT_CLASS_NORMAL
flags_inv = HIDEHAIR|HIDEEARS|HIDEFACE
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0, fire = 60, acid = 60)
/obj/item/clothing/head/helmet/plate/crusader/blue
icon_state = "crusader-blue"
/obj/item/clothing/head/helmet/plate/crusader/red
icon_state = "crusader-red"
//Prophet helmet
/obj/item/clothing/head/helmet/plate/crusader/prophet
name = "Prophet's Hat"
desc = "A religious-looking hat."
alternate_worn_icon = 'icons/mob/large-worn-icons/64x64/head.dmi'
flags = 0
armor = list(melee = 60, bullet = 60, laser = 60, energy = 50, bomb = 70, bio = 50, rad = 50, fire = 60, acid = 60) //religion protects you from disease and radiation, honk.
worn_x_dimension = 64
worn_y_dimension = 64
/obj/item/clothing/head/helmet/plate/crusader/prophet/red
icon_state = "prophet-red"
/obj/item/clothing/head/helmet/plate/crusader/prophet/blue
icon_state = "prophet-blue"
//Structure conversion staff
/obj/item/weapon/godstaff
name = "godstaff"
desc = "It's a stick..?"
icon_state = "godstaff-red"
var/conversion_color = "#ffffff"
var/staffcooldown = 0
var/staffwait = 30
/obj/item/weapon/godstaff/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(staffcooldown + staffwait > world.time)
return
user.visible_message("[user] chants deeply and waves their staff!")
if(do_after(user, 20,1,src))
target.add_atom_colour(conversion_color, WASHABLE_COLOUR_PRIORITY) //wololo
staffcooldown = world.time
/obj/item/weapon/godstaff/red
icon_state = "godstaff-red"
conversion_color = "#ff0000"
/obj/item/weapon/godstaff/blue
icon_state = "godstaff-blue"
conversion_color = "#0000ff"
/obj/item/clothing/gloves/plate
name = "Plate Gauntlets"
icon_state = "crusader"
desc = "They're like gloves, but made of metal."
siemens_coefficient = 0
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
/obj/item/clothing/gloves/plate/red
icon_state = "crusader-red"
/obj/item/clothing/gloves/plate/blue
icon_state = "crusader-blue"
/obj/item/clothing/shoes/plate
name = "Plate Boots"
desc = "Metal boots, they look heavy."
icon_state = "crusader"
w_class = WEIGHT_CLASS_NORMAL
armor = list(melee = 50, bullet = 50, laser = 50, energy = 40, bomb = 60, bio = 0, rad = 0, fire = 60, acid = 60) //does this even do anything on boots?
flags = NOSLIP
cold_protection = FEET
min_cold_protection_temperature = SHOES_MIN_TEMP_PROTECT
heat_protection = FEET
max_heat_protection_temperature = SHOES_MAX_TEMP_PROTECT
/obj/item/clothing/shoes/plate/red
icon_state = "crusader-red"
/obj/item/clothing/shoes/plate/blue
icon_state = "crusader-blue"
/obj/item/weapon/storage/box/itemset/crusader
name = "Crusader's Armour Set" //i can't into ck2 references
desc = "This armour is said to be based on the armor of kings on another world thousands of years ago, who tended to assassinate, conspire, and plot against everyone who tried to do the same to them. Some things never change."
/obj/item/weapon/storage/box/itemset/crusader/blue/New()
..()
contents = list()
sleep(1)
new /obj/item/clothing/suit/armor/plate/crusader/blue(src)
new /obj/item/clothing/head/helmet/plate/crusader/blue(src)
new /obj/item/clothing/gloves/plate/blue(src)
new /obj/item/clothing/shoes/plate/blue(src)
/obj/item/weapon/storage/box/itemset/crusader/red/New()
..()
contents = list()
sleep(1)
new /obj/item/clothing/suit/armor/plate/crusader/red(src)
new /obj/item/clothing/head/helmet/plate/crusader/red(src)
new /obj/item/clothing/gloves/plate/red(src)
new /obj/item/clothing/shoes/plate/red(src)
/obj/item/weapon/claymore/weak
desc = "This one is rusted."
force = 30
armour_penetration = 15
+239 -64
View File
@@ -8,16 +8,29 @@
/obj/item/borg/stun
name = "electrically-charged arm"
icon_state = "elecarm"
var/charge_cost = 30
/obj/item/borg/stun/attack(mob/living/M, mob/living/silicon/robot/user)
if(!user.cell.use(30)) return
/obj/item/borg/stun/attack(mob/living/M, mob/living/user)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.check_shields(0, "[M]'s [name]", src, MELEE_ATTACK))
playsound(M, 'sound/weapons/Genhit.ogg', 50, 1)
return FALSE
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
if(!R.cell.use(charge_cost))
return
user.do_attack_animation(M)
M.Weaken(5)
M.apply_effect(STUTTER, 5)
M.Stun(5)
M.visible_message("<span class='danger'>[user] has prodded [M] with [src]!</span>", \
"<span class='userdanger'>[user] has prodded you with [src]!</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
add_logs(user, M, "stunned", src, "(INTENT: [uppertext(user.a_intent)])")
/obj/item/borg/cyborghug
@@ -27,10 +40,11 @@
var/mode = 0 //0 = Hugs 1 = "Hug" 2 = Shock 3 = CRUSH
var/ccooldown = 0
var/scooldown = 0
var/shockallowed = 0//Can it be a stunarm when emagged. Only PK borgs get this by default.
var/shockallowed = FALSE//Can it be a stunarm when emagged. Only PK borgs get this by default.
var/boop = FALSE
/obj/item/borg/cyborghug/attack_self(mob/living/user)
if(isrobot(user))
if(iscyborg(user))
var/mob/living/silicon/robot/P = user
if(P.emagged&&shockallowed == 1)
if(mode < 3)
@@ -52,18 +66,25 @@
user << "ERROR: ARM ACTUATORS OVERLOADED."
/obj/item/borg/cyborghug/attack(mob/living/M, mob/living/silicon/robot/user)
if(M == user)
return
switch(mode)
if(0)
if(M.health >= 0)
if(ishuman(M))
if(user.zone_selected == "head")
user.visible_message("<span class='notice'>[user] playfully boops [M] on the head!</span>", \
"<span class='notice'>You playfully boop [M] on the head!</span>")
user.do_attack_animation(M, ATTACK_EFFECT_BOOP)
playsound(loc, 'sound/weapons/tap.ogg', 50, 1, -1)
else if(ishuman(M))
if(M.lying)
user.visible_message("<span class='notice'>[user] shakes [M] trying to get \him up!</span>", \
"<span class='notice'>You shake [M] trying to get \him up!</span>")
user.visible_message("<span class='notice'>[user] shakes [M] trying to get [M.p_them()] up!</span>", \
"<span class='notice'>You shake [M] trying to get [M.p_them()] up!</span>")
else
user.visible_message("<span class='notice'>[user] hugs [M] to make \him feel better!</span>", \
"<span class='notice'>You hug [M] to make \him feel better!</span>")
user.visible_message("<span class='notice'>[user] hugs [M] to make [M.p_them()] feel better!</span>", \
"<span class='notice'>You hug [M] to make [M.p_them()] feel better!</span>")
if(M.resting)
M.resting = 0
M.resting = FALSE
M.update_canmove()
else
user.visible_message("<span class='notice'>[user] pets [M]!</span>", \
@@ -73,13 +94,17 @@
if(M.health >= 0)
if(ishuman(M))
if(M.lying)
user.visible_message("<span class='notice'>[user] shakes [M] trying to get \him up!</span>", \
"<span class='notice'>You shake [M] trying to get \him up!</span>")
user.visible_message("<span class='notice'>[user] shakes [M] trying to get [M.p_them()] up!</span>", \
"<span class='notice'>You shake [M] trying to get [M.p_them()] up!</span>")
else if(user.zone_selected == "head")
user.visible_message("<span class='warning'>[user] bops [M] on the head!</span>", \
"<span class='warning'>You bop [M] on the head!</span>")
user.do_attack_animation(M, ATTACK_EFFECT_PUNCH)
else
user.visible_message("<span class='warning'>[user] hugs [M] in a firm bear-hug! [M] looks uncomfortable...</span>", \
"<span class='warning'>You hug [M] firmly to make \him feel better! [M] looks uncomfortable...</span>")
"<span class='warning'>You hug [M] firmly to make [M.p_them()] feel better! [M] looks uncomfortable...</span>")
if(M.resting)
M.resting = 0
M.resting = FALSE
M.update_canmove()
else
user.visible_message("<span class='warning'>[user] bops [M] on the head!</span>", \
@@ -94,7 +119,7 @@
"<span class='danger'>You electrocute [M] with your touch!</span>")
M.update_canmove()
else
if(!isrobot(M))
if(!iscyborg(M))
M.adjustFireLoss(10)
user.visible_message("<span class='userdanger'>[user] shocks [M]!</span>", \
"<span class='danger'>You shock [M]!</span>")
@@ -103,9 +128,9 @@
"<span class='danger'>You shock [M] to no effect.</span>")
playsound(loc, 'sound/effects/sparks2.ogg', 50, 1, -1)
user.cell.charge -= 500
scooldown = 1
scooldown = TRUE
spawn(20)
scooldown = 0
scooldown = FALSE
if(3)
if(!ccooldown)
if(M.health >= 0)
@@ -116,14 +141,17 @@
user.visible_message("<span class='userdanger'>[user] crushes [M]!</span>", \
"<span class='danger'>You crush [M]!</span>")
playsound(loc, 'sound/weapons/smash.ogg', 50, 1, -1)
M.adjustBruteLoss(10)
M.adjustBruteLoss(15)
user.cell.charge -= 300
ccooldown = 1
ccooldown = TRUE
spawn(10)
ccooldown = 0
ccooldown = FALSE
/obj/item/borg/cyborghug/peacekeeper
shockallowed = 1
shockallowed = TRUE
/obj/item/borg/cyborghug/medical
boop = TRUE
/obj/item/borg/charger
name = "power connector"
@@ -148,7 +176,7 @@
update_icon()
/obj/item/borg/charger/afterattack(obj/item/target, mob/living/silicon/robot/user, proximity_flag)
if(!proximity_flag || !isrobot(user))
if(!proximity_flag || !iscyborg(user))
return
if(mode == "draw")
if(is_type_in_list(target, charge_machines))
@@ -254,7 +282,7 @@
desc = "Releases a harmless blast that confuses most organics. For when the harm is JUST TOO MUCH"
icon_state = "megaphone"
var/cooldown = 0
var/emagged = 0
var/emagged = FALSE
/obj/item/device/harmalarm/emag_act(mob/user)
emagged = !emagged
@@ -269,70 +297,213 @@
user << "<font color='red'>The device is still recharging!</font>"
return
if(isrobot(user))
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
if(R.cell.charge < 1200)
user << "<font color='red'>You don't have enough charge to do this!</font>"
return
R.cell.charge -= 1000
if(R.emagged)
safety = 0
safety = FALSE
if(safety == 1)
if(safety == TRUE)
user.visible_message("<font color='red' size='2'>[user] blares out a near-deafening siren from its speakers!</font>", \
"<span class='userdanger'>The siren pierces your hearing and confuses you!</span>", \
"<span class='danger'>The siren pierces your hearing!</span>")
for(var/mob/living/M in get_hearers_in_view(9, user))
if(iscarbon(M))
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
if(istype(H.ears, /obj/item/clothing/ears/earmuffs))
continue
for(var/mob/living/carbon/M in get_hearers_in_view(9, user))
if(M.get_ear_protection() == FALSE)
M.confused += 6
M << "<font color='red' size='7'>HUMAN HARM</font>"
audible_message("<font color='red' size='7'>HUMAN HARM</font>")
playsound(get_turf(src), 'sound/AI/harmalarm.ogg', 70, 3)
cooldown = world.time + 200
log_game("[user.ckey]([user]) used a Cyborg Harm Alarm in ([user.x],[user.y],[user.z])")
if(isrobot(user))
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
R.connected_ai << "<br><span class='notice'>NOTICE - Peacekeeping 'HARM ALARM' used by: [user]</span><br>"
return
if(safety == 0)
for(var/mob/living/M in get_hearers_in_view(9, user))
if(iscarbon(M))
var/earsafety = 0
if(istype(M, /mob/living/carbon/alien))
continue
if(ishuman(M))
var/mob/living/carbon/human/S = M
if(istype(S.ears, /obj/item/clothing/ears/earmuffs))
continue
if(S.check_ear_prot())
earsafety = 1
if(earsafety)
M.confused += 5
M.stuttering += 10
M.adjustEarDamage(0, 5)
M.Jitter(10)
user.visible_message("<font color='red' size='3'>[user] blares out a sonic screech from its speakers!</font>", \
"<span class='userdanger'>You hear a sharp screech, before your thoughts are interrupted and you find yourself extremely disorientated.</span>", \
"<span class='danger'>You hear a sonic screech and suddenly can't seem to walk straight!")
else
M.Weaken(2)
M.confused += 10
M.stuttering += 15
M.adjustEarDamage(0, 20)
M.Jitter(25)
user.visible_message("<font color='red' size='3'>[user] blares out a sonic screech from its speakers!</font>", \
"<span class='userdanger'>You hear a sharp screech before your thoughts are interrupted and you collapse, your ears ringing!</span>", \
"<span class='danger'>You hear a sonic screech and collapse, your ears riniging!")
M << "<font color='red' size='7'>BZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZT</font>"
if(safety == FALSE)
user.audible_message("<font color='red' size='7'>BZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZT</font>")
for(var/mob/living/carbon/C in get_hearers_in_view(9, user))
var/bang_effect = C.soundbang_act(2, 0, 0, 5)
switch(bang_effect)
if(1)
C.confused += 5
C.stuttering += 10
C.Jitter(10)
if(2)
C.Weaken(2)
C.confused += 10
C.stuttering += 15
C.Jitter(25)
playsound(get_turf(src), 'sound/machines/warning-buzzer.ogg', 130, 3)
cooldown = world.time + 600
log_game("[user.ckey]([user]) used an emagged Cyborg Harm Alarm in ([user.x],[user.y],[user.z])")
/obj/item/borg/lollipop
name = "lollipop fabricator"
desc = "Reward good humans with this. Toggle in-module to switch between dispensing and high velocity ejection modes."
icon_state = "lollipop"
var/candy = 30
var/candymax = 30
var/charge_delay = 10
var/charging = 0
var/mode = 1
var/firedelay = 0
var/hitspeed = 2
var/hitdamage = 0
var/emaggedhitdamage = 3
/obj/item/borg/lollipop/equipped()
check_amount()
/obj/item/borg/lollipop/dropped()
check_amount()
/obj/item/borg/lollipop/proc/check_amount() //Doesn't even use processing ticks.
if(charging)
return
if(candy < candymax)
addtimer(CALLBACK(src, .proc/charge_lollipops), charge_delay)
charging = TRUE
/obj/item/borg/lollipop/proc/charge_lollipops()
candy++
charging = FALSE
check_amount()
/obj/item/borg/lollipop/proc/dispense(atom/A, mob/user)
if(candy <= 0)
user << "<span class='warning'>No lollipops left in storage!</span>"
return FALSE
var/turf/T = get_turf(A)
if(!T || !istype(T) || !isopenturf(T))
return FALSE
if(isobj(A))
var/obj/O = A
if(O.density)
return FALSE
new /obj/item/weapon/reagent_containers/food/snacks/lollipop(T)
candy--
check_amount()
user << "<span class='notice'>Dispensing lollipop...</span>"
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
return TRUE
/obj/item/borg/lollipop/proc/shootL(atom/target, mob/living/user, params)
if(candy <= 0)
user << "<span class='warning'>Not enough lollipops left!</span>"
return FALSE
candy--
var/obj/item/ammo_casing/caseless/lollipop/A = new /obj/item/ammo_casing/caseless/lollipop(src)
A.BB.damage = hitdamage
if(hitdamage)
A.BB.nodamage = FALSE
A.BB.speed = 0.5
playsound(src.loc, 'sound/machines/click.ogg', 50, 1)
A.fire_casing(target, user, params, 0, 0, null, 0)
user.visible_message("<span class='warning'>[user] blasts a flying lollipop at [target]!</span>")
check_amount()
/obj/item/borg/lollipop/proc/shootG(atom/target, mob/living/user, params) //Most certainly a good idea.
if(candy <= 0)
user << "<span class='warning'>Not enough gumballs left!</span>"
return FALSE
candy--
var/obj/item/ammo_casing/caseless/gumball/A = new /obj/item/ammo_casing/caseless/gumball(src)
A.BB.damage = hitdamage
if(hitdamage)
A.BB.nodamage = FALSE
A.BB.speed = 0.5
A.BB.color = rgb(rand(0, 255), rand(0, 255), rand(0, 255))
playsound(src.loc, 'sound/weapons/bulletflyby3.ogg', 50, 1)
A.fire_casing(target, user, params, 0, 0, null, 0)
user.visible_message("<span class='warning'>[user] shoots a high-velocity gumball at [target]!</span>")
check_amount()
/obj/item/borg/lollipop/afterattack(atom/target, mob/living/user, proximity, click_params)
check_amount()
if(iscyborg(user))
var/mob/living/silicon/robot/R = user
if(!R.cell.use(12))
user << "<span class='warning'>Not enough power.</span>"
return FALSE
if(R.emagged)
hitdamage = emaggedhitdamage
switch(mode)
if(1)
if(!proximity)
return FALSE
dispense(target, user)
if(2)
shootL(target, user, click_params)
if(3)
shootG(target, user, click_params)
hitdamage = initial(hitdamage)
/obj/item/borg/lollipop/attack_self(mob/living/user)
switch(mode)
if(1)
mode++
user << "<span class='notice'>Module is now throwing lollipops.</span>"
if(2)
mode++
user << "<span class='notice'>Module is now blasting gumballs.</span>"
if(3)
mode = 1
user << "<span class='notice'>Module is now dispensing lollipops.</span>"
..()
/obj/item/ammo_casing/caseless/gumball
name = "Gumball"
desc = "Why are you seeing this?!"
projectile_type = /obj/item/projectile/bullet/reusable/gumball
click_cooldown_override = 2
/obj/item/projectile/bullet/reusable/gumball
name = "gumball"
desc = "Oh noes! A fast-moving gumball!"
icon_state = "gumball"
ammo_type = /obj/item/weapon/reagent_containers/food/snacks/gumball/cyborg
nodamage = TRUE
/obj/item/projectile/bullet/reusable/gumball/handle_drop()
if(!dropped)
var/turf/T = get_turf(src)
var/obj/item/weapon/reagent_containers/food/snacks/gumball/S = new ammo_type(T)
S.color = color
dropped = TRUE
/obj/item/ammo_casing/caseless/lollipop //NEEDS RANDOMIZED COLOR LOGIC.
name = "Lollipop"
desc = "Why are you seeing this?!"
projectile_type = /obj/item/projectile/bullet/reusable/lollipop
click_cooldown_override = 2
/obj/item/projectile/bullet/reusable/lollipop
name = "lollipop"
desc = "Oh noes! A fast-moving lollipop!"
icon_state = "lollipop_1"
ammo_type = /obj/item/weapon/reagent_containers/food/snacks/lollipop/cyborg
var/color2 = rgb(0, 0, 0)
nodamage = TRUE
/obj/item/projectile/bullet/reusable/lollipop/New()
var/obj/item/weapon/reagent_containers/food/snacks/lollipop/S = new ammo_type(src)
color2 = S.headcolor
var/image/head = image(icon = 'icons/obj/projectiles.dmi', icon_state = "lollipop_2")
head.color = color2
add_overlay(head)
/obj/item/projectile/bullet/reusable/lollipop/handle_drop()
if(!dropped)
var/turf/T = get_turf(src)
var/obj/item/weapon/reagent_containers/food/snacks/lollipop/S = new ammo_type(T)
S.change_head_color(color2)
dropped = TRUE
/**********************************************************************
HUD/SIGHT things
***********************************************************************/
@@ -346,6 +517,10 @@
icon_state = "securearea"
sight_mode = BORGXRAY
/obj/item/borg/sight/xray/truesight_lens
name = "truesight lens"
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "truesight_lens"
/obj/item/borg/sight/thermal
name = "\proper thermal vision"
+98 -174
View File
@@ -1,68 +1,19 @@
/obj/item/robot_parts
name = "robot parts"
icon = 'icons/obj/robot_parts.dmi'
force = 4
throwforce = 4
item_state = "buildpipe"
icon_state = "blank"
flags = CONDUCT
slot_flags = SLOT_BELT
var/body_zone
/obj/item/robot_parts/l_arm
name = "cyborg left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("slapped", "punched")
icon_state = "l_arm"
body_zone = "l_arm"
/obj/item/robot_parts/r_arm
name = "cyborg right arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("slapped", "punched")
icon_state = "r_arm"
body_zone = "r_arm"
//The robot bodyparts have been moved to code/module/surgery/bodyparts/robot_bodyparts.dm
/obj/item/robot_parts/l_leg
name = "cyborg left leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("kicked", "stomped")
icon_state = "l_leg"
body_zone = "l_leg"
/obj/item/robot_parts/r_leg
name = "cyborg right leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
attack_verb = list("kicked", "stomped")
icon_state = "r_leg"
body_zone = "r_leg"
/obj/item/robot_parts/chest
name = "cyborg torso"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
icon_state = "chest"
body_zone = "chest"
var/wired = 0
var/obj/item/weapon/stock_parts/cell/cell = null
/obj/item/robot_parts/head
name = "cyborg head"
desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
icon_state = "head"
body_zone = "head"
var/obj/item/device/assembly/flash/handheld/flash1 = null
var/obj/item/device/assembly/flash/handheld/flash2 = null
/obj/item/robot_parts/robot_suit
/obj/item/robot_suit
name = "cyborg endoskeleton"
desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
icon = 'icons/obj/robot_parts.dmi'
icon_state = "robo_suit"
var/obj/item/robot_parts/l_arm/l_arm = null
var/obj/item/robot_parts/r_arm/r_arm = null
var/obj/item/robot_parts/l_leg/l_leg = null
var/obj/item/robot_parts/r_leg/r_leg = null
var/obj/item/robot_parts/chest/chest = null
var/obj/item/robot_parts/head/head = null
var/obj/item/bodypart/l_arm/robot/l_arm = null
var/obj/item/bodypart/r_arm/robot/r_arm = null
var/obj/item/bodypart/l_leg/robot/l_leg = null
var/obj/item/bodypart/r_leg/robot/r_leg = null
var/obj/item/bodypart/chest/robot/chest = null
var/obj/item/bodypart/head/robot/head = null
var/created_name = ""
var/mob/living/silicon/ai/forced_ai
@@ -71,26 +22,39 @@
var/aisync = 1
var/panel_locked = 1
/obj/item/robot_parts/robot_suit/New()
/obj/item/robot_suit/New()
..()
src.updateicon()
updateicon()
/obj/item/robot_parts/robot_suit/proc/updateicon()
src.cut_overlays()
if(src.l_arm)
src.add_overlay("l_arm+o")
if(src.r_arm)
src.add_overlay("r_arm+o")
if(src.chest)
src.add_overlay("chest+o")
if(src.l_leg)
src.add_overlay("l_leg+o")
if(src.r_leg)
src.add_overlay("r_leg+o")
if(src.head)
src.add_overlay("head+o")
/obj/item/robot_suit/prebuilt/New()
l_arm = new(src)
r_arm = new(src)
l_leg = new(src)
r_leg = new(src)
head = new(src)
head.flash1 = new(head)
head.flash2 = new(head)
chest = new(src)
chest.wired = TRUE
chest.cell = new /obj/item/weapon/stock_parts/cell/high/plus(chest)
..()
/obj/item/robot_parts/robot_suit/proc/check_completion()
/obj/item/robot_suit/proc/updateicon()
cut_overlays()
if(l_arm)
add_overlay("l_arm+o")
if(r_arm)
add_overlay("r_arm+o")
if(chest)
add_overlay("chest+o")
if(l_leg)
add_overlay("l_leg+o")
if(r_leg)
add_overlay("r_leg+o")
if(head)
add_overlay("head+o")
/obj/item/robot_suit/proc/check_completion()
if(src.l_arm && src.r_arm)
if(src.l_leg && src.r_leg)
if(src.chest && src.head)
@@ -98,7 +62,7 @@
return 1
return 0
/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user, params)
/obj/item/robot_suit/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = W
@@ -107,71 +71,83 @@
var/obj/item/weapon/ed209_assembly/B = new /obj/item/weapon/ed209_assembly
B.loc = get_turf(src)
user << "<span class='notice'>You arm the robot frame.</span>"
if (user.get_inactive_hand()==src)
user.unEquip(src)
user.put_in_inactive_hand(B)
var/holding_this = user.get_inactive_held_item()==src
qdel(src)
if (holding_this)
user.put_in_inactive_hand(B)
else
user << "<span class='warning'>You need one sheet of metal to start building ED-209!</span>"
return
else if(istype(W, /obj/item/robot_parts/l_leg))
else if(istype(W, /obj/item/bodypart/l_leg/robot))
if(src.l_leg)
return
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
W.icon_state = initial(W.icon_state)
W.cut_overlays()
src.l_leg = W
src.updateicon()
else if(istype(W, /obj/item/robot_parts/r_leg))
else if(istype(W, /obj/item/bodypart/r_leg/robot))
if(src.r_leg)
return
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
W.icon_state = initial(W.icon_state)
W.cut_overlays()
src.r_leg = W
src.updateicon()
else if(istype(W, /obj/item/robot_parts/l_arm))
else if(istype(W, /obj/item/bodypart/l_arm/robot))
if(src.l_arm)
return
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
W.icon_state = initial(W.icon_state)
W.cut_overlays()
src.l_arm = W
src.updateicon()
else if(istype(W, /obj/item/robot_parts/r_arm))
else if(istype(W, /obj/item/bodypart/r_arm/robot))
if(src.r_arm)
return
if(!user.unEquip(W))
if(!user.transferItemToLoc(W, src))
return
W.loc = src
W.icon_state = initial(W.icon_state)//in case it is a dismembered robotic limb
W.cut_overlays()
src.r_arm = W
src.updateicon()
else if(istype(W, /obj/item/robot_parts/chest))
else if(istype(W, /obj/item/bodypart/chest/robot))
var/obj/item/bodypart/chest/robot/CH = W
if(src.chest)
return
if(W:wired && W:cell)
if(!user.unEquip(W))
if(CH.wired && CH.cell)
if(!user.transferItemToLoc(CH, src))
return
W.loc = src
src.chest = W
CH.icon_state = initial(CH.icon_state) //in case it is a dismembered robotic limb
CH.cut_overlays()
src.chest = CH
src.updateicon()
else if(!W:wired)
else if(!CH.wired)
user << "<span class='warning'>You need to attach wires to it first!</span>"
else
user << "<span class='warning'>You need to attach a cell to it first!</span>"
else if(istype(W, /obj/item/robot_parts/head))
else if(istype(W, /obj/item/bodypart/head/robot))
var/obj/item/bodypart/head/robot/HD = W
for(var/X in HD.contents)
if(istype(X, /obj/item/organ))
user << "<span class='warning'>There are organs inside [HD]!</span>"
return
if(src.head)
return
if(W:flash2 && W:flash1)
if(!user.unEquip(W))
if(HD.flash2 && HD.flash1)
if(!user.transferItemToLoc(HD, src))
return
W.loc = src
src.head = W
HD.icon_state = initial(HD.icon_state)//in case it is a dismembered robotic limb
HD.cut_overlays()
src.head = HD
src.updateicon()
else
user << "<span class='warning'>You need to attach a flash to it first!</span>"
@@ -185,20 +161,20 @@
else if(istype(W, /obj/item/device/mmi))
var/obj/item/device/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
user << "<span class='warning'>You can't put the MMI in, the frame has to be standing on the ground to be perfectly precise!</span>"
if(!isturf(loc))
user << "<span class='warning'>You can't put [M] in, the frame has to be standing on the ground to be perfectly precise!</span>"
return
if(!M.brainmob)
user << "<span class='warning'>Sticking an empty MMI into the frame would sort of defeat the purpose!</span>"
user << "<span class='warning'>Sticking an empty [M.name] into the frame would sort of defeat the purpose!</span>"
return
var/mob/living/carbon/brain/BM = M.brainmob
var/mob/living/brain/BM = M.brainmob
if(!BM.key || !BM.mind)
user << "<span class='warning'>The mmi indicates that their mind is completely unresponsive; there's no point!</span>"
user << "<span class='warning'>The MMI indicates that their mind is completely unresponsive; there's no point!</span>"
return
if(!BM.client) //braindead
user << "<span class='warning'>The mmi indicates that their mind is currently inactive; it might change!</span>"
user << "<span class='warning'>The MMI indicates that their mind is currently inactive; it might change!</span>"
return
if(BM.stat == DEAD || (M.brain && M.brain.damaged_brain))
@@ -206,26 +182,21 @@
return
if(jobban_isbanned(BM, "Cyborg"))
user << "<span class='warning'>This MMI does not seem to fit!</span>"
user << "<span class='warning'>This [M.name] does not seem to fit!</span>"
return
if(!user.unEquip(W))
if(!user.temporarilyRemoveItemFromInventory(W))
return
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc))
if(!O)
return
if(M.hacked || M.clockwork)
if(M.laws && M.laws.id != DEFAULT_AI_LAWID)
aisync = 0
lawsync = 0
var/datum/ai_laws/L
if(M.clockwork)
L = new/datum/ai_laws/ratvar
else
L = new/datum/ai_laws/syndicate_override
O.laws = L
L.associate(O)
O.laws = M.laws
M.laws.associate(O)
O.invisibility = 0
//Transfer debug settings to new mob
@@ -240,15 +211,14 @@
O.connected_ai = forced_ai
if(!lawsync)
O.lawupdate = 0
if(!M.hacked && !M.clockwork)
if(M.laws.id == DEFAULT_AI_LAWID)
O.make_laws()
ticker.mode.remove_antag_for_borging(BM.mind)
if(!istype(M.laws, /datum/ai_laws/ratvar))
remove_servant_of_ratvar(BM, TRUE)
BM.mind.transfer_to(O)
if(M.clockwork)
add_servant_of_ratvar(O)
if(O.mind && O.mind.special_role)
O.mind.store_memory("As a cyborg, you must obey your silicon laws and master AI above all else. Your objectives will consider you to be dead.")
O << "<span class='userdanger'>You have been robotized!</span>"
@@ -259,7 +229,7 @@
O.cell = chest.cell
chest.cell.loc = O
chest.cell = null
W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
W.forceMove(O)//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
if(O.mmi) //we delete the mmi created by robot/New()
qdel(O.mmi)
O.mmi = W //and give the real mmi to the borg.
@@ -267,7 +237,7 @@
feedback_inc("cyborg_birth",1)
src.loc = O
forceMove(O)
O.robot_suit = src
if(!locomotion)
@@ -283,7 +253,7 @@
else
return ..()
/obj/item/robot_parts/robot_suit/proc/Interact(mob/user)
/obj/item/robot_suit/proc/Interact(mob/user)
var/t1 = text("Designation: <A href='?src=\ref[];Name=1'>[(created_name ? "[created_name]" : "Default Cyborg")]</a><br>\n",src)
t1 += text("Master AI: <A href='?src=\ref[];Master=1'>[(forced_ai ? "[forced_ai.name]" : "Automatic")]</a><br><br>\n",src)
@@ -295,12 +265,12 @@
popup.set_content(t1)
popup.open()
/obj/item/robot_parts/robot_suit/Topic(href, href_list)
if(usr.lying || usr.stat || usr.stunned || !Adjacent(usr))
/obj/item/robot_suit/Topic(href, href_list)
if(usr.incapacitated() || !Adjacent(usr))
return
var/mob/living/living_user = usr
var/obj/item/item_in_hand = living_user.get_active_hand()
var/obj/item/item_in_hand = living_user.get_active_held_item()
if(!istype(item_in_hand, /obj/item/device/multitool))
living_user << "<span class='warning'>You need a multitool!</span>"
return
@@ -330,50 +300,4 @@
add_fingerprint(usr)
Interact(usr)
return
/obj/item/robot_parts/chest/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
if(src.cell)
user << "<span class='warning'>You have already inserted a cell!</span>"
return
else
if(!user.unEquip(W))
return
W.loc = src
src.cell = W
user << "<span class='notice'>You insert the cell.</span>"
else if(istype(W, /obj/item/stack/cable_coil))
if(src.wired)
user << "<span class='warning'>You have already inserted wire!</span>"
return
var/obj/item/stack/cable_coil/coil = W
if (coil.use(1))
src.wired = 1
user << "<span class='notice'>You insert the wire.</span>"
else
user << "<span class='warning'>You need one length of coil to wire it!</span>"
else
return ..()
/obj/item/robot_parts/head/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/device/assembly/flash/handheld))
var/obj/item/device/assembly/flash/handheld/F = W
if(src.flash1 && src.flash2)
user << "<span class='warning'>You have already inserted the eyes!</span>"
return
else if(F.crit_fail)
user << "<span class='warning'>You can't use a broken flash!</span>"
return
else
if(!user.unEquip(W))
return
F.loc = src
if(src.flash1)
src.flash2 = F
else
src.flash1 = F
user << "<span class='notice'>You insert the flash into the eye socket.</span>"
else
return ..()
+116 -77
View File
@@ -11,6 +11,9 @@
var/installed = 0
var/require_module = 0
var/module_type = null
// if true, is not stored in the robot to be ejected
// if module is reset
var/one_use = FALSE
/obj/item/borg/upgrade/proc/action(mob/living/silicon/robot/R)
if(R.stat == DEAD)
@@ -21,48 +24,12 @@
usr << "There's no mounting point for the module!"
return 1
/obj/item/borg/upgrade/reset
name = "cyborg module reset board"
desc = "Used to reset a cyborg's module. Destroys any other upgrades applied to the cyborg."
icon_state = "cyborg_upgrade1"
require_module = 1
/obj/item/borg/upgrade/reset/action(mob/living/silicon/robot/R)
if(..())
return
R.notify_ai(2)
R.uneq_all()
R.pixel_x = initial(pixel_x)
R.hands.icon_state = "nomod"
R.icon = 'icons/mob/robots.dmi'
R.icon_state = "robot"
R.update_icons()
qdel(R.module)
R.module = null
R.modtype = "robot"
R.designation = "Default"
R.updatename("Default")
R.update_icons()
R.update_headlamp()
R.speed = 0 // Remove upgrades.
R.ionpulse = FALSE
R.magpulse = FALSE
R.weather_immunities = initial(R.weather_immunities)
R.status_flags |= CANPUSH
return 1
/obj/item/borg/upgrade/rename
name = "cyborg reclassification board"
desc = "Used to rename a cyborg."
icon_state = "cyborg_upgrade1"
var/heldname = "default name"
var/heldname = ""
one_use = TRUE
/obj/item/borg/upgrade/rename/attack_self(mob/user)
heldname = stripped_input(user, "Enter new robot name", "Cyborg Reclassification", heldname, MAX_NAME_LEN)
@@ -71,7 +38,12 @@
if(..())
return
R.fully_replace_character_name(R.name, heldname)
var/oldname = R.real_name
R.custom_name = heldname
R.updatename()
if(oldname == R.real_name)
R.notify_ai(3, oldname, R.real_name)
return 1
@@ -80,16 +52,16 @@
name = "cyborg emergency reboot module"
desc = "Used to force a reboot of a disabled-but-repaired cyborg, bringing it back online."
icon_state = "cyborg_upgrade1"
one_use = TRUE
/obj/item/borg/upgrade/restart/action(mob/living/silicon/robot/R)
if(R.health < 0)
usr << "<span class='warning'>You have to repair the cyborg before using this module!</span>"
return 0
if(!R.key)
for(var/mob/dead/observer/ghost in player_list)
if(ghost.mind && ghost.mind.current == R)
R.key = ghost.key
if(R.mind)
R.mind.grab_ghost()
playsound(loc, 'sound/voice/liveagain.ogg', 75, 1)
R.revive()
@@ -168,14 +140,14 @@
if(..())
return
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module.modules)
qdel(D)
for(var/obj/item/weapon/shovel/S in R.module.modules)
qdel(S)
R.module.modules += new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
R.module.rebuild()
for(var/obj/item/weapon/pickaxe/drill/cyborg/D in R.module)
R.module.remove_module(D, TRUE)
for(var/obj/item/weapon/shovel/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/pickaxe/drill/cyborg/diamond/DD = new /obj/item/weapon/pickaxe/drill/cyborg/diamond(R.module)
R.module.basic_modules += DD
R.module.add_module(DD, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/soh
@@ -190,32 +162,12 @@
if(..())
return
for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module.modules)
qdel(S)
R.module.modules += new /obj/item/weapon/storage/bag/ore/holding(R.module)
R.module.rebuild()
return 1
/obj/item/borg/upgrade/hyperka
name = "mining cyborg hyper-kinetic accelerator"
desc = "A satchel of holding replacement for mining cyborg's ore satchel module."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "materials=6;powerstorage=4;engineering=4;magnets=4;combat=4"
/obj/item/borg/upgrade/hyperka/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/gun/energy/kinetic_accelerator/cyborg/H in R.module.modules)
qdel(H)
R.module.modules += new /obj/item/weapon/gun/energy/kinetic_accelerator/hyper/cyborg(R.module)
R.module.rebuild()
for(var/obj/item/weapon/storage/bag/ore/cyborg/S in R.module)
R.module.remove_module(S, TRUE)
var/obj/item/weapon/storage/bag/ore/holding/H = new /obj/item/weapon/storage/bag/ore/holding(R.module)
R.module.basic_modules += H
R.module.add_module(H, FALSE, TRUE)
return 1
/obj/item/borg/upgrade/syndicate
@@ -240,6 +192,7 @@
name = "mining cyborg lavaproof tracks"
desc = "An upgrade kit to apply specialized coolant systems and insulation layers to mining cyborg tracks, enabling them to withstand exposure to molten rock."
icon_state = "ash_plating"
resistance_flags = LAVA_PROOF | FIRE_PROOF
require_module = 1
module_type = /obj/item/weapon/robot_module/miner
origin_tech = "engineering=4;materials=4;plasmatech=4"
@@ -261,6 +214,7 @@
var/on = 0
var/powercost = 10
var/mob/living/silicon/robot/cyborg
var/datum/action/toggle_action
/obj/item/borg/upgrade/selfrepair/action(mob/living/silicon/robot/R)
if(..())
@@ -273,10 +227,19 @@
cyborg = R
icon_state = "selfrepair_off"
var/datum/action/A = new /datum/action/item_action/toggle(src)
A.Grant(R)
toggle_action = new /datum/action/item_action/toggle(src)
toggle_action.Grant(R)
return 1
/obj/item/borg/upgrade/selfrepair/dropped()
addtimer(CALLBACK(src, .proc/check_dropped), 1)
/obj/item/borg/upgrade/selfrepair/proc/check_dropped()
if(loc != cyborg)
toggle_action.Remove(cyborg)
cyborg = null
deactivate()
/obj/item/borg/upgrade/selfrepair/ui_action_click()
on = !on
if(on)
@@ -342,3 +305,79 @@
msg_cooldown = world.time
else
deactivate()
/obj/item/borg/upgrade/hypospray
name = "medical cyborg hypospray advanced synthesiser"
desc = "An upgrade to the Medical module cyborg's hypospray, allowing it \
to produce more advanced and complex medical reagents."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = null
var/list/additional_reagents = list()
/obj/item/borg/upgrade/hypospray/action(mob/living/silicon/robot/R)
if(..())
return
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
if(H.accepts_reagent_upgrades)
for(var/re in additional_reagents)
H.add_reagent(re)
return 1
/obj/item/borg/upgrade/hypospray/expanded
name = "medical cyborg expanded hypospray"
desc = "An upgrade to the Medical module's hypospray, allowing it \
to treat a wider range of conditions and problems."
additional_reagents = list("mannitol", "oculine", "inacusiate",
"mutadone", "haloperidol")
origin_tech = "programming=5;engineering=4;biotech=5"
/obj/item/borg/upgrade/hypospray/high_strength
name = "medical cyborg high-strength hypospray"
desc = "An upgrade to the Medical module's hypospray, containing \
stronger versions of existing chemicals."
additional_reagents = list("oxandrolone", "sal_acid", "rezadone",
"pen_acid")
origin_tech = "programming=5;engineering=5;biotech=6"
/obj/item/borg/upgrade/piercing_hypospray
name = "cyborg piercing hypospray"
desc = "An upgrade to a cyborg's hypospray, allowing it to \
pierce armor and thick material."
origin_tech = "materials=5;engineering=7;combat=3"
icon_state = "cyborg_upgrade3"
/obj/item/borg/upgrade/piercing_hypospray/action(mob/living/silicon/robot/R)
if(..())
return
var/found_hypo = FALSE
for(var/obj/item/weapon/reagent_containers/borghypo/H in R.module)
H.bypass_protection = TRUE
found_hypo = TRUE
if(!found_hypo)
return
return 1
/obj/item/borg/upgrade/defib
name = "medical cyborg defibrillator"
desc = "An upgrade to the Medical module, installing a builtin \
defibrillator, for on the scene revival."
icon_state = "cyborg_upgrade3"
require_module = 1
module_type = /obj/item/weapon/robot_module/medical
origin_tech = "programming=4;engineering=6;materials=5;powerstorage=5;biotech=5"
/obj/item/borg/upgrade/defib/action(mob/living/silicon/robot/R)
if(..())
return
var/obj/item/weapon/twohanded/shockpaddles/cyborg/S = new(R.module)
R.module.basic_modules += S
R.module.add_module(S, FALSE, TRUE)
return 1
+2 -2
View File
@@ -9,8 +9,8 @@
throwforce = 0
throw_speed = 2
throw_range = 2
w_class = 1
burn_state = FLAMMABLE
w_class = WEIGHT_CLASS_TINY
resistance_flags = FLAMMABLE
var/value = 1
/obj/item/stack/spacecash/c10
+31 -29
View File
@@ -4,11 +4,12 @@
icon = 'icons/obj/items.dmi'
amount = 6
max_amount = 6
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 7
burn_state = FLAMMABLE
burntime = 5
resistance_flags = FLAMMABLE
obj_integrity = 40
max_integrity = 40
var/heal_brute = 0
var/heal_burn = 0
var/stop_bleeding = 0
@@ -30,19 +31,21 @@
return 1
var/obj/item/bodypart/affecting
if(ishuman(M))
var/mob/living/carbon/human/H = M
affecting = H.get_bodypart(check_zone(user.zone_selected))
if(iscarbon(M))
var/mob/living/carbon/C = M
affecting = C.get_bodypart(check_zone(user.zone_selected))
if(!affecting) //Missing limb?
user << "<span class='warning'>[H] doesn't have \a [parse_zone(user.zone_selected)]!</span>"
user << "<span class='warning'>[C] doesn't have \a [parse_zone(user.zone_selected)]!</span>"
return
if(stop_bleeding)
if(H.bleedsuppress)
user << "<span class='warning'>[H]'s bleeding is already bandaged!</span>"
return
else if(!H.bleed_rate)
user << "<span class='warning'>[H] isn't bleeding!</span>"
return
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(stop_bleeding)
if(H.bleedsuppress)
user << "<span class='warning'>[H]'s bleeding is already bandaged!</span>"
return
else if(!H.bleed_rate)
user << "<span class='warning'>[H] isn't bleeding!</span>"
return
if(isliving(M))
@@ -75,25 +78,24 @@
user.visible_message("<span class='green'>[user] applies [src] on [t_himself].</span>", "<span class='green'>You apply [src] on yourself.</span>")
if(ishuman(M))
var/mob/living/carbon/human/H = M
affecting = H.get_bodypart(check_zone(user.zone_selected))
if(iscarbon(M))
var/mob/living/carbon/C = M
affecting = C.get_bodypart(check_zone(user.zone_selected))
if(!affecting) //Missing limb?
user << "<span class='warning'>[H] doesn't have \a [parse_zone(user.zone_selected)]!</span>"
user << "<span class='warning'>[C] doesn't have \a [parse_zone(user.zone_selected)]!</span>"
return
if(stop_bleeding)
if(!H.bleedsuppress) //so you can't stack bleed suppression
H.suppress_bloodloss(stop_bleeding)
if(affecting.status == ORGAN_ORGANIC) //Limb must be organic to be healed - RR
if(affecting.heal_damage(src.heal_brute, src.heal_burn, 0))
H.update_damage_overlays(0)
M.updatehealth()
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(stop_bleeding)
if(!H.bleedsuppress) //so you can't stack bleed suppression
H.suppress_bloodloss(stop_bleeding)
if(affecting.status == BODYPART_ORGANIC) //Limb must be organic to be healed - RR
if(affecting.heal_damage(heal_brute, heal_burn))
C.update_damage_overlays()
else
user << "<span class='notice'>Medicine won't work on a robotic limb!</span>"
else
M.heal_organ_damage((src.heal_brute/2), (src.heal_burn/2))
M.heal_bodypart_damage((src.heal_brute/2), (src.heal_burn/2))
use(1)
@@ -123,7 +125,7 @@
desc = "A roll of cloth roughly cut from something that can stop bleeding, but does not heal wounds."
stop_bleeding = 900
/obj/item/stack/medical/gauze/cyborg/
/obj/item/stack/medical/gauze/cyborg
materials = list()
is_cyborg = 1
cost = 250
+4 -4
View File
@@ -11,7 +11,7 @@ var/global/list/datum/stack_recipe/rod_recipes = list ( \
icon_state = "rods"
item_state = "rods"
flags = CONDUCT
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
force = 9
throwforce = 10
throw_speed = 3
@@ -49,7 +49,7 @@ var/global/list/datum/stack_recipe/rod_recipes = list ( \
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
var/replace = (user.get_inactive_held_item()==R)
R.use(2)
if (!R && replace)
user.put_in_hands(new_item)
@@ -58,7 +58,7 @@ var/global/list/datum/stack_recipe/rod_recipes = list ( \
var/obj/item/weapon/reagent_containers/food/snacks/S = W
if(amount != 1)
user << "<span class='warning'>You must use a single rod!</span>"
else if(S.w_class > 2)
else if(S.w_class > WEIGHT_CLASS_SMALL)
user << "<span class='warning'>The ingredient is too big for [src]!</span>"
else
var/obj/item/weapon/reagent_containers/food/snacks/customizable/A = new/obj/item/weapon/reagent_containers/food/snacks/customizable/kebab(get_turf(src))
@@ -66,7 +66,7 @@ var/global/list/datum/stack_recipe/rod_recipes = list ( \
else
return ..()
/obj/item/stack/rods/cyborg/
/obj/item/stack/rods/cyborg
materials = list()
is_cyborg = 1
cost = 250
+53 -204
View File
@@ -8,6 +8,11 @@
/*
* Glass sheets
*/
var/global/list/datum/stack_recipe/glass_recipes = list ( \
new/datum/stack_recipe("directional window", /obj/structure/window/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("fulltile window", /obj/structure/window/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
)
/obj/item/stack/sheet/glass
name = "glass"
desc = "HOLY SHEET! That is a lot of glass."
@@ -15,6 +20,9 @@
icon_state = "sheet-glass"
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
origin_tech = "materials=1"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100)
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/glass
/obj/item/stack/sheet/glass/cyborg
materials = list()
@@ -24,8 +32,9 @@
/obj/item/stack/sheet/glass/fifty
amount = 50
/obj/item/stack/sheet/glass/attack_self(mob/user)
construct_window(user)
/obj/item/stack/sheet/glass/New(loc, amount)
recipes = glass_recipes
..()
/obj/item/stack/sheet/glass/attackby(obj/item/W, mob/user, params)
add_fingerprint(user)
@@ -46,7 +55,7 @@
RG.add_fingerprint(user)
var/obj/item/stack/sheet/glass/G = src
src = null
var/replace = (user.get_inactive_hand()==G)
var/replace = (user.get_inactive_held_item()==G)
V.use(1)
G.use(1)
if (!G && replace)
@@ -57,79 +66,18 @@
else
return ..()
/obj/item/stack/sheet/glass/proc/construct_window(mob/user)
if(!user || !src)
return 0
if(!istype(user.loc,/turf))
return 0
if(!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return 0
if(zero_amount())
return 0
var/title = "Sheet-Glass"
title += " ([src.get_amount()] sheet\s left)"
switch(alert(title, "Would you like full tile glass or one direction?", "One Direction", "Full Window", "Cancel", null))
if("One Direction")
if(!src)
return 1
if(src.loc != user)
return 1
var/list/directions = new/list(cardinal)
var/i = 0
for (var/obj/structure/window/win in user.loc)
i++
if(i >= 4)
user << "<span class='warning'>There are too many windows in this location.</span>"
return 1
directions-=win.dir
if(!(win.ini_dir in cardinal))
user << "<span class='danger'>Can't let you do that.</span>"
return 1
//Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
var/dir_to_set = 2
for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
var/found = 0
for(var/obj/structure/window/WT in user.loc)
if(WT.dir == direction)
found = 1
if(!found)
dir_to_set = direction
break
var/obj/structure/window/W
W = new /obj/structure/window( user.loc, 0 )
W.setDir(dir_to_set)
W.ini_dir = W.dir
W.anchored = 0
W.air_update_turf(1)
src.use(1)
W.add_fingerprint(user)
if("Full Window")
if(!src)
return 1
if(src.loc != user)
return 1
if(src.get_amount() < 2)
user << "<span class='warning'>You need more glass to do that!</span>"
return 1
if(locate(/obj/structure/window) in user.loc)
user << "<span class='warning'>There is a window in the way!</span>"
return 1
var/obj/structure/window/W
W = new /obj/structure/window/fulltile( user.loc, 0 )
W.anchored = 0
W.air_update_turf(1)
W.add_fingerprint(user)
src.use(2)
return 0
/*
* Reinforced glass sheets
*/
var/global/list/datum/stack_recipe/reinforced_glass_recipes = list ( \
new/datum/stack_recipe("windoor frame", /obj/structure/windoor_assembly, 5, time = 0, on_floor = TRUE, window_checks = TRUE), \
null, \
new/datum/stack_recipe("directional reinforced window", /obj/structure/window/reinforced/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("fulltile reinforced window", /obj/structure/window/reinforced/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE) \
)
/obj/item/stack/sheet/rglass
name = "reinforced glass"
desc = "Glass which seems to have rods or something stuck in them."
@@ -137,137 +85,30 @@
icon_state = "sheet-rglass"
materials = list(MAT_METAL=MINERAL_MATERIAL_AMOUNT/2, MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
origin_tech = "materials=2"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 70, acid = 100)
resistance_flags = ACID_PROOF
merge_type = /obj/item/stack/sheet/rglass
/obj/item/stack/sheet/rglass/cyborg
materials = list()
var/datum/robot_energy_storage/metsource
var/datum/robot_energy_storage/glasource
var/metcost = 250
var/glacost = 500
/obj/item/stack/sheet/rglass/cyborg/get_amount()
return min(round(metsource.energy / metcost), round(glasource.energy / glacost))
return min(round(source.energy / metcost), round(glasource.energy / glacost))
/obj/item/stack/sheet/rglass/cyborg/use(amount) // Requires special checks, because it uses two storages
metsource.use_charge(amount * metcost)
source.use_charge(amount * metcost)
glasource.use_charge(amount * glacost)
return
/obj/item/stack/sheet/rglass/cyborg/add(amount)
metsource.add_charge(amount * metcost)
source.add_charge(amount * metcost)
glasource.add_charge(amount * glacost)
return
/obj/item/stack/sheet/rglass/attack_self(mob/user)
construct_window(user)
/obj/item/stack/sheet/rglass/proc/construct_window(mob/user)
if(!user || !src)
return 0
if(!istype(user.loc,/turf))
return 0
if(!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return 0
var/title = "Sheet Reinf. Glass"
title += " ([src.get_amount()] sheet\s left)"
switch(input(title, "Would you like full tile glass a one direction glass pane or a windoor?") in list("One Direction", "Full Window", "Windoor", "Cancel"))
if("One Direction")
if(!src)
return 1
if(src.loc != user)
return 1
var/list/directions = new/list(cardinal)
var/i = 0
for (var/obj/structure/window/win in user.loc)
i++
if(i >= 4)
user << "<span class='danger'>There are too many windows in this location.</span>"
return 1
directions-=win.dir
if(!(win.ini_dir in cardinal))
user << "<span class='danger'>Can't let you do that.</span>"
return 1
//Determine the direction. It will first check in the direction the person making the window is facing, if it finds an already made window it will try looking at the next cardinal direction, etc.
var/dir_to_set = 2
for(var/direction in list( user.dir, turn(user.dir,90), turn(user.dir,180), turn(user.dir,270) ))
var/found = 0
for(var/obj/structure/window/WT in user.loc)
if(WT.dir == direction)
found = 1
if(!found)
dir_to_set = direction
break
var/obj/structure/window/W
W = new /obj/structure/window/reinforced( user.loc, 1 )
W.state = 0
W.setDir(dir_to_set)
W.ini_dir = W.dir
W.anchored = 0
W.add_fingerprint(user)
src.use(1)
if("Full Window")
if(!src)
return 1
if(src.loc != user)
return 1
if(src.get_amount() < 2)
user << "<span class='warning'>You need more glass to do that!</span>"
return 1
if(locate(/obj/structure/window) in user.loc)
user << "<span class='warning'>There is a window in the way!</span>"
return 1
var/obj/structure/window/W
W = new /obj/structure/window/reinforced/fulltile(user.loc, 1)
W.state = 0
W.anchored = 0
W.add_fingerprint(user)
src.use(2)
if("Windoor")
if(!src || src.loc != user || !isturf(user.loc))
return 1
for(var/obj/structure/windoor_assembly/WA in user.loc)
if(WA.dir == user.dir)
user << "<span class='warning'>There is already a windoor assembly in that location!</span>"
return 1
for(var/obj/machinery/door/window/W in user.loc)
if(W.dir == user.dir)
user << "<span class='warning'>There is already a windoor in that location!</span>"
return 1
if(src.get_amount() < 5)
user << "<span class='warning'>You need more glass to do that!</span>"
return 1
var/obj/structure/windoor_assembly/WD = new(user.loc)
WD.state = "01"
WD.anchored = 0
WD.add_fingerprint(user)
src.use(5)
switch(user.dir)
if(SOUTH)
WD.setDir(SOUTH)
WD.ini_dir = SOUTH
if(EAST)
WD.setDir(EAST)
WD.ini_dir = EAST
if(WEST)
WD.setDir(WEST)
WD.ini_dir = WEST
else //If the user is facing northeast. northwest, southeast, southwest or north, default to north
WD.setDir(NORTH)
WD.ini_dir = NORTH
else
return 1
return 0
/obj/item/stack/sheet/rglass/New(loc, amount)
recipes = reinforced_glass_recipes
..()
/obj/item/weapon/shard
@@ -275,19 +116,22 @@
desc = "A nasty looking shard of glass."
icon = 'icons/obj/shards.dmi'
icon_state = "large"
w_class = 1
w_class = WEIGHT_CLASS_TINY
force = 5
throwforce = 10
item_state = "shard-glass"
materials = list(MAT_GLASS=MINERAL_MATERIAL_AMOUNT)
attack_verb = list("stabbed", "slashed", "sliced", "cut")
hitsound = 'sound/weapons/bladeslice.ogg'
resistance_flags = ACID_PROOF
armor = list(melee = 100, bullet = 0, laser = 0, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 100)
obj_integrity = 40
max_integrity = 40
var/cooldown = 0
sharpness = IS_SHARP
/obj/item/weapon/shard/suicide_act(mob/user)
user.visible_message(pick("<span class='suicide'>[user] is slitting \his wrists with the shard of glass! It looks like \he's trying to commit suicide.</span>", \
"<span class='suicide'>[user] is slitting \his throat with the shard of glass! It looks like \he's trying to commit suicide.</span>"))
user.visible_message("<span class='suicide'>[user] is slitting [user.p_their()] [pick("wrists", "throat")] with the shard of glass! It looks like [user.p_theyre()] trying to commit suicide.</span>")
return (BRUTELOSS)
@@ -311,23 +155,22 @@
return
if(istype(A, /obj/item/weapon/storage))
return
var/hit_hand = ((user.active_hand_index % 2 == 0) ? "r_" : "l_") + "arm"
if(ishuman(user))
var/mob/living/carbon/human/H = user
if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.specflags)) // golems, etc
if(!H.gloves && !(PIERCEIMMUNE in H.dna.species.species_traits)) // golems, etc
H << "<span class='warning'>[src] cuts into your hand!</span>"
var/organ = (H.hand ? "l_" : "r_") + "arm"
var/obj/item/bodypart/affecting = H.get_bodypart(organ)
if(affecting && affecting.take_damage(force / 2))
H.update_damage_overlays(0)
H.apply_damage(force*0.5, BRUTE, hit_hand)
else if(ismonkey(user))
var/mob/living/carbon/monkey/M = user
M << "<span class='warning'>[src] cuts into your hand!</span>"
M.adjustBruteLoss(force / 2)
M.apply_damage(force*0.5, BRUTE, hit_hand)
/obj/item/weapon/shard/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/weapon/weldingtool))
if(istype(I, /obj/item/device/lightreplacer))
I.attackby(src, user)
else if(istype(I, /obj/item/weapon/weldingtool))
var/obj/item/weapon/weldingtool/WT = I
if(WT.remove_fuel(0, user))
var/obj/item/stack/sheet/glass/NG = new (user.loc)
@@ -347,16 +190,22 @@
playsound(loc, 'sound/effects/glass_step.ogg', 50, 1)
if(ishuman(AM))
var/mob/living/carbon/human/H = AM
if(PIERCEIMMUNE in H.dna.species.specflags)
if(PIERCEIMMUNE in H.dna.species.species_traits)
return
var/picked_def_zone = pick("l_leg", "r_leg")
var/obj/item/bodypart/O = H.get_bodypart(picked_def_zone)
if(!istype(O))
return
if(!H.shoes)
var/feetCover = (H.wear_suit && H.wear_suit.body_parts_covered & FEET) || (H.w_uniform && H.w_uniform.body_parts_covered & FEET)
if(!H.shoes && !feetCover)
H.apply_damage(5, BRUTE, picked_def_zone)
H.Weaken(3)
if(cooldown < world.time - 10) //cooldown to avoid message spam.
H.visible_message("<span class='danger'>[H] steps in the broken glass!</span>", \
"<span class='userdanger'>You step in the broken glass!</span>")
if(!H.incapacitated())
H.visible_message("<span class='danger'>[H] steps in the broken glass!</span>", \
"<span class='userdanger'>You step in the broken glass!</span>")
else
H.visible_message("<span class='danger'>[H] slides on the broken glass!</span>", \
"<span class='userdanger'>You slide on the broken glass!</span>")
cooldown = world.time
H.Weaken(3)
@@ -18,9 +18,9 @@ var/global/list/datum/stack_recipe/human_recipes = list( \
return ..()
/obj/item/stack/sheet/animalhide/generic
name = "generic skin"
desc = "A piece of generic skin."
singular_name = "generic skin piece"
name = "skin"
desc = "A piece of skin."
singular_name = "skin piece"
icon_state = "sheet-hide"
/obj/item/stack/sheet/animalhide/corgi
@@ -104,7 +104,7 @@ var/global/list/datum/stack_recipe/xeno_recipes = list ( \
/obj/item/stack/sheet/hairlesshide
name = "hairless hide"
desc = "This hide was stripped of it's hair, but still needs tanning."
desc = "This hide was stripped of its hair, but still needs washing and tanning."
singular_name = "hairless hide piece"
icon_state = "sheet-hairlesshide"
origin_tech = null
@@ -152,7 +152,7 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
icon_state = "goliath_hide"
singular_name = "hide plate"
flags = NOBLUDGEON
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
/obj/item/stack/sheet/animalhide/ashdrake
@@ -162,14 +162,14 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
icon_state = "dragon_hide"
singular_name = "drake plate"
flags = NOBLUDGEON
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
layer = MOB_LAYER
//Step one - dehairing.
/obj/item/stack/sheet/animalhide/attackby(obj/item/weapon/W, mob/user, params)
if(is_sharp(W))
if(W.is_sharp())
playsound(loc, 'sound/weapons/slice.ogg', 50, 1, -1)
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
if(do_after(user,50, target = src))
@@ -207,4 +207,4 @@ var/global/list/datum/stack_recipe/sinew_recipes = list ( \
var/obj/item/stack/sheet/leather/HS = new(src.loc)
HS.amount = 1
wetness = initial(wetness)
src.use(1)
src.use(1)
@@ -4,7 +4,7 @@
desc = "A glass tile, which is wired, somehow."
icon = 'icons/obj/tiles.dmi'
icon_state = "glass_wire"
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
force = 3
throwforce = 5
throw_speed = 3
@@ -22,14 +22,13 @@
var/obj/item/stack/sheet/glass/G = new (user.loc)
G.add_fingerprint(user)
if(amount <= 0)
user.unEquip(src, 1)
qdel(src)
else if(istype(O, /obj/item/stack/sheet/metal))
var/obj/item/stack/sheet/metal/M = O
if (M.use(1))
use(1)
var/obj/item/stack/tile/light/L = new (user.loc)
var/obj/item/L = new /obj/item/stack/tile/light(user.loc)
user << "<span class='notice'>You make a light tile.</span>"
L.add_fingerprint(user)
else
@@ -10,6 +10,8 @@ Mineral Sheets
- Gold
- Silver
- Clown
- Titanium
- Plastitanium
Others:
- Adamantine
- Mythril
@@ -133,8 +135,9 @@ var/global/list/datum/stack_recipe/uranium_recipes = list ( \
singular_name = "plasma sheet"
origin_tech = "plasmatech=2;materials=2"
sheettype = "plasma"
burn_state = FLAMMABLE
burntime = 5
resistance_flags = FLAMMABLE
obj_integrity = 100
max_integrity = 100
materials = list(MAT_PLASMA=MINERAL_MATERIAL_AMOUNT)
var/global/list/datum/stack_recipe/plasma_recipes = list ( \
@@ -157,7 +160,7 @@ var/global/list/datum/stack_recipe/plasma_recipes = list ( \
else
return ..()
/obj/item/stack/sheet/mineral/plasma/fire_act()
/obj/item/stack/sheet/mineral/plasma/fire_act(exposed_temperature, exposed_volume)
atmos_spawn_air("plasma=[amount*10];TEMP=1000")
qdel(src)
@@ -179,6 +182,7 @@ var/global/list/datum/stack_recipe/gold_recipes = list ( \
new/datum/stack_recipe("HoP Statue", /obj/structure/statue/gold/hop, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("CE Statue", /obj/structure/statue/gold/ce, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("RD Statue", /obj/structure/statue/gold/rd, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("Simple Crown", /obj/item/clothing/head/crown, 5), \
new/datum/stack_recipe("CMO Statue", /obj/structure/statue/gold/cmo, 5, one_per_turf = 1, on_floor = 1), \
)
@@ -237,6 +241,60 @@ var/global/list/datum/stack_recipe/clown_recipes = list ( \
pixel_y = rand(0,4)-4
..()
/*
* Titanium
*/
/obj/item/stack/sheet/mineral/titanium
name = "titanium"
icon_state = "sheet-titanium"
singular_name = "titanium sheet"
force = 5
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 1
throw_range = 3
origin_tech = "materials=4"
sheettype = "titanium"
materials = list(MAT_TITANIUM=MINERAL_MATERIAL_AMOUNT)
var/global/list/datum/stack_recipe/titanium_recipes = list ( \
new/datum/stack_recipe("titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20), \
)
/obj/item/stack/sheet/mineral/titanium/New(var/loc, var/amount=null)
recipes = titanium_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
/*
* Plastitanium
*/
/obj/item/stack/sheet/mineral/plastitanium
name = "plastitanium"
icon_state = "sheet-plastitanium"
singular_name = "plastitanium sheet"
force = 5
throwforce = 5
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 1
throw_range = 3
origin_tech = "materials=4"
sheettype = "plastitanium"
materials = list(MAT_TITANIUM=2000, MAT_PLASMA=2000)
var/global/list/datum/stack_recipe/plastitanium_recipes = list ( \
new/datum/stack_recipe("plas-titanium tile", /obj/item/stack/tile/mineral/plastitanium, 1, 4, 20), \
)
/obj/item/stack/sheet/mineral/plastitanium/New(var/loc, var/amount=null)
recipes = plastitanium_recipes
pixel_x = rand(0,4)-4
pixel_y = rand(0,4)-4
..()
/*
* Snow
*/
@@ -6,6 +6,7 @@
* Cloth
* Cardboard
* Runed Metal (cult)
* Brass (clockwork cult)
*/
/*
@@ -30,6 +31,7 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
new/datum/stack_recipe("wall girders", /obj/structure/girder, 2, time = 40, one_per_turf = 1, on_floor = 1), \
null, \
new/datum/stack_recipe("computer frame", /obj/structure/frame/computer, 5, time = 25, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("modular console", /obj/machinery/modular_computer/console/buildable/, 10, time = 25, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("machine frame", /obj/structure/frame/machine, 5, time = 25, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("airlock assembly", /obj/structure/door_assembly, 4, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("firelock frame", /obj/structure/firelock_frame, 3, time = 50, one_per_turf = 1, on_floor = 1), \
@@ -59,6 +61,12 @@ var/global/list/datum/stack_recipe/metal_recipes = list ( \
throwforce = 10
flags = CONDUCT
origin_tech = "materials=1"
resistance_flags = FIRE_PROOF
merge_type = /obj/item/stack/sheet/metal
/obj/item/stack/sheet/metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
qdel(src)
/obj/item/stack/sheet/metal/narsie_act()
if(prob(20))
@@ -94,10 +102,13 @@ var/global/list/datum/stack_recipe/plasteel_recipes = list ( \
desc = "This sheet is an alloy of iron and plasma."
icon_state = "sheet-plasteel"
item_state = "sheet-metal"
materials = list(MAT_METAL=6000, MAT_PLASMA=6000)
materials = list(MAT_METAL=2000, MAT_PLASMA=2000)
throwforce = 10
flags = CONDUCT
origin_tech = "materials=2"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 80)
resistance_flags = FIRE_PROOF
merge_type = /obj/item/stack/sheet/plasteel
/obj/item/stack/sheet/plasteel/New(var/loc, var/amount=null)
recipes = plasteel_recipes
@@ -117,18 +128,23 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \
new/datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20), \
new/datum/stack_recipe("wood table frame", /obj/structure/table_frame/wood, 2, time = 10), \
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 40), \
new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/normal, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("rolling pin", /obj/item/weapon/kitchen/rollingpin, 2, time = 30), \
new/datum/stack_recipe("wooden chair", /obj/structure/chair/wood/, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("winged wooden chair", /obj/structure/chair/wood/wings, 3, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("wooden barricade", /obj/structure/barricade/wooden, 5, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("wooden door", /obj/structure/mineral_door/wood, 10, time = 20, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("coffin", /obj/structure/closet/coffin, 5, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("book case", /obj/structure/bookcase, 4, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("drying rack", /obj/machinery/smartfridge/drying_rack, 10, time = 15, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("dog bed", /obj/structure/bed/dogbed, 10, time = 10, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("picture frame", /obj/item/weapon/picture_frame, 1, time = 10),\
new/datum/stack_recipe("display case chassis", /obj/structure/displaycase_chassis, 5, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("wooden buckler", /obj/item/weapon/shield/riot/buckler, 20, time = 40), \
new/datum/stack_recipe("apiary", /obj/structure/beebox, 40, time = 50),\
new/datum/stack_recipe("tiki mask", /obj/item/clothing/mask/gas/tiki_mask, 2), \
new/datum/stack_recipe("honey frame", /obj/item/honey_frame, 5, time = 10),\
new/datum/stack_recipe("ore box", /obj/structure/ore_box, 4, time = 50, one_per_turf = 1, on_floor = 1),\
new/datum/stack_recipe("baseball bat", /obj/item/weapon/melee/baseball_bat, 5, time = 15),\
)
/obj/item/stack/sheet/mineral/wood
@@ -139,7 +155,9 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \
icon = 'icons/obj/items.dmi'
origin_tech = "materials=1;biotech=1"
sheettype = "wood"
burn_state = FLAMMABLE
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 0)
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/mineral/wood
/obj/item/stack/sheet/mineral/wood/New(var/loc, var/amount=null)
recipes = wood_recipes
@@ -153,6 +171,7 @@ var/global/list/datum/stack_recipe/wood_recipes = list ( \
*/
var/global/list/datum/stack_recipe/cloth_recipes = list ( \
new/datum/stack_recipe("grey jumpsuit", /obj/item/clothing/under/color/grey, 3), \
new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/sneakers/black, 2), \
null, \
new/datum/stack_recipe("backpack", /obj/item/weapon/storage/backpack, 4), \
new/datum/stack_recipe("dufflebag", /obj/item/weapon/storage/backpack/dufflebag, 6), \
@@ -165,9 +184,11 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
null, \
new/datum/stack_recipe("improvised gauze", /obj/item/stack/medical/gauze/improvised, 1, 2, 6), \
new/datum/stack_recipe("rag", /obj/item/weapon/reagent_containers/glass/rag, 1), \
new/datum/stack_recipe("black shoes", /obj/item/clothing/shoes/sneakers/black, 2), \
new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 3), \
new/datum/stack_recipe("empty sandbag", /obj/item/weapon/emptysandbag, 4), \
null, \
new/datum/stack_recipe("fingerless gloves", /obj/item/clothing/gloves/fingerless, 1), \
new/datum/stack_recipe("black gloves", /obj/item/clothing/gloves/color/black, 3), \
)
/obj/item/stack/sheet/cloth
@@ -176,9 +197,10 @@ var/global/list/datum/stack_recipe/cloth_recipes = list ( \
singular_name = "cloth roll"
icon_state = "sheet-cloth"
origin_tech = "materials=2"
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
force = 0
throwforce = 0
merge_type = /obj/item/stack/sheet/cloth
/obj/item/stack/sheet/cloth/New(var/loc, var/amount=null)
recipes = cloth_recipes
@@ -209,7 +231,8 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
singular_name = "cardboard sheet"
icon_state = "sheet-card"
origin_tech = "materials=1"
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/sheet/cardboard
/obj/item/stack/sheet/cardboard/New(var/loc, var/amount=null)
recipes = cardboard_recipes
@@ -223,21 +246,26 @@ var/global/list/datum/stack_recipe/cardboard_recipes = list ( \
*/
var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 3, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("runed door", /obj/machinery/door/airlock/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("runed girder", /obj/structure/girder/cult, 1, time = 50, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("pylon", /obj/structure/cult/pylon, 3, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("forge", /obj/structure/cult/forge, 5, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("archives", /obj/structure/cult/tome, 2, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("altar", /obj/structure/cult/talisman, 5, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("pylon", /obj/structure/destructible/cult/pylon, 4, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("forge", /obj/structure/destructible/cult/forge, 3, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("archives", /obj/structure/destructible/cult/tome, 3, time = 40, one_per_turf = 1, on_floor = 1), \
new/datum/stack_recipe("altar", /obj/structure/destructible/cult/talisman, 3, time = 40, one_per_turf = 1, on_floor = 1), \
)
/obj/item/stack/sheet/runed_metal
name = "runed metal"
desc = "Sheets of cold metal with shifting inscriptions writ upon them."
singular_name = "runed metal"
singular_name = "runed metal sheet"
icon_state = "sheet-runed"
icon = 'icons/obj/items.dmi'
sheettype = "runed"
merge_type = /obj/item/stack/sheet/runed_metal
/obj/item/stack/sheet/runed_metal/ratvar_act()
new /obj/item/stack/tile/brass(loc, amount)
qdel(src)
/obj/item/stack/sheet/runed_metal/attack_self(mob/living/user)
if(!iscultist(user))
@@ -258,6 +286,45 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
recipes = runed_metal_recipes
return ..()
/*
* Brass
*/
var/global/list/datum/stack_recipe/brass_recipes = list ( \
new/datum/stack_recipe("wall gear", /obj/structure/destructible/clockwork/wall_gear, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE), \
null,
new/datum/stack_recipe("pinion airlock", /obj/machinery/door/airlock/clockwork, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass pinion airlock", /obj/machinery/door/airlock/clockwork/brass, 5, time = 50, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass windoor", /obj/machinery/door/window/clockwork, 2, time = 30, on_floor = TRUE, window_checks = TRUE), \
null,
new/datum/stack_recipe("directional brass window", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("fulltile brass window", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE) \
)
/obj/item/stack/tile/brass
name = "brass"
desc = "Sheets made out of brass."
singular_name = "brass sheet"
icon_state = "sheet-brass"
icon = 'icons/obj/items.dmi'
resistance_flags = FIRE_PROOF | ACID_PROOF
throwforce = 10
max_amount = 50
throw_speed = 1
throw_range = 3
turf_type = /turf/open/floor/clockwork
/obj/item/stack/tile/brass/narsie_act()
if(prob(20))
new /obj/item/stack/sheet/runed_metal(loc, amount)
qdel(src)
/obj/item/stack/tile/brass/New(var/loc, var/amount=null)
recipes = brass_recipes
..()
pixel_x = 0
pixel_y = 0
/obj/item/stack/sheet/lessergem
name = "lesser gems"
desc = "Rare kind of gems which are only gained by blood sacrifice to minor deities. They are needed in crafting powerful objects."
@@ -284,7 +351,7 @@ var/global/list/datum/stack_recipe/runed_metal_recipes = list ( \
desc = "Someone's been drinking their milk."
force = 7
throwforce = 5
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
throw_speed = 1
throw_range = 3
origin_tech = "materials=2;biotech=2"
@@ -1,6 +1,6 @@
/obj/item/stack/sheet
name = "sheet"
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
force = 5
throwforce = 5
max_amount = 50
+59 -22
View File
@@ -78,12 +78,6 @@
var/title as text
var/can_build = 1
can_build = can_build && (max_multiplier>0)
/*
if (R.one_per_turf)
can_build = can_build && !(locate(R.result_type) in usr.loc)
if (R.on_floor)
can_build = can_build && istype(usr.loc, /turf/open/floor)
*/
if (R.res_amount>1)
title+= "[R.res_amount]x [R.title]\s"
else
@@ -111,7 +105,7 @@
/obj/item/stack/Topic(href, href_list)
..()
if ((usr.restrained() || usr.stat || usr.get_active_hand() != src))
if (usr.restrained() || usr.stat || usr.get_active_held_item() != src)
return
if (href_list["make"])
if (src.get_amount() < 1) qdel(src) //Never should happen
@@ -133,10 +127,20 @@
O.setDir(usr.dir)
use(R.req_amount * multiplier)
//START: oh fuck i'm so sorry
if(istype(O, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = O
W.ini_dir = W.dir
else if(istype(O, /obj/structure/window))
var/obj/structure/window/W = O
W.ini_dir = W.dir
//END: oh fuck i'm so sorry
//is it a stack ?
if (R.max_res_amount > 1)
var/obj/item/stack/new_item = O
new_item.amount = R.res_amount*multiplier
new_item.update_icon()
if(new_item.amount <= 0)//if the stack is empty, i.e it has been merged with an existing stack and has been garbage collected
return
@@ -164,10 +168,13 @@
else
usr << "<span class='warning'>You haven't got enough [src] to build \the [R.title]!</span>"
return 0
if (R.one_per_turf && (locate(R.result_type) in usr.loc))
if(R.window_checks && !valid_window_location(usr.loc, usr.dir))
usr << "<span class='warning'>The [R.title] won't fit here!</span>"
return 0
if(R.one_per_turf && (locate(R.result_type) in usr.loc))
usr << "<span class='warning'>There is another [R.title] here!</span>"
return 0
if (R.on_floor && !istype(usr.loc, /turf/open/floor))
if(R.on_floor && !isfloorturf(usr.loc))
usr << "<span class='warning'>\The [R.title] must be constructed on the floor!</span>"
return 0
return 1
@@ -200,6 +207,8 @@
update_icon()
/obj/item/stack/proc/merge(obj/item/stack/S) //Merge src into S, as much as possible
if(S == src) //amusingly this can cause a stack to consume itself, let's not allow that.
return
var/transfer = get_amount()
if(S.is_cyborg)
transfer = min(transfer, round((S.source.max_energy - S.source.energy) / S.cost))
@@ -222,22 +231,44 @@
return ..()
/obj/item/stack/attack_hand(mob/user)
if (user.get_inactive_hand() == src)
if (user.get_inactive_held_item() == src)
if(zero_amount())
return
var/obj/item/stack/F = new src.type(user, 1)
. = F
F.copy_evidences(src)
user.put_in_hands(F)
src.add_fingerprint(user)
F.add_fingerprint(user)
use(1)
if (src && usr.machine==src)
spawn(0) src.interact(usr)
change_stack(user,1)
else
..()
return
/obj/item/stack/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src))
user << "<span class='warning'>You can't do that right now!</span>"
return
if(!in_range(src, user))
return
else
if(zero_amount())
return
//get amount from user
var/min = 0
var/max = src.get_amount()
var/stackmaterial = input(user,"How many sheets do you wish to take out of this stack? (Maximum [max]") as num
if(stackmaterial == null || stackmaterial <= min || stackmaterial >= src.get_amount())
return
else
change_stack(user,stackmaterial)
user << "<span class='notice'>You take [stackmaterial] sheets out of the stack</span>"
/obj/item/stack/proc/change_stack(mob/user,amount)
var/obj/item/stack/F = new src.type(user, amount)
. = F
F.copy_evidences(src)
user.put_in_hands(F)
add_fingerprint(user)
F.add_fingerprint(user)
use(amount)
/obj/item/stack/attackby(obj/item/W, mob/user, params)
if(istype(W, merge_type))
var/obj/item/stack/S = W
@@ -253,6 +284,10 @@
src.fingerprintslast = from.fingerprintslast
//TODO bloody overlay
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
if(M && M.dirty < 100)
M.dirty += amount
/*
* Recipe datum
*/
@@ -263,10 +298,11 @@
var/res_amount = 1
var/max_res_amount = 1
var/time = 0
var/one_per_turf = 0
var/on_floor = 0
var/one_per_turf = FALSE
var/on_floor = FALSE
var/window_checks = FALSE
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = 0, on_floor = 0)
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1, time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE)
src.title = title
src.result_type = result_type
src.req_amount = req_amount
@@ -275,3 +311,4 @@
src.time = time
src.one_per_turf = one_per_turf
src.on_floor = on_floor
src.window_checks = window_checks
@@ -0,0 +1,33 @@
/obj/item/stack/telecrystal
name = "telecrystal"
desc = "It seems to be pulsing with suspiciously enticing energies."
singular_name = "telecrystal"
icon = 'icons/obj/telescience.dmi'
icon_state = "telecrystal"
w_class = WEIGHT_CLASS_TINY
max_amount = 50
flags = NOBLUDGEON
origin_tech = "materials=6;syndicate=1"
/obj/item/stack/telecrystal/attack(mob/target, mob/user)
if(target == user) //You can't go around smacking people with crystals to find out if they have an uplink or not.
for(var/obj/item/weapon/implant/uplink/I in target)
if(I && I.imp_in)
I.hidden_uplink.telecrystals += amount
use(amount)
user << "<span class='notice'>You press [src] onto yourself and charge your hidden uplink.</span>"
/obj/item/stack/telecrystal/afterattack(obj/item/I, mob/user, proximity)
if(!proximity)
return
if(istype(I, /obj/item))
if(I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
I.hidden_uplink.telecrystals += amount
use(amount)
user << "<span class='notice'>You slot [src] into the [I] and charge its internal uplink.</span>"
/obj/item/stack/telecrystal/five
amount = 5
/obj/item/stack/telecrystal/twenty
amount = 20
@@ -25,7 +25,6 @@
amount--
new/obj/item/stack/light_w(user.loc)
if(amount <= 0)
user.unEquip(src, 1)
qdel(src)
else
return ..()
@@ -63,3 +63,23 @@
origin_tech = "materials=6;abductor=1"
turf_type = /turf/open/floor/mineral/abductor
mineralType = "abductor"
/obj/item/stack/tile/mineral/titanium
name = "titanium tile"
singular_name = "titanium floor tile"
desc = "A tile made of titanium, used for shuttles."
icon_state = "tile_shuttle"
origin_tech = "materials=2"
turf_type = /turf/open/floor/mineral/titanium
mineralType = "titanium"
materials = list(MAT_TITANIUM=500)
/obj/item/stack/tile/mineral/plastitanium
name = "plas-titanium tile"
singular_name = "plas-titanium floor tile"
desc = "A tile made of plas-titanium, used for very evil shuttles."
icon_state = "tile_darkshuttle"
origin_tech = "materials=2"
turf_type = /turf/open/floor/mineral/plastitanium
mineralType = "plastitanium"
materials = list(MAT_TITANIUM=250, MAT_PLASMA=250)
@@ -3,7 +3,7 @@
singular_name = "broken tile"
desc = "A broken tile. This should not exist."
icon = 'icons/obj/tiles.dmi'
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
force = 1
throwforce = 1
throw_speed = 3
@@ -47,7 +47,7 @@
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
var/replace = (user.get_inactive_held_item()==R)
R.use(4)
if (!R && replace)
user.put_in_hands(new_item)
@@ -60,7 +60,7 @@
"<span class='italics'>You hear welding.</span>")
var/obj/item/stack/rods/R = src
src = null
var/replace = (user.get_inactive_hand()==R)
var/replace = (user.get_inactive_held_item()==R)
R.use(4)
if (!R && replace)
user.put_in_hands(new_item)
@@ -75,7 +75,7 @@
icon_state = "tile_grass"
origin_tech = "biotech=1"
turf_type = /turf/open/floor/grass
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
//Wood
@@ -86,7 +86,7 @@
icon_state = "tile-wood"
origin_tech = "biotech=1"
turf_type = /turf/open/floor/wood
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
//Carpets
@@ -96,7 +96,7 @@
desc = "A piece of carpet. It is the same size as a floor tile."
icon_state = "tile-carpet"
turf_type = /turf/open/floor/carpet
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
/obj/item/stack/tile/fakespace
@@ -105,7 +105,8 @@
desc = "A piece of carpet with a convincing star pattern."
icon_state = "tile_space"
turf_type = /turf/open/floor/fakespace
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
merge_type = /obj/item/stack/tile/fakespace
/obj/item/stack/tile/fakespace/loaded
amount = 30
@@ -118,6 +119,7 @@
icon_state = "tile_noslip"
turf_type = /turf/open/floor/noslip
origin_tech = "materials=3"
merge_type = /obj/item/stack/tile/noslip
/obj/item/stack/tile/noslip/thirty
amount = 30
@@ -156,6 +158,8 @@
flags = CONDUCT
turf_type = /turf/open/floor/plasteel
mineralType = "metal"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70)
resistance_flags = FIRE_PROOF
/obj/item/stack/tile/plasteel/cyborg
desc = "The ground you walk on." //Not the usual floor tile desc as that refers to throwing, Cyborgs can't do that - RR
+9 -9
View File
@@ -12,7 +12,7 @@
flags = NOBLUDGEON
amount = 25
max_amount = 25
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
/obj/item/stack/wrapping_paper/Destroy()
if(!amount)
@@ -32,7 +32,7 @@
flags = NOBLUDGEON
amount = 25
max_amount = 25
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
/obj/item/proc/can_be_package_wrapped() //can the item be wrapped with package wrapper into a delivery package
return 1
@@ -58,8 +58,8 @@
var/obj/item/I = target
if(!I.can_be_package_wrapped())
return
if(user.r_hand == I || user.l_hand == I)
if(!user.unEquip(I))
if(user.is_holding(I))
if(!user.dropItemToGround(I))
return
else if(!isturf(I.loc))
return
@@ -71,6 +71,7 @@
user.put_in_hands(P)
I.forceMove(P)
var/size = round(I.w_class)
P.name = "[weightclass2text(size)] parcel"
P.w_class = size
size = min(size, 5)
P.icon_state = "deliverypackage[size]"
@@ -79,14 +80,13 @@
var/obj/structure/closet/O = target
if(O.opened)
return
if(!O.density) //can't wrap non dense closets (e.g. body bags)
if(!O.delivery_icon) //no delivery icon means unwrappable closet (e.g. body bags)
user << "<span class='warning'>You can't wrap this!</span>"
return
if(use(3))
var/obj/structure/bigDelivery/P = new /obj/structure/bigDelivery(get_turf(O.loc))
if(O.horizontal)
P.icon_state = "deliverycrate"
O.loc = P
P.icon_state = O.delivery_icon
O.forceMove(P)
P.add_fingerprint(user)
O.add_fingerprint(user)
else
@@ -110,6 +110,6 @@
icon = 'icons/obj/items.dmi'
icon_state = "c_tube"
throwforce = 0
w_class = 1
w_class = WEIGHT_CLASS_TINY
throw_speed = 3
throw_range = 5
+92 -81
View File
@@ -43,6 +43,7 @@
/obj/item/toy/balloon/New()
create_reagents(10)
..()
/obj/item/toy/balloon/attack(mob/living/carbon/human/M, mob/user)
return
@@ -73,7 +74,7 @@
user << "<span class='notice'>You fill the balloon with the contents of [I].</span>"
I.reagents.trans_to(src, 10)
update_icon()
else if(is_sharp(I))
else if(I.is_sharp())
balloon_burst()
else
return ..()
@@ -114,7 +115,7 @@
icon = 'icons/obj/weapons.dmi'
icon_state = "syndballoon"
item_state = "syndballoon"
w_class = 4
w_class = WEIGHT_CLASS_BULKY
/*
* Fake singularity
@@ -138,7 +139,7 @@
righthand_file = 'icons/mob/inhands/guns_righthand.dmi'
flags = CONDUCT
slot_flags = SLOT_BELT
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
materials = list(MAT_METAL=10, MAT_GLASS=10)
attack_verb = list("struck", "pistol whipped", "hit", "bashed")
var/bullets = 7
@@ -172,8 +173,8 @@
/obj/item/toy/gun/afterattack(atom/target as mob|obj|turf|area, mob/user, flag)
if (flag)
return
if (!(istype(usr, /mob/living/carbon/human) || ticker) && ticker.mode.name != "monkey")
usr << "<span class='warning'>You don't have the dexterity to do this!</span>"
if (!user.IsAdvancedToolUser())
user << "<span class='warning'>You don't have the dexterity to do this!</span>"
return
src.add_fingerprint(user)
if (src.bullets < 1)
@@ -191,7 +192,7 @@
desc = "Make sure to recyle the box in an autolathe when it gets empty."
icon = 'icons/obj/ammo.dmi'
icon_state = "357OLD-7"
w_class = 1
w_class = WEIGHT_CLASS_TINY
materials = list(MAT_METAL=10, MAT_GLASS=10)
var/amount_left = 7
@@ -212,7 +213,7 @@
icon_state = "sword0"
item_state = "sword0"
var/active = 0
w_class = 2
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("attacked", "struck", "hit")
var/hacked = 0
@@ -227,13 +228,13 @@
else
icon_state = "swordblue"
item_state = "swordblue"
w_class = 4
w_class = WEIGHT_CLASS_BULKY
else
user << "<span class='notice'>You push the plastic blade back down into the handle.</span>"
playsound(user, 'sound/weapons/saberoff.ogg', 20, 1)
icon_state = "sword0"
item_state = "sword0"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
add_fingerprint(user)
// Copied from /obj/item/weapon/melee/energy/sword/attackby
@@ -248,8 +249,6 @@
if(hacked) // That's right, we'll only check the "original" "sword".
newSaber.hacked = 1
newSaber.item_color = "rainbow"
user.unEquip(W)
user.unEquip(src)
qdel(W)
qdel(src)
else if(istype(W, /obj/item/device/multitool))
@@ -260,12 +259,7 @@
if(active)
icon_state = "swordrainbow"
// Updating overlays, copied from welder code.
// I tried calling attack_self twice, which looked cool, except it somehow didn't update the overlays!!
if(user.r_hand == src)
user.update_inv_r_hand(0)
else if(user.l_hand == src)
user.update_inv_l_hand(0)
user.update_inv_hands()
else
user << "<span class='warning'>It's already fabulous!</span>"
else
@@ -281,8 +275,8 @@
icon_state = "foamblade"
item_state = "arm_blade"
attack_verb = list("pricked", "absorbed", "gored")
w_class = 2
burn_state = FLAMMABLE
w_class = WEIGHT_CLASS_SMALL
resistance_flags = FLAMMABLE
/*
@@ -316,7 +310,7 @@
slot_flags = SLOT_BELT | SLOT_BACK
force = 5
throwforce = 5
w_class = 3
w_class = WEIGHT_CLASS_NORMAL
attack_verb = list("attacked", "slashed", "stabbed", "sliced")
hitsound = 'sound/weapons/bladeslice.ogg'
@@ -329,7 +323,7 @@
desc = "Wow!"
icon = 'icons/obj/toy.dmi'
icon_state = "snappop"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/ash_type = /obj/effect/decal/cleanable/ash
/obj/item/toy/snappop/proc/pop_burst(var/n=3, var/c=1)
@@ -342,7 +336,7 @@
playsound(src, 'sound/effects/snap.ogg', 50, 1)
qdel(src)
/obj/item/toy/snappop/fire_act()
/obj/item/toy/snappop/fire_act(exposed_temperature, exposed_volume)
pop_burst()
/obj/item/toy/snappop/throw_impact(atom/hit_atom)
@@ -352,7 +346,7 @@
/obj/item/toy/snappop/Crossed(H as mob|obj)
if(ishuman(H) || issilicon(H)) //i guess carp and shit shouldn't set them off
var/mob/living/carbon/M = H
if(issilicon(H) || M.m_intent == "run")
if(issilicon(H) || M.m_intent == MOVE_INTENT_RUN)
M << "<span class='danger'>You step on the snap pop!</span>"
pop_burst(2, 0)
@@ -366,7 +360,7 @@
/obj/effect/decal/cleanable/ash/snappop_phoenix/New()
. = ..()
addtimer(src, "respawn", respawn_time)
addtimer(CALLBACK(src, .proc/respawn), respawn_time)
/obj/effect/decal/cleanable/ash/snappop_phoenix/proc/respawn()
new /obj/item/toy/snappop/phoenix(get_turf(src))
@@ -465,7 +459,7 @@
desc = "A generic action figure modeled after nothing in particular."
icon = 'icons/obj/toy.dmi'
icon_state = "owlprize"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/cooldown = FALSE
var/messages = list("I'm super generic!", "Mathematics class is of variable difficulty!")
var/span = "danger"
@@ -525,7 +519,7 @@
desc = "A tool to help you write fictional devils!"
icon = 'icons/obj/library.dmi'
icon_state = "demonomicon"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
recharge_time = 60
/obj/item/toy/talking/codex_gigas/activation_message(mob/user)
@@ -614,8 +608,7 @@
"Remember, a dog is for life, not just for christmas.")
/obj/item/toy/talking/skeleton/suicide_act(mob/user)
user.visible_message("<span class='suicide'>[user] is trying to commit \
suicide with \the [src].</span>")
user.visible_message("<span class='suicide'>[user] is trying to commit suicide with [src].</span>")
if(ishuman(user))
var/mob/living/carbon/human/H = user
@@ -643,8 +636,9 @@
/obj/item/toy/cards
burn_state = FLAMMABLE
burntime = 5
resistance_flags = FLAMMABLE
obj_integrity = 50
max_integrity = 50
var/parentdeck = null
var/deckstyle = "nanotrasen"
var/card_hitsound = null
@@ -654,9 +648,6 @@
var/card_throw_range = 7
var/list/card_attack_verb = list("attacked")
/obj/item/toy/cards/New()
..()
/obj/item/toy/cards/proc/apply_card_vars(obj/item/toy/cards/newobj, obj/item/toy/cards/sourceobj) // Applies variables for supporting multiple types of card deck
if(!istype(sourceobj))
return
@@ -667,7 +658,7 @@
icon = 'icons/obj/toy.dmi'
deckstyle = "nanotrasen"
icon_state = "deck_nanotrasen_full"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
var/obj/machinery/computer/holodeck/holo = null // Holodeck cards should not be infinite
var/list/cards = list()
@@ -740,7 +731,7 @@
if(istype(I, /obj/item/toy/cards/singlecard))
var/obj/item/toy/cards/singlecard/SC = I
if(SC.parentdeck == src)
if(!user.unEquip(SC))
if(!user.temporarilyRemoveItemFromInventory(SC))
user << "<span class='warning'>The card is stuck to your hand, you can't add it to the deck!</span>"
return
cards += SC.cardname
@@ -752,7 +743,7 @@
else if(istype(I, /obj/item/toy/cards/cardhand))
var/obj/item/toy/cards/cardhand/CH = I
if(CH.parentdeck == src)
if(!user.unEquip(CH))
if(!user.temporarilyRemoveItemFromInventory(CH))
user << "<span class='warning'>The hand of cards is stuck to your hand, you can't add it to the deck!</span>"
return
cards += CH.currenthand
@@ -776,12 +767,10 @@
else if(istype(over_object, /obj/screen/inventory/hand))
var/obj/screen/inventory/hand/H = over_object
if(!remove_item_from_storage(M))
M.unEquip(src)
switch(H.slot_id)
if(slot_r_hand)
M.put_in_r_hand(src)
if(slot_l_hand)
M.put_in_l_hand(src)
M.temporarilyRemoveItemFromInventory(src, TRUE)
if(!M.put_in_hand(src, H.held_index))
qdel(src)
return
usr << "<span class='notice'>You pick up the deck.</span>"
else
@@ -794,7 +783,7 @@
desc = "A number of cards not in a deck, customarily held in ones hand."
icon = 'icons/obj/toy.dmi'
icon_state = "nanotrasen_hand2"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/list/currenthand = list()
var/choice = null
@@ -822,7 +811,7 @@
var/mob/living/carbon/human/cardUser = usr
var/O = src
if(href_list["pick"])
if (cardUser.get_item_by_slot(slot_l_hand) == src || cardUser.get_item_by_slot(slot_r_hand) == src)
if (cardUser.is_holding(src))
var/choice = href_list["pick"]
var/obj/item/toy/cards/singlecard/C = new/obj/item/toy/cards/singlecard(cardUser.loc)
src.currenthand -= choice
@@ -831,7 +820,7 @@
C.apply_card_vars(C,O)
C.pickup(cardUser)
cardUser.put_in_hands(C)
cardUser.visible_message("<span class='notice'>[cardUser] draws a card from \his hand.</span>", "<span class='notice'>You take the [C.cardname] from your hand.</span>")
cardUser.visible_message("<span class='notice'>[cardUser] draws a card from [cardUser.p_their()] hand.</span>", "<span class='notice'>You take the [C.cardname] from your hand.</span>")
interact(cardUser)
if(src.currenthand.len < 3)
@@ -845,20 +834,19 @@
N.parentdeck = src.parentdeck
N.cardname = src.currenthand[1]
N.apply_card_vars(N,O)
cardUser.unEquip(src)
qdel(src)
N.pickup(cardUser)
cardUser.put_in_hands(N)
cardUser << "<span class='notice'>You also take [currenthand[1]] and hold it.</span>"
cardUser << browse(null, "window=cardhand")
qdel(src)
return
/obj/item/toy/cards/cardhand/attackby(obj/item/toy/cards/singlecard/C, mob/living/user, params)
if(istype(C))
if(C.parentdeck == src.parentdeck)
src.currenthand += C.cardname
user.unEquip(C)
user.visible_message("[user] adds a card to their hand.", "<span class='notice'>You add the [C.cardname] to your hand.</span>")
user.visible_message("[user] adds a card to [user.p_their()] hand.", "<span class='notice'>You add the [C.cardname] to your hand.</span>")
qdel(C)
interact(user)
if(currenthand.len > 4)
src.icon_state = "[deckstyle]_hand5"
@@ -866,7 +854,6 @@
src.icon_state = "[deckstyle]_hand4"
else if(currenthand.len > 2)
src.icon_state = "[deckstyle]_hand3"
qdel(C)
else
user << "<span class='warning'>You can't mix cards from other decks!</span>"
else
@@ -882,15 +869,14 @@
newobj.card_throw_speed = sourceobj.card_throw_speed
newobj.card_throw_range = sourceobj.card_throw_range
newobj.card_attack_verb = sourceobj.card_attack_verb
if(sourceobj.burn_state == FIRE_PROOF)
newobj.burn_state = FIRE_PROOF
newobj.resistance_flags = sourceobj.resistance_flags
/obj/item/toy/cards/singlecard
name = "card"
desc = "a card"
icon = 'icons/obj/toy.dmi'
icon_state = "singlecard_nanotrasen_down"
w_class = 1
w_class = WEIGHT_CLASS_TINY
var/cardname = null
var/flipped = 0
pixel_x = -5
@@ -899,8 +885,8 @@
/obj/item/toy/cards/singlecard/examine(mob/user)
if(ishuman(user))
var/mob/living/carbon/human/cardUser = user
if(cardUser.get_item_by_slot(slot_l_hand) == src || cardUser.get_item_by_slot(slot_r_hand) == src)
cardUser.visible_message("[cardUser] checks \his card.", "<span class='notice'>The card reads: [src.cardname]</span>")
if(cardUser.is_holding(src))
cardUser.visible_message("[cardUser] checks [cardUser.p_their()] card.", "<span class='notice'>The card reads: [cardname]</span>")
else
cardUser << "<span class='warning'>You need to have the card in your hand to check it!</span>"
@@ -935,12 +921,11 @@
H.currenthand += src.cardname
H.parentdeck = C.parentdeck
H.apply_card_vars(H,C)
user.unEquip(C)
H.pickup(user)
user.put_in_active_hand(H)
user << "<span class='notice'>You combine the [C.cardname] and the [src.cardname] into a hand.</span>"
qdel(C)
qdel(src)
H.pickup(user)
user.put_in_active_hand(H)
else
user << "<span class='warning'>You can't mix cards from other decks!</span>"
@@ -948,8 +933,8 @@
var/obj/item/toy/cards/cardhand/H = I
if(H.parentdeck == parentdeck)
H.currenthand += cardname
user.unEquip(src)
user.visible_message("[user] adds a card to \his hand.", "<span class='notice'>You add the [cardname] to your hand.</span>")
user.visible_message("[user] adds a card to [user.p_their()] hand.", "<span class='notice'>You add the [cardname] to your hand.</span>")
qdel(src)
H.interact(user)
if(H.currenthand.len > 4)
H.icon_state = "[deckstyle]_hand5"
@@ -957,7 +942,6 @@
H.icon_state = "[deckstyle]_hand4"
else if(H.currenthand.len > 2)
H.icon_state = "[deckstyle]_hand3"
qdel(src)
else
user << "<span class='warning'>You can't mix cards from other decks!</span>"
else
@@ -1000,7 +984,7 @@
card_throw_speed = 3
card_throw_range = 7
card_attack_verb = list("attacked", "sliced", "diced", "slashed", "cut")
burn_state = FIRE_PROOF
resistance_flags = 0
/*
* Fake nuke
@@ -1011,7 +995,7 @@
desc = "A plastic model of a Nuclear Fission Explosive."
icon = 'icons/obj/toy.dmi'
icon_state = "nuketoyidle"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/nuke/attack_self(mob/user)
@@ -1035,16 +1019,16 @@
/obj/item/toy/minimeteor
name = "\improper Mini-Meteor"
desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor?"
desc = "Relive the excitement of a meteor shower! SweetMeat-eor. Co is not responsible for any injuries, headaches or hearing loss caused by Mini-Meteor."
icon = 'icons/obj/toy.dmi'
icon_state = "minimeteor"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
/obj/item/toy/minimeteor/throw_impact(atom/hit_atom)
if(!..())
playsound(src, 'sound/effects/meteorimpact.ogg', 40, 1)
for(var/mob/M in urange(10, src))
if(!M.stat && !istype(M, /mob/living/silicon/ai))\
if(!M.stat && !isAI(M))
shake_camera(M, 3, 1)
qdel(src)
@@ -1058,9 +1042,9 @@
icon = 'icons/obj/toy.dmi'
icon_state = "carpplushie"
item_state = "carp_plushie"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
attack_verb = list("bitten", "eaten", "fin slapped")
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
var/bitesound = 'sound/weapons/bite.ogg'
//Attack mob
@@ -1082,7 +1066,7 @@
desc = "A big, plastic red button. Reads 'From HonkCo Pranks?' on the back."
icon = 'icons/obj/assemblies.dmi'
icon_state = "bigred"
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/redbutton/attack_self(mob/user)
@@ -1091,7 +1075,7 @@
user.visible_message("<span class='warning'>[user] presses the big red button.</span>", "<span class='notice'>You press the button, it plays a loud noise!</span>", "<span class='italics'>The button clicks loudly.</span>")
playsound(src, 'sound/effects/explosionfar.ogg', 50, 0, surround = 0)
for(var/mob/M in urange(10, src)) // Checks range
if(!M.stat && !istype(M, /mob/living/silicon/ai)) // Checks to make sure whoever's getting shaken is alive/not the AI
if(!M.stat && !isAI(M)) // Checks to make sure whoever's getting shaken is alive/not the AI
sleep(8) // Short delay to match up with the explosion sound
shake_camera(M, 2, 1) // Shakes player camera 2 squares for 1 second.
@@ -1126,7 +1110,7 @@
icon_state = "ball"
name = "beach ball"
item_state = "beachball"
w_class = 4 //Stops people from hiding it in their bags/pockets
w_class = WEIGHT_CLASS_BULKY //Stops people from hiding it in their bags/pockets
/obj/item/toy/beach_ball/afterattack(atom/target as mob|obj|turf|area, mob/user)
user.drop_item()
@@ -1141,7 +1125,7 @@
icon_state = "toy_xeno"
name = "xenomorph action figure"
desc = "MEGA presents the new Xenos Isolated action figure! Comes complete with realistic sounds! Pull back string to use."
w_class = 2
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
/obj/item/toy/toy_xeno/attack_self(mob/user)
@@ -1168,9 +1152,9 @@
desc = "A colorful toy mouse!"
icon = 'icons/obj/toy.dmi'
icon_state = "toy_mouse"
w_class = 2.0
w_class = WEIGHT_CLASS_SMALL
var/cooldown = 0
burn_state = FLAMMABLE
resistance_flags = FLAMMABLE
/*
@@ -1188,6 +1172,7 @@
/obj/item/toy/figure/New()
desc = "A \"Space Life\" brand [src]."
..()
/obj/item/toy/figure/attack_self(mob/user as mob)
if(cooldown <= world.time)
@@ -1224,7 +1209,7 @@
/obj/item/toy/figure/botanist
name = "Botanist action figure"
icon_state = "botanist"
toysay = "Dude, I see colors..."
toysay = "Blaze it!"
/obj/item/toy/figure/captain
name = "Captain action figure"
@@ -1249,7 +1234,7 @@
/obj/item/toy/figure/chef
name = "Chef action figure"
icon_state = "chef"
toysay = "Pun-Pun is a tasty burger."
toysay = " I'll make you into a burger!"
/obj/item/toy/figure/chemist
name = "Chemist action figure"
@@ -1275,7 +1260,7 @@
/obj/item/toy/figure/dsquad
name = "Death Squad Officer action figure"
icon_state = "dsquad"
toysay = "Eliminate all threats!"
toysay = "Kill em all!"
/obj/item/toy/figure/engineer
name = "Engineer action figure"
@@ -1288,14 +1273,14 @@
toysay = "Smash!"
/obj/item/toy/figure/hop
name = "Head of Personel action figure"
name = "Head of Personnel action figure"
icon_state = "hop"
toysay = "Giving out all access!"
/obj/item/toy/figure/hos
name = "Head of Security action figure"
icon_state = "hos"
toysay = "Get the justice chamber ready, I think we got a joker here."
toysay = "Go ahead, make my day."
/obj/item/toy/figure/qm
name = "Quartermaster action figure"
@@ -1331,7 +1316,7 @@
/obj/item/toy/figure/miner
name = "Shaft Miner action figure"
icon_state = "miner"
toysay = "Oh god it's eating my intestines!"
toysay = "COLOSSUS RIGHT OUTSIDE THE BASE!"
/obj/item/toy/figure/ninja
name = "Ninja action figure"
@@ -1358,7 +1343,7 @@
/obj/item/toy/figure/scientist
name = "Scientist action figure"
icon_state = "scientist"
toysay = "For science!"
toysay = "I call toxins."
toysound = 'sound/effects/explosionfar.ogg'
/obj/item/toy/figure/syndie
@@ -1381,3 +1366,29 @@
name = "Warden action figure"
icon_state = "warden"
toysay = "Seventeen minutes for coughing at an officer!"
/obj/item/toy/dummy
name = "ventriloquist dummy"
desc = "It's a dummy, dummy."
icon = 'icons/obj/toy.dmi'
icon_state = "assistant"
item_state = "doll"
var/doll_name = "Dummy"
//Add changing looks when i feel suicidal about making 20 inhands for these.
/obj/item/toy/dummy/attack_self(mob/user)
var/new_name = stripped_input(usr,"What would you like to name the dummy?","Input a name",doll_name,MAX_NAME_LEN)
if(!new_name)
return
doll_name = new_name
user << "You name the dummy as \"[doll_name]\""
name = "[initial(name)] - [doll_name]"
/obj/item/toy/dummy/talk_into(atom/movable/M, message, channel, list/spans)
log_say("[key_name(M)] : through dummy : [message]")
say(message)
return NOPASS
/obj/item/toy/dummy/GetVoice()
return doll_name

Some files were not shown because too many files have changed in this diff Show More