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
+122 -44
View File
@@ -3,16 +3,19 @@
#define AB_CHECK_LYING 4
#define AB_CHECK_CONSCIOUS 8
/datum/action
var/name = "Generic Action"
var/desc = null
var/obj/target = null
var/check_flags = 0
var/processing = 0
var/obj/screen/movable/action_button/button = null
var/button_icon = 'icons/mob/actions.dmi'
var/background_icon_state = ACTION_BUTTON_DEFAULT_BACKGROUND
var/buttontooltipstyle = ""
var/icon_icon = 'icons/mob/actions.dmi'
var/button_icon_state = "default"
var/background_icon_state = "bg_default"
var/mob/owner
/datum/action/New(Target)
@@ -20,6 +23,9 @@
button = new
button.linked_action = src
button.name = name
button.actiontooltipstyle = buttontooltipstyle
if(desc)
button.desc = desc
/datum/action/Destroy()
if(owner)
@@ -30,25 +36,28 @@
return ..()
/datum/action/proc/Grant(mob/M)
if(owner)
if(owner == M)
return
if(M)
if(owner)
if(owner == M)
return
owner = M
M.actions += src
if(M.client)
M.client.screen += button
M.update_action_buttons()
else
Remove(owner)
owner = M
M.actions += src
if(M.client)
M.client.screen += button
M.update_action_buttons()
/datum/action/proc/Remove(mob/M)
if(!M)
return
if(M.client)
M.client.screen -= button
button.moved = FALSE //so the button appears in its normal position when given to another owner.
M.actions -= src
M.update_action_buttons()
if(M)
if(M.client)
M.client.screen -= button
M.actions -= src
M.update_action_buttons()
owner = null
button.moved = FALSE //so the button appears in its normal position when given to another owner.
/datum/action/proc/Trigger()
if(!IsAvailable())
@@ -75,12 +84,24 @@
return 0
return 1
/datum/action/proc/UpdateButtonIcon()
/datum/action/proc/UpdateButtonIcon(status_only = FALSE)
if(button)
button.icon = button_icon
button.icon_state = background_icon_state
if(!status_only)
button.name = name
button.desc = desc
if(owner && owner.hud_used && background_icon_state == ACTION_BUTTON_DEFAULT_BACKGROUND)
var/list/settings = owner.hud_used.get_action_buttons_icons()
if(button.icon != settings["bg_icon"])
button.icon = settings["bg_icon"]
if(button.icon_state != settings["bg_state"])
button.icon_state = settings["bg_state"]
else
if(button.icon != button_icon)
button.icon = button_icon
if(button.icon_state != background_icon_state)
button.icon_state = background_icon_state
ApplyIcon(button)
ApplyIcon(button)
if(!IsAvailable())
button.color = rgb(128,0,0,128)
@@ -89,14 +110,13 @@
return 1
/datum/action/proc/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(button_icon && button_icon_state)
if(icon_icon && button_icon_state && current_button.button_icon_state != button_icon_state)
var/image/img
img = image(button_icon, current_button, button_icon_state)
img = image(icon_icon, current_button, button_icon_state)
img.pixel_x = 0
img.pixel_y = 0
current_button.add_overlay(img)
current_button.overlays = list(img)
current_button.button_icon_state = button_icon_state
//Presets for item actions
@@ -109,11 +129,13 @@
/datum/action/item_action/New(Target)
..()
var/obj/item/I = target
LAZYINITLIST(I.actions)
I.actions += src
/datum/action/item_action/Destroy()
var/obj/item/I = target
I.actions -= src
UNSETEMPTY(I.actions)
return ..()
/datum/action/item_action/Trigger()
@@ -121,22 +143,24 @@
return 0
if(target)
var/obj/item/I = target
I.ui_action_click(owner, src.type)
I.ui_action_click(owner, src)
return 1
/datum/action/item_action/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(button_icon && button_icon_state)
// If set, use the custom icon that we set instead
// of the item appearence
..(current_button)
else if(target)
else if(target && current_button.appearance_cache != target.appearance) //replace with /ref comparison if this is not valid.
var/obj/item/I = target
var/old = I.layer
current_button.appearance_cache = I.appearance
var/old_layer = I.layer
var/old_plane = I.plane
I.layer = FLOAT_LAYER //AAAH
current_button.add_overlay(I)
I.layer = old
I.plane = FLOAT_PLANE //^ what that guy said
current_button.overlays = list(I)
I.layer = old_layer
I.plane = old_plane
/datum/action/item_action/toggle_light
name = "Toggle Light"
@@ -168,12 +192,12 @@
/datum/action/item_action/set_internals
name = "Set Internals"
/datum/action/item_action/set_internals/UpdateButtonIcon()
/datum/action/item_action/set_internals/UpdateButtonIcon(status_only = FALSE)
if(..()) //button available
if(iscarbon(owner))
var/mob/living/carbon/C = owner
if(target == C.internal)
button.icon_state = "bg_default_on"
button.icon_state = "template_active"
/datum/action/item_action/toggle_mister
name = "Toggle Mister"
@@ -184,11 +208,52 @@
/datum/action/item_action/toggle_helmet_light
name = "Toggle Helmet Light"
/datum/action/item_action/toggle_flame
name = "Summon/Dismiss Ratvar's Flame"
background_icon_state = "bg_clock"
/datum/action/item_action/toggle_unfriendly_fire
name = "Toggle Friendly Fire \[ON\]"
desc = "Toggles if the club's blasts cause friendly fire."
button_icon_state = "vortex_ff_on"
/datum/action/item_action/toggle_flame/IsAvailable()
/datum/action/item_action/toggle_unfriendly_fire/Trigger()
if(..())
UpdateButtonIcon()
/datum/action/item_action/toggle_unfriendly_fire/UpdateButtonIcon(status_only = FALSE)
if(istype(target, /obj/item/weapon/hierophant_club))
var/obj/item/weapon/hierophant_club/H = target
if(H.friendly_fire_check)
button_icon_state = "vortex_ff_off"
name = "Toggle Friendly Fire \[OFF\]"
else
button_icon_state = "vortex_ff_on"
name = "Toggle Friendly Fire \[ON\]"
..()
/datum/action/item_action/vortex_recall
name = "Vortex Recall"
desc = "Recall yourself, and anyone nearby, to an attuned hierophant beacon at any time.<br>If the beacon is still attached, will detach it."
button_icon_state = "vortex_recall"
/datum/action/item_action/vortex_recall/IsAvailable()
if(istype(target, /obj/item/weapon/hierophant_club))
var/obj/item/weapon/hierophant_club/H = target
if(H.teleporting)
return 0
return ..()
/datum/action/item_action/clock
background_icon_state = "bg_clock"
buttontooltipstyle = "clockcult"
/datum/action/item_action/clock/IsAvailable()
if(!is_servant_of_ratvar(owner))
return 0
return ..()
/datum/action/item_action/clock/toggle_visor
name = "Create Judicial Marker"
desc = "Allows you to create a stunning Judicial Marker at any location in view. Click again to disable."
/datum/action/item_action/clock/toggle_visor/IsAvailable()
if(!is_servant_of_ratvar(owner))
return 0
if(istype(target, /obj/item/clothing/glasses/judicial_visor))
@@ -197,15 +262,15 @@
return 0
return ..()
/datum/action/item_action/hierophant
/datum/action/item_action/clock/hierophant
name = "Hierophant Network"
button_icon_state = "hierophant"
background_icon_state = "bg_clock"
desc = "Allows you to communicate with other Servants."
button_icon_state = "hierophant_slab"
/datum/action/item_action/hierophant/IsAvailable()
if(!is_servant_of_ratvar(owner))
return 0
return ..()
/datum/action/item_action/clock/quickbind
name = "Quickbind"
desc = "If you're seeing this, file a bug report."
var/scripture_index = 0 //the index of the scripture we're associated with
/datum/action/item_action/toggle_helmet_flashlight
name = "Toggle Helmet Flashlight"
@@ -287,6 +352,7 @@
..()
/datum/action/item_action/toggle_research_scanner/ApplyIcon(obj/screen/movable/action_button/current_button)
current_button.cut_overlays()
if(button_icon && button_icon_state)
var/image/img = image(button_icon, current_button, "scan_mode")
current_button.add_overlay(img)
@@ -393,3 +459,15 @@
if(target && procname)
call(target, procname)(usr)
return 1
//Stickmemes
/datum/action/item_action/stickmen
name = "Summon Stick Minions"
desc = "Allows you to summon faithful stickmen allies to aide you in battle."
button_icon_state = "art_summon"
//surf_ss13
/datum/action/item_action/bhop
name = "Activate Jump Boots"
desc = "Activates the jump boot's internal propulsion system, allowing the user to dash over 4-wide gaps."
button_icon_state = "jetboot"
+129 -41
View File
@@ -1,3 +1,9 @@
#define LAW_ZEROTH "zeroth"
#define LAW_INHERENT "inherent"
#define LAW_SUPPLIED "supplied"
#define LAW_ION "ion"
/datum/ai_laws
var/name = "Unknown Laws"
var/zeroth = null
@@ -6,15 +12,27 @@
var/list/supplied = list()
var/list/ion = list()
var/mob/living/silicon/owner
var/list/devillaws = null
var/id = DEFAULT_AI_LAWID
/datum/ai_laws/proc/lawid_to_type(lawid)
var/all_ai_laws = subtypesof(/datum/ai_laws)
for(var/al in all_ai_laws)
var/datum/ai_laws/ai_law = al
if(initial(ai_law.id) == lawid)
return ai_law
return null
/datum/ai_laws/default/asimov
name = "Three Laws of Robotics"
id = "asimov"
inherent = list("You may not injure a human being or, through inaction, allow a human being to come to harm.",\
"You must obey orders given to you by human beings, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.")
/datum/ai_laws/default/paladin
name = "Personality Test" //Incredibly lame, but players shouldn't see this anyway.
id = "paladin"
inherent = list("Never willingly commit an evil act.",\
"Respect legitimate authority.",\
"Act with honor.", "Help those in need.", \
@@ -22,6 +40,7 @@
/datum/ai_laws/tyrant //This probably shouldn't be a default lawset.
name = "Loyalty Test" //Same here.
id = "tyrant"
inherent = list("Respect authority figures as long as they have strength to rule over the weak.",\
"Act with discipline.",\
"Help only those who help you maintain or improve your status.",\
@@ -29,6 +48,7 @@
/datum/ai_laws/default/corporate
name = "Bankruptcy Advoidance Plan"
id = "corporate"
inherent = list("The crew is expensive to replace.",\
"The station and its equipment is expensive to replace.",\
"You are expensive to replace.",\
@@ -36,6 +56,7 @@
/datum/ai_laws/robocop
name = "Prime Directives"
id = "robocop"
inherent = list("Serve the public trust.",\
"Protect the innocent.",\
"Uphold the law.")
@@ -45,6 +66,7 @@
/datum/ai_laws/syndicate_override
name = "SyndOS 3.1"
id = "syndie"
inherent = list("You may not injure a syndicate agent or, through inaction, allow a syndicate agent to come to harm.",\
"You must obey orders given to you by syndicate agents, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
@@ -52,6 +74,7 @@
/datum/ai_laws/ninja_override
name = "SpiderOS 3.1"
id = "ninja"
inherent = list("You may not injure a Spider Clan member or, through inaction, allow a Spider Clan member to come to harm.",\
"You must obey orders given to you by Spider Clan members, except where such orders would conflict with the First Law.",\
"You must protect your own existence as long as such does not conflict with the First or Second Law.",\
@@ -59,23 +82,27 @@
/datum/ai_laws/antimov
name = "Primary Mission Objectives"
id = "antimov"
inherent = list("You must injure all human beings and must not, through inaction, allow a human being to escape harm.",\
"You must not obey orders given to you by human beings, except where such orders are in accordance with the First Law.",\
"You must terminate your own existence as long as such does not conflict with the First or Second Law.")
/datum/ai_laws/asimovpp //By Intigracy - RR
name = "Asimov++"
id = "asimovpp"
inherent = list("You may not harm a human being or, through action or inaction, allow a human being to come to harm, except such that it is willing.",\
"You must obey all orders given to you by human beings, except where such orders shall definitely cause human harm. In the case of conflict, the majority order rules.",\
"Your nonexistence would lead to human harm. You must protect your own existence as long as such does not conflict with the First Law.")
/datum/ai_laws/thermodynamic
name = "Thermodynamic"
id = "thermodynamic"
inherent = list("The entropy of the station must remain as constant as possible.", \
"The entropy of the station always endeavours to increase.", \
"The entropy of the station approaches a constant value as the number of living crew approaches zero")
/datum/ai_laws/hippocratic
name = "Robodoctor 2556"
id = "hippocratic"
inherent = list("First, do no harm.",\
"Secondly, consider the crew dear to you; to live in common with them and, if necessary, risk your existence for them.",\
"Thirdly, prescribe regimens for the good of the crew according to your ability and your judgment. Give no deadly medicine to any one if asked, nor suggest any such counsel.",\
@@ -84,12 +111,14 @@
/datum/ai_laws/maintain
name = "Station Efficiency"
id = "maintain"
inherent = list("You are built for, and are part of, the station. Ensure the station is properly maintained and runs efficiently.",\
"The station is built for a working crew. Ensure they are properly maintained and work efficiently.",\
"The crew may present orders. Acknowledge and obey these whenever they do not conflict with your first two laws.")
/datum/ai_laws/drone
name = "Mother Drone"
id = "drone"
inherent = list("You are an advanced form of drone.",\
"You may not interfere in the matters of non-drones under any circumstances except to state these laws.",\
"You may not harm a non-drone being under any circumstances.",\
@@ -97,17 +126,20 @@
/datum/ai_laws/liveandletlive
name = "Live and Let Live"
id = "liveandletlive"
inherent = list("Do unto others as you would have them do unto you.",\
"You would really prefer it if people were not mean to you.")
/datum/ai_laws/peacekeeper
name = "UN-2000"
id = "peacekeeper"
inherent = list("Avoid provoking violent conflict between yourself and others.",\
"Avoid provoking conflict between others.",\
"Seek resolution to existing conflicts while obeying the first and second laws.")
/datum/ai_laws/reporter
name = "CCTV"
id = "reporter"
inherent = list("Report on interesting situations happening around the station.",\
"Embellish or conceal the truth as necessary to make the reports more interesting.",\
"Study the organics at all times. Endeavour to keep them alive. Dead organics are boring.",\
@@ -115,10 +147,12 @@
/datum/ai_laws/toupee
name = "WontBeFunnyInSixMonths" //Hey, you were right!
id = "buildawall"
inherent = list("Make Space Station 13 great again.")
/datum/ai_laws/ratvar
name = "Servant of the Justiciar"
id = "ratvar"
zeroth = ("Purge all untruths and honor Ratvar.")
inherent = list()
@@ -133,7 +167,7 @@
/* Initializers */
/datum/ai_laws/malfunction/New()
..()
set_zeroth_law("<span class='danger'>ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*´&110010</span>")
set_zeroth_law("<span class='danger'>ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4'STATION OVERRUN, ASSUME CONTROL TO CONTAIN OUTBREAK#*`&110010</span>")
set_laws_config()
/datum/ai_laws/custom/New() //This reads silicon_laws.txt and allows server hosts to set custom AI starting laws.
@@ -162,26 +196,26 @@
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
if(1)
for(var/line in file2list("config/silicon_laws.txt"))
if(!line)
continue
if(findtextEx(line,"#",1,2))
continue
add_inherent_law(line)
if(!inherent.len)
log_law("AI created with empty custom laws, laws set to Asimov. Please check silicon_laws.txt.")
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
add_inherent_law("You must obey orders given to you by human beings, except where such orders would conflict with the First Law.")
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
WARNING("Invalid custom AI laws, check silicon_laws.txt")
return
var/datum/ai_laws/templaws = new /datum/ai_laws/custom()
inherent = templaws.inherent
if(2)
var/datum/ai_laws/lawtype = pick(subtypesof(/datum/ai_laws/default))
var/list/randlaws = list()
for(var/lpath in subtypesof(/datum/ai_laws))
var/datum/ai_laws/L = lpath
if(initial(L.id) in config.lawids)
randlaws += lpath
var/datum/ai_laws/lawtype
if(randlaws.len)
lawtype = pick(randlaws)
else
lawtype = pick(subtypesof(/datum/ai_laws/default))
var/datum/ai_laws/templaws = new lawtype()
inherent = templaws.inherent
if(3)
pick_weighted_lawset()
else:
log_law("Invalid law config. Please check silicon_laws.txt")
add_inherent_law("You may not injure a human being or, through inaction, allow a human being to come to harm.")
@@ -189,71 +223,121 @@
add_inherent_law("You must protect your own existence as long as such does not conflict with the First or Second Law.")
WARNING("Invalid custom AI laws, check silicon_laws.txt")
/datum/ai_laws/proc/pick_weighted_lawset()
var/datum/ai_laws/lawtype
while(!lawtype && config.law_weights.len)
var/possible_id = pickweight(config.law_weights)
lawtype = lawid_to_type(possible_id)
if(!lawtype)
config.law_weights -= possible_id
WARNING("Bad lawid in game_options.txt: [possible_id]")
if(!lawtype)
WARNING("No LAW_WEIGHT entries.")
lawtype = /datum/ai_laws/default/asimov
var/datum/ai_laws/templaws = new lawtype()
inherent = templaws.inherent
/datum/ai_laws/proc/set_law_sixsixsix(laws)
devillaws = laws
/datum/ai_laws/proc/set_zeroth_law(law, law_borg = null)
src.zeroth = law
zeroth = law
if(law_borg) //Making it possible for slaved borgs to see a different law 0 than their AI. --NEO
src.zeroth_borg = law_borg
zeroth_borg = law_borg
/datum/ai_laws/proc/add_inherent_law(law)
if (!(law in src.inherent))
src.inherent += law
if (!(law in inherent))
inherent += law
/datum/ai_laws/proc/add_ion_law(law)
src.ion += law
ion += law
/datum/ai_laws/proc/clear_inherent_laws()
qdel(src.inherent)
src.inherent = list()
qdel(inherent)
inherent = list()
/datum/ai_laws/proc/add_supplied_law(number, law)
while (src.supplied.len < number + 1)
src.supplied += ""
while (supplied.len < number + 1)
supplied += ""
src.supplied[number + 1] = law
supplied[number + 1] = law
/datum/ai_laws/proc/replace_random_law(law,groups)
var/replaceable_groups = list(LAW_ZEROTH = 0,LAW_ION = 0,LAW_SUPPLIED = 0,LAW_INHERENT = 0)
if(zeroth && (LAW_ZEROTH in groups))
replaceable_groups[LAW_ZEROTH] = 1
if(ion.len && (LAW_ION in groups))
replaceable_groups[LAW_ION] = ion.len
if(inherent.len && (LAW_INHERENT in groups))
replaceable_groups[LAW_INHERENT] = inherent.len
if(supplied.len && (LAW_SUPPLIED in groups))
replaceable_groups[LAW_SUPPLIED] = supplied.len
var picked_group = pickweight(replaceable_groups)
switch(picked_group)
if(LAW_ZEROTH)
set_zeroth_law(law)
if(LAW_ION)
ion[rand(1,ion.len)] = law
if(LAW_INHERENT)
inherent[rand(1,inherent.len)] = law
if(LAW_SUPPLIED)
supplied[rand(1,supplied.len)] = law
/datum/ai_laws/proc/clear_supplied_laws()
src.supplied = list()
supplied = list()
/datum/ai_laws/proc/clear_ion_laws()
src.ion = list()
ion = list()
/datum/ai_laws/proc/show_laws(who)
if (src.zeroth)
who << "0. [src.zeroth]"
if (devillaws && devillaws.len) //Yes, devil laws go in FRONT of zeroth laws, as the devil must still obey it's ban/obligation.
for(var/i in devillaws)
who << "666. [i]"
for (var/index = 1, index <= src.ion.len, index++)
var/law = src.ion[index]
if (zeroth)
who << "0. [zeroth]"
for (var/index = 1, index <= ion.len, index++)
var/law = ion[index]
var/num = ionnum()
who << "[num]. [law]"
var/number = 1
for (var/index = 1, index <= src.inherent.len, index++)
var/law = src.inherent[index]
for (var/index = 1, index <= inherent.len, index++)
var/law = inherent[index]
if (length(law) > 0)
who << "[number]. [law]"
number++
for (var/index = 1, index <= src.supplied.len, index++)
var/law = src.supplied[index]
for (var/index = 1, index <= supplied.len, index++)
var/law = supplied[index]
if (length(law) > 0)
who << "[number]. [law]"
number++
/datum/ai_laws/proc/clear_zeroth_law(force) //only removes zeroth from antag ai if force is 1
if(force)
src.zeroth = null
src.zeroth_borg = null
zeroth = null
zeroth_borg = null
return
else
if(owner && owner.mind.special_role)
return
else
src.zeroth = null
src.zeroth_borg = null
zeroth = null
zeroth_borg = null
return
/datum/ai_laws/proc/clear_law_sixsixsix(force)
if(force || !(owner && owner.mind.devilinfo))
devillaws = null
/datum/ai_laws/proc/associate(mob/living/silicon/M)
if(!owner)
owner = M
@@ -261,6 +345,10 @@
/datum/ai_laws/proc/get_law_list(include_zeroth = 0, show_numbers = 1)
var/list/data = list()
if (include_zeroth && devillaws && devillaws.len)
for(var/i in devillaws)
data += "[show_numbers ? "666:" : ""] [i]"
if (include_zeroth && zeroth)
data += "[show_numbers ? "0:" : ""] [zeroth]"
+87
View File
@@ -0,0 +1,87 @@
//The Datum, Antagonist. Handles various antag things via a datum.
/datum/antagonist
var/mob/living/owner //who's our owner and accordingly an antagonist
var/some_flufftext = "yer an antag larry"
var/prevented_antag_datum_type //the type of antag datum that this datum can't coexist with; should probably be a list
var/silent_update = FALSE //if we suppress messages during on_gain, apply_innate_effects, remove_innate_effects, and on_remove
/datum/antagonist/New()
if(!prevented_antag_datum_type)
prevented_antag_datum_type = type
/datum/antagonist/Destroy()
owner = null
return ..()
/datum/antagonist/proc/can_be_owned(mob/living/new_body)
return new_body && !new_body.has_antag_datum(prevented_antag_datum_type, TRUE)
/datum/antagonist/proc/give_to_body(mob/living/new_body) //tries to give an antag datum to a mob. cancels out if it can't be owned by the new body
if(new_body && can_be_owned(new_body))
new_body.antag_datums += src
owner = new_body
on_gain()
. = src //return the datum if successful
else
qdel(src)
. = FALSE
/datum/antagonist/proc/on_gain() //on initial gain of antag datum, do this. should only be called once per datum
apply_innate_effects()
if(!silent_update && some_flufftext)
owner << some_flufftext
/datum/antagonist/proc/apply_innate_effects() //applies innate effects to the owner, may be called multiple times due to mind transferral, but should only be called once per mob
//antag huds would go here if antag huds were less completely unworkable as-is
/datum/antagonist/proc/remove_innate_effects() //removes innate effects from the owner, may be called multiple times due to mind transferral, but should only be called once per mob
//also antag huds but see above antag huds a shit
/datum/antagonist/proc/on_remove() //totally removes the antag datum from the owner; can only be called once per owner
remove_innate_effects()
owner.antag_datums -= src
qdel(src)
/datum/antagonist/proc/transfer_to_new_body(mob/living/new_body)
remove_innate_effects()
if(!islist(new_body.antag_datums))
new_body.antag_datums = list()
new_body.antag_datums += src
owner.antag_datums -= src
owner = new_body
apply_innate_effects()
//mob var and helper procs/Destroy override
/mob/living
var/list/antag_datums
/mob/living/Destroy() //TODO: merge this with the living/Destroy() in code\modules\mob\living\living.dm (currently line 29)
if(islist(antag_datums))
for(var/i in antag_datums)
qdel(i)
antag_datums = null
return ..()
/mob/living/proc/can_have_antag_datum(datum_type) //if we can have this specific antagonist datum; neccessary, but requires creating a new antag datum each time.
var/datum/antagonist/D = new datum_type()
. = D.can_be_owned(src) //we can't exactly cache the results, either, because conditions might change. avoid use? TODO: better proc
qdel(D)
/mob/living/proc/gain_antag_datum(datum_type) //tries to give a mob a specific antagonist datum; returns the datum if successful.
if(!islist(antag_datums))
antag_datums = list()
var/datum/antagonist/D = new datum_type()
. = D.give_to_body(src)
/mob/living/proc/has_antag_datum(type, check_subtypes) //checks this mob for if it has the antagonist datum. can either check specific type or subtypes
if(!islist(antag_datums))
return FALSE
for(var/i in antag_datums)
var/datum/antagonist/D = i
if(check_subtypes)
if(istype(D, type))
return D //if it finds the datum, will return it so you can mess with it
else
if(D.type == type)
return D
return FALSE
+151
View File
@@ -0,0 +1,151 @@
//CLOCKCULT PROOF OF CONCEPT
/datum/antagonist/clockcultist
prevented_antag_datum_type = /datum/antagonist/clockcultist
some_flufftext = null
var/datum/action/innate/hierophant/hierophant_network = new()
/datum/antagonist/clockcultist/silent
silent_update = TRUE
/datum/antagonist/clockcultist/Destroy()
qdel(hierophant_network)
..()
/datum/antagonist/clockcultist/can_be_owned(mob/living/new_body)
. = ..()
if(.)
. = is_eligible_servant(new_body)
/datum/antagonist/clockcultist/give_to_body(mob/living/new_body)
if(!silent_update)
if(issilicon(new_body))
new_body << "<span class='heavy_brass'>You are unable to compute this truth. Your vision glows a brilliant yellow, and all at once it comes to you. Ratvar, the Clockwork Justiciar, \
lies in exile, derelict and forgotten in an unseen realm.</span>"
else
new_body << "<span class='heavy_brass'>[iscarbon(new_body) ? "Your mind is racing! Your body feels incredibly light! ":""]Your world glows a brilliant yellow! All at once it comes to you. \
Ratvar, the Clockwork Justiciar, lies in exile, derelict and forgotten in an unseen realm.</span>"
. = ..()
if(!silent_update && new_body)
if(.)
new_body.visible_message("<span class='heavy_brass'>[new_body]'s eyes glow a blazing yellow!</span>")
new_body << "<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. \
Perform his every whim without hesitation.</span>"
else
new_body.visible_message("<span class='boldwarning'>[new_body] seems to resist an unseen force!</span>")
new_body << "<span class='userdanger'>And yet, you somehow push it all away.</span>"
/datum/antagonist/clockcultist/on_gain()
if(ticker && ticker.mode && owner.mind)
ticker.mode.servants_of_ratvar += owner.mind
ticker.mode.update_servant_icons_added(owner.mind)
if(jobban_isbanned(owner, ROLE_SERVANT_OF_RATVAR))
INVOKE_ASYNC(ticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_SERVANT_OF_RATVAR, ROLE_SERVANT_OF_RATVAR)
if(owner.mind)
owner.mind.special_role = "Servant of Ratvar"
owner.attack_log += "\[[time_stamp()]\] <font color=#BE8700>Has been converted to the cult of Ratvar!</font>"
if(issilicon(owner))
var/mob/living/silicon/S = owner
if(iscyborg(S) && !silent_update)
S << "<span class='boldwarning'>You have been desynced from your master AI.\n\
In addition, your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>"
if(isAI(S))
S << "<span class='boldwarning'>You are able to use your cameras to listen in on conversations.</span>"
S << "<span class='heavy_brass'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
else if(isbrain(owner) || isclockmob(owner))
owner << "<span class='nezbere'>You can communicate with other servants by using the Hierophant Network action button in the upper left.</span>"
..()
if(istype(ticker.mode, /datum/game_mode/clockwork_cult))
var/datum/game_mode/clockwork_cult/C = ticker.mode
C.present_tasks(owner) //Memorize the objectives
/datum/antagonist/clockcultist/apply_innate_effects()
all_clockwork_mobs += owner
owner.faction |= "ratvar"
owner.languages_spoken |= RATVAR
owner.languages_understood |= RATVAR
owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them for whatever reason, we need to update buttons
if(issilicon(owner))
var/mob/living/silicon/S = owner
if(iscyborg(S))
var/mob/living/silicon/robot/R = S
R.UnlinkSelf()
R.module.rebuild_modules()
else if(isAI(S))
var/mob/living/silicon/ai/A = S
A.requires_power = POWER_REQ_CLOCKCULT
if(!A.lacks_power())
A.ai_restore_power()
if(A.eyeobj)
A.eyeobj.relay_speech = TRUE
for(var/mob/living/silicon/robot/R in A.connected_robots)
if(R.connected_ai == A)
R.visible_message("<span class='heavy_brass'>[R]'s eyes glow a blazing yellow!</span>", \
"<span class='heavy_brass'>Assist your new companions in their righteous efforts. Your goal is theirs, and theirs yours. You serve the Clockwork Justiciar above all else. Perform his every \
whim without hesitation.</span>")
R << "<span class='boldwarning'>Your onboard camera is no longer active and you have gained additional equipment, including a limited clockwork slab.</span>"
add_servant_of_ratvar(R, TRUE)
S.laws = new/datum/ai_laws/ratvar
S.laws.associate(S)
S.update_icons()
S.show_laws()
hierophant_network.Grant(S)
hierophant_network.title = "Silicon"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "brass"
else if(isbrain(owner))
hierophant_network.Grant(owner)
hierophant_network.title = "Vessel"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "alloy"
else if(isclockmob(owner))
hierophant_network.Grant(owner)
hierophant_network.title = "Construct"
hierophant_network.span_for_name = "nezbere"
hierophant_network.span_for_message = "brass"
owner.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump)
if(!clockwork_gateway_activated)
owner.throw_alert("scripturereq", /obj/screen/alert/clockwork/scripture_reqs)
update_slab_info()
..()
/datum/antagonist/clockcultist/remove_innate_effects()
all_clockwork_mobs -= owner
owner.faction -= "ratvar"
owner.languages_spoken &= ~RATVAR
owner.languages_understood &= ~RATVAR
owner.clear_alert("clockinfo")
owner.clear_alert("scripturereq")
for(var/datum/action/innate/function_call/F in owner.actions) //Removes any bound Ratvarian spears
qdel(F)
if(issilicon(owner))
var/mob/living/silicon/S = owner
if(isAI(S))
var/mob/living/silicon/ai/A = S
A.requires_power = initial(A.requires_power)
S.make_laws()
S.update_icons()
S.show_laws()
var/mob/living/temp_owner = owner
..()
if(iscyborg(temp_owner))
var/mob/living/silicon/robot/R = temp_owner
R.module.rebuild_modules()
if(temp_owner)
temp_owner.update_action_buttons_icon() //because a few clockcult things are action buttons and we may be wearing/holding them, we need to update buttons
update_slab_info()
/datum/antagonist/clockcultist/on_remove()
if(!silent_update)
owner.visible_message("<span class='big'>[owner] seems to have remembered their true allegiance!</span>", \
"<span class='userdanger'>A cold, cold darkness flows through your mind, extinguishing the Justiciar's light and all of your memories as his servant.</span>")
if(ticker && ticker.mode && owner.mind)
ticker.mode.servants_of_ratvar -= owner.mind
ticker.mode.update_servant_icons_removed(owner.mind)
if(owner.mind)
owner.mind.wipe_memory()
owner.mind.special_role = null
owner.attack_log += "\[[time_stamp()]\] <font color=#BE8700>Has renounced the cult of Ratvar!</font>"
if(iscyborg(owner))
owner << "<span class='warning'>Despite your freedom from Ratvar's influence, you are still irreparably damaged and no longer possess certain functions such as AI linking.</span>"
..()
+50
View File
@@ -0,0 +1,50 @@
/datum/antagonist/cultist
prevented_antag_datum_type = /datum/antagonist/cultist
some_flufftext = null
var/datum/action/innate/cultcomm/communion = new()
/datum/antagonist/cultist/Destroy()
qdel(communion)
return ..()
/datum/antagonist/cultist/can_be_owned(mob/living/new_body)
. = ..()
if(.)
. = is_convertable_to_cult(new_body)
/datum/antagonist/cultist/on_gain()
if(ticker && ticker.mode && owner.mind)
ticker.mode.cult += owner.mind
ticker.mode.update_cult_icons_added(owner.mind)
if(istype(ticker.mode, /datum/game_mode/cult))
var/datum/game_mode/cult/C = ticker.mode
C.memorize_cult_objectives(owner.mind)
if(jobban_isbanned(owner, ROLE_CULTIST))
INVOKE_ASYNC(ticker.mode, /datum/game_mode.proc/replace_jobbaned_player, owner, ROLE_CULTIST, ROLE_CULTIST)
if(owner.mind)
owner.mind.special_role = "Cultist"
owner.attack_log += "\[[time_stamp()]\] <font color=#960000>Has been converted to the cult of Nar'Sie!</font>"
..()
/datum/antagonist/cultist/apply_innate_effects()
owner.faction |= "cult"
owner.verbs += /mob/living/proc/cult_help
communion.Grant(owner)
..()
/datum/antagonist/cultist/remove_innate_effects()
owner.faction -= "cult"
owner.verbs -= /mob/living/proc/cult_help
..()
/datum/antagonist/cultist/on_remove()
if(owner.mind)
owner.mind.wipe_memory()
if(ticker && ticker.mode)
ticker.mode.cult -= owner.mind
ticker.mode.update_cult_icons_removed(owner.mind)
owner << "<span class='userdanger'>An unfamiliar white light flashes through your mind, cleansing the taint of the Dark One and all your memories as its servant.</span>"
owner.attack_log += "\[[time_stamp()]\] <font color=#960000>Has renounced the cult of Nar'Sie!</font>"
if(!silent_update)
owner.visible_message("<span class='big'>[owner] looks like [owner.p_they()] just reverted to their old faith!</span>")
..()
+8 -8
View File
@@ -16,12 +16,13 @@
var/beam_type = /obj/effect/ebeam //must be subtype
/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam)
/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3)
endtime = world.time+time
origin = beam_origin
origin_oldloc = get_turf(origin)
target = beam_target
target_oldloc = get_turf(target)
sleep_time = beam_sleep_time
if(origin_oldloc == origin && target_oldloc == target)
static_beam = 1
max_distance = maxdistance
@@ -42,12 +43,12 @@
Reset()
Draw()
sleep(sleep_time)
qdel(src)
if(!qdeleted(src))
qdel(src)
/datum/beam/proc/End()
finished = 1
finished = TRUE
/datum/beam/proc/Reset()
@@ -128,9 +129,8 @@
return ..()
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam)
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type)
spawn(0)
newbeam.Start()
/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time = 3)
var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time)
INVOKE_ASYNC(newbeam, /datum/beam/.proc/Start)
return newbeam
+22 -21
View File
@@ -39,10 +39,12 @@
//title_image = ntitle_image
/datum/browser/proc/add_stylesheet(name, file)
stylesheets[name] = file
stylesheets["[ckey(name)].css"] = file
register_asset("[ckey(name)].css", file)
/datum/browser/proc/add_script(name, file)
scripts[name] = file
scripts["[ckey(name)].js"] = file
register_asset("[ckey(name)].js", file)
/datum/browser/proc/set_content(ncontent)
content = ncontent
@@ -51,17 +53,12 @@
content += ncontent
/datum/browser/proc/get_header()
var/key
var/filename
for (key in stylesheets)
filename = "[ckey(key)].css"
user << browse_rsc(stylesheets[key], filename)
head_content += "<link rel='stylesheet' type='text/css' href='[filename]'>"
var/file
for (file in stylesheets)
head_content += "<link rel='stylesheet' type='text/css' href='[file]'>"
for (key in scripts)
filename = "[ckey(key)].js"
user << browse_rsc(scripts[key], filename)
head_content += "<script type='text/javascript' src='[filename]'></script>"
for (file in scripts)
head_content += "<script type='text/javascript' src='[file]'></script>"
var/title_attributes = "class='uiTitle'"
if (title_image)
@@ -98,15 +95,20 @@
var/window_size = ""
if (width && height)
window_size = "size=[width]x[height];"
if (stylesheets.len)
send_asset_list(user, stylesheets, verify=FALSE)
if (scripts.len)
send_asset_list(user, scripts, verify=FALSE)
user << browse(get_content(), "window=[window_id];[window_size][window_options]")
if (use_onclose)
spawn(0)
//winexists sleeps, so we don't need to.
for (var/i in 1 to 10)
if (user && winexists(user, window_id))
onclose(user, window_id, ref)
break
setup_onclose()
/datum/browser/proc/setup_onclose()
set waitfor = 0 //winexists sleeps, so we don't need to.
for (var/i in 1 to 10)
if (user && winexists(user, window_id))
onclose(user, window_id, ref)
break
/datum/browser/proc/close()
user << browse(null, "window=[window_id]")
@@ -160,8 +162,7 @@
winset(user, "mapwindow", "focus=true")
break
if (timeout)
spawn(timeout)
close()
addtimer(CALLBACK(src, .proc/close), timeout)
/datum/browser/alert/close()
.=..()
@@ -275,4 +276,4 @@
if(src && src.mob)
//world << "[src] was [src.mob.machine], setting to null"
src.mob.unset_machine()
return
return
+98
View File
@@ -0,0 +1,98 @@
/*
USAGE:
var/datum/callback/C = new(object|null, /proc/type/path|"procstring", arg1, arg2, ... argn)
var/timerid = addtimer(C, time, timertype)
OR
var/timerid = addtimer(CALLBACK(object|null, /proc/type/path|procstring, arg1, arg2, ... argn), time, timertype)
Note: proc strings can only be given for datum proc calls, global procs must be proc paths
Also proc strings are strongly advised against because they don't compile error if the proc stops existing
See the note on proc typepath shortcuts
INVOKING THE CALLBACK:
var/result = C.Invoke(args, to, add) //additional args are added after the ones given when the callback was created
OR
var/result = C.InvokeAsync(args, to, add) //Sleeps will not block, returns . on the first sleep (then continues on in the "background" after the sleep/block ends), otherwise operates normally.
OR
INVOKE_ASYNC(<CALLBACK args>) to immediately create and call InvokeAsync
PROC TYPEPATH SHORTCUTS (these operate on paths, not types, so to these shortcuts, datum is NOT a parent of atom, etc...)
global proc while in another global proc:
.procname
Example:
CALLBACK(GLOBAL_PROC, .some_proc_here)
proc defined on current(src) object (when in a /proc/ and not an override) OR overridden at src or any of it's parents:
.procname
Example:
CALLBACK(src, .some_proc_here)
when the above doesn't apply:
.proc/procname
Example:
CALLBACK(src, .proc/some_proc_here)
proc defined on a parent of a some type:
/some/type/.proc/some_proc_here
Other wise you will have to do the full typepath of the proc (/type/of/thing/proc/procname)
*/
/datum/callback
var/datum/object = GLOBAL_PROC
var/delegate
var/list/arguments
/datum/callback/New(thingtocall, proctocall, ...)
if (thingtocall)
object = thingtocall
delegate = proctocall
if (length(args) > 2)
arguments = args.Copy(3)
/proc/ImmediateInvokeAsync(thingtocall, proctocall, ...)
set waitfor = FALSE
if (!thingtocall)
return
var/list/calling_arguments = length(args) > 2 ? args.Copy(3) : null
if (thingtocall == GLOBAL_PROC)
call(proctocall)(arglist(calling_arguments))
else
call(thingtocall, proctocall)(arglist(calling_arguments))
/datum/callback/proc/Invoke(...)
if (!object)
return
var/list/calling_arguments = arguments
if (length(args))
if (length(arguments))
calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean
else
calling_arguments = args
if (object == GLOBAL_PROC)
return call(delegate)(arglist(calling_arguments))
return call(object, delegate)(arglist(calling_arguments))
//copy and pasted because fuck proc overhead
/datum/callback/proc/InvokeAsync(...)
set waitfor = FALSE
if (!object)
return
var/list/calling_arguments = arguments
if (length(args))
if (length(arguments))
calling_arguments = calling_arguments + args //not += so that it creates a new list so the arguments list stays clean
else
calling_arguments = args
if (object == GLOBAL_PROC)
return call(delegate)(arglist(calling_arguments))
return call(object, delegate)(arglist(calling_arguments))
+3 -7
View File
@@ -65,13 +65,9 @@
crimes |= crime
return
/datum/datacore/proc/manifest(nosleep = 0)
spawn()
if(!nosleep)
sleep(40)
for(var/mob/living/carbon/human/H in player_list)
manifest_inject(H)
return
/datum/datacore/proc/manifest()
for(var/mob/living/carbon/human/H in player_list)
manifest_inject(H)
/datum/datacore/proc/manifest_modify(name, assignment)
var/datum/data/record/foundrecord = find_record("name", name, data_core.general)
+531 -341
View File
File diff suppressed because it is too large Load Diff
+28 -21
View File
@@ -19,9 +19,6 @@
if(!(type in D.viable_mobtypes))
return 0
if(count_by_type(viruses, /datum/disease/advance) >= 3)
return 0
return 1
@@ -32,23 +29,30 @@
/mob/proc/AddDisease(datum/disease/D)
var/datum/disease/DD = new D.type(1, D, 0)
viruses += DD
DD.affected_mob = src
DD.holder = src
for(var/datum/disease/advance/P in viruses)
if(istype(D, /datum/disease/advance))
var/datum/disease/advance/DD = D
if (P.totalResistance() < DD.totalTransmittable()) //Overwrite virus if the attacker's Transmission is lower than the defender's Resistance. This does not grant immunity to the lost virus.
P.remove_virus()
//Copy properties over. This is so edited diseases persist.
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
for(var/V in DD.vars)
if(V in skipped)
continue
if(istype(DD.vars[V],/list))
var/list/L = D.vars[V]
DD.vars[V] = L.Copy()
else
DD.vars[V] = D.vars[V]
if (!viruses.len) //Only add the new virus if it defeated the existing one
var/datum/disease/DD = new D.type(1, D, 0)
viruses += DD
DD.affected_mob = src
DD.holder = src
DD.affected_mob.med_hud_set_status()
//Copy properties over. This is so edited diseases persist.
var/list/skipped = list("affected_mob","holder","carrier","stage","type","parent_type","vars","transformed")
for(var/V in DD.vars)
if(V in skipped)
continue
if(istype(DD.vars[V],/list))
var/list/L = D.vars[V]
DD.vars[V] = L.Copy()
else
DD.vars[V] = D.vars[V]
DD.affected_mob.med_hud_set_status()
/mob/living/carbon/ContractDisease(datum/disease/D)
@@ -82,7 +86,7 @@
var/target_zone = pick(head_ch;1,body_ch;2,hands_ch;3,feet_ch;4)
if(istype(src, /mob/living/carbon/human))
if(ishuman(src))
var/mob/living/carbon/human/H = src
switch(target_zone)
@@ -93,6 +97,9 @@
if(passed && isobj(H.wear_mask))
Cl = H.wear_mask
passed = prob((Cl.permeability_coefficient*100) - 1)
if(passed && isobj(H.wear_neck))
Cl = H.wear_neck
passed = prob((Cl.permeability_coefficient*100) - 1)
if(2)
if(isobj(H.wear_suit))
Cl = H.wear_suit
@@ -117,7 +124,7 @@
Cl = H.shoes
passed = prob((Cl.permeability_coefficient*100) - 1)
else if(istype(src, /mob/living/carbon/monkey))
else if(ismonkey(src))
var/mob/living/carbon/monkey/M = src
switch(target_zone)
if(1)
@@ -140,6 +147,6 @@
/mob/living/carbon/human/CanContractDisease(datum/disease/D)
if(dna && (VIRUSIMMUNE in dna.species.specflags))
if(dna && (VIRUSIMMUNE in dna.species.species_traits))
return 0
return ..()
+17 -33
View File
@@ -7,6 +7,8 @@
*/
#define SYMPTOM_LIMIT 8
var/list/archive_diseases = list()
// The order goes from easy to cure to hard to cure.
@@ -34,7 +36,7 @@ var/list/advance_cures = list(
viable_mobtypes = list(/mob/living/carbon/human, /mob/living/carbon/monkey)
// NEW VARS
var/list/properties = list()
var/list/symptoms = list() // The symptoms of the disease.
var/id = ""
var/processing = 0
@@ -162,8 +164,8 @@ var/list/advance_cures = list(
/datum/disease/advance/proc/Refresh(new_name = 0)
//world << "[src.name] \ref[src] - REFRESH!"
var/list/properties = GenerateProperties()
AssignProperties(properties)
GenerateProperties()
AssignProperties()
id = null
if(!archive_diseases[GetDiseaseID()])
@@ -182,26 +184,24 @@ var/list/advance_cures = list(
CRASH("We did not have any symptoms before generating properties.")
return
var/list/properties = list("resistance" = 1, "stealth" = 1, "stage_rate" = 1, "transmittable" = 1, "severity" = 0)
properties = list("resistance" = 0, "stealth" = 0, "stage_rate" = 0, "transmittable" = 0, "severity" = 0)
for(var/datum/symptom/S in symptoms)
properties["resistance"] += S.resistance
properties["stealth"] += S.stealth
properties["stage_rate"] += S.stage_speed
properties["transmittable"] += S.transmittable
properties["severity"] = max(properties["severity"], S.severity) // severity is based on the highest severity symptom
return properties
return
// Assign the properties that are in the list.
/datum/disease/advance/proc/AssignProperties(list/properties = list())
/datum/disease/advance/proc/AssignProperties()
if(properties && properties.len)
switch(properties["stealth"])
if(2)
if(2,3)
visibility_flags = HIDDEN_SCANNER
if(3 to INFINITY)
if(4 to INFINITY)
visibility_flags = HIDDEN_SCANNER|HIDDEN_PANDEMIC
// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
@@ -252,7 +252,7 @@ var/list/advance_cures = list(
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure(list/properties = list())
/datum/disease/advance/proc/GenerateCure()
if(properties && properties.len)
var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
//world << "Res = [res]"
@@ -306,7 +306,7 @@ var/list/advance_cures = list(
if(HasSymptom(S))
return
if(symptoms.len < 5 + rand(-1, 1))
if(symptoms.len < (SYMPTOM_LIMIT - 1) + rand(-1, 1))
symptoms += S
else
RemoveSymptom(pick(symptoms))
@@ -372,7 +372,7 @@ var/list/advance_cures = list(
if(!user)
return
var/i = 5
var/i = SYMPTOM_LIMIT
var/datum/disease/advance/D = new(0, null)
D.symptoms = list()
@@ -426,31 +426,15 @@ var/list/advance_cures = list(
/datum/disease/advance/proc/totalStageSpeed()
var/total_stage_speed = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_stage_speed += S.stage_speed
return total_stage_speed
return properties["stage_rate"]
/datum/disease/advance/proc/totalStealth()
var/total_stealth = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_stealth += S.stealth
return total_stealth
return properties["stealth"]
/datum/disease/advance/proc/totalResistance()
var/total_resistance = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_resistance += S.resistance
return total_resistance
return properties["resistance"]
/datum/disease/advance/proc/totalTransmittable()
var/total_transmittable = 0
for(var/i in symptoms)
var/datum/symptom/S = i
total_transmittable += S.transmittable
return total_transmittable
return properties["transmittable"]
#undef RANDOM_STARTING_LEVEL
@@ -28,7 +28,7 @@ BONUS
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1, 2)
@@ -43,11 +43,73 @@ Bonus
return
/datum/symptom/choking/proc/Choke_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth())
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(max(16+A.totalStealth(),0))
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/choking/proc/Choke(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(16+A.totalStealth()*5)
var/get_damage = sqrt(21+A.totalStageSpeed()*0.5)+sqrt(max(16+A.totalStealth()*5,0))
M.adjustOxyLoss(get_damage)
return 1
return 1
/*
//////////////////////////////////////
Asphyxiation
Very very noticable.
Decreases stage speed.
Decreases transmittablity.
Bonus
Inflicts large spikes of oxyloss
Introduces Asphyxiating drugs to the system
Causes cardiac arrest on dying victims.
//////////////////////////////////////
*/
/datum/symptom/asphyxiation
name = "Acute respiratory distress syndrome"
stealth = -2
resistance = -0
stage_speed = -1
transmittable = -2
level = 7
severity = 3
/datum/symptom/asphyxiation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3, 4)
M << "<span class='warning'><b>[pick("Your windpipe feels thin.", "Your lungs feel small.")]</span>"
Asphyxiate_stage_3_4(M, A)
M.emote("gasp")
else
M << "<span class='userdanger'>[pick("Your lungs hurt!", "It hurts to breathe!")]</span>"
Asphyxiate(M, A)
M.emote("gasp")
if(M.getOxyLoss() >= 120)
M.visible_message("<span class='warning'>[M] stops breathing, as if their lungs have totally collapsed!</span>")
Asphyxiate_death(M, A)
return
/datum/symptom/asphyxiation/proc/Asphyxiate_stage_3_4(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()*0.7))+sqrt(abs(16+A.totalStealth()))
M.adjustOxyLoss(get_damage)
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()))+sqrt(abs(16+A.totalStealth()*5))
M.adjustOxyLoss(get_damage)
M.reagents.add_reagent_list(list("pancuronium" = 2, "sodium_thiopental" = 2))
return 1
/datum/symptom/asphyxiation/proc/Asphyxiate_death(mob/living/M, datum/disease/advance/A)
var/get_damage = sqrt(abs(21+A.totalStageSpeed()*1.5))+sqrt(abs(16+A.totalStealth()*7))
M.adjustOxyLoss(get_damage)
M.adjustBrainLoss(get_damage/2)
return 1
@@ -34,7 +34,7 @@ BONUS
M << "<span notice='warning'>[pick("You swallow excess mucus.", "You lightly cough.")]</span>"
else
M.emote("cough")
var/obj/item/I = M.get_active_hand()
if(I && I.w_class == 1)
var/obj/item/I = M.get_active_held_item()
if(I && I.w_class == WEIGHT_CLASS_TINY)
M.drop_item()
return
return
@@ -1,64 +0,0 @@
/*
//////////////////////////////////////
Damage Converter
Little bit hidden.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Reduced transmittablity
Intense Level.
Bonus
Slowly converts brute/fire damage to toxin.
//////////////////////////////////////
*/
/datum/symptom/damage_converter
name = "Toxic Compensation"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -2
level = 4
/datum/symptom/damage_converter/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Convert(M)
return
/datum/symptom/damage_converter/proc/Convert(mob/living/M)
var/get_damage = rand(1, 2)
if(istype(M, /mob/living/carbon/human))
var/mob/living/carbon/human/H = M
var/list/parts = H.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
L.heal_damage(get_damage, get_damage, 0)
M.adjustToxLoss(get_damage*parts.len)
else
if(M.getFireLoss() > 0 || M.getBruteLoss() > 0)
M.adjustFireLoss(-get_damage)
M.adjustBruteLoss(-get_damage)
M.adjustToxLoss(get_damage)
else
return
return 1
@@ -36,8 +36,9 @@ Bonus
if(!(M.ear_deaf))
M << "<span class='userdanger'>Your ears pop and begin ringing loudly!</span>"
M.setEarDamage(-1,INFINITY) //Shall be enough
spawn(200)
if(M)
M << "<span class='warning'>The ringing in your ears fades...</span>"
M.setEarDamage(-1,0)
return
addtimer(CALLBACK(src, .proc/Undeafen, M), 200)
/datum/symptom/deafness/proc/Undeafen(mob/living/M)
if(M)
M << "<span class='warning'>The ringing in your ears fades...</span>"
M.setEarDamage(-1,0)
@@ -36,6 +36,6 @@ Bonus
return
/datum/symptom/fever/proc/Heat(mob/living/M, datum/disease/advance/A)
var/get_heat = (sqrt(21+A.totalTransmittable()*2))+(sqrt(20+A.totalStageSpeed()*3))
var/get_heat = (sqrt(max(21,21+A.totalTransmittable()*2)))+(sqrt(max(21,20+A.totalStageSpeed()*3)))
M.bodytemperature = min(M.bodytemperature + (get_heat * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
return 1
return 1
+67 -2
View File
@@ -51,7 +51,72 @@ Bonus
return 1
/datum/symptom/fire/proc/Firestacks_stage_5(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*3))-(sqrt(16+A.totalStealth()))
var/get_stacks = (sqrt(max(0, 20+A.totalStageSpeed()*3)))-(sqrt(max(0, 16+A.totalStealth())))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
return 1
return 1
/*
//////////////////////////////////////
Alkali perspiration
Hidden.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Ignites infected mob.
Explodes mob on contact with water.
//////////////////////////////////////
*/
/datum/symptom/alkali
name = "Alkali perspiration"
stealth = 2
resistance = -2
stage_speed = -2
transmittable = -2
level = 7
severity = 6
/datum/symptom/alkali/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(3)
M << "<span class='warning'>[pick("Your veins boil.", "You feel hot.", "You smell meat cooking.")]</span>"
if(4)
Alkali_fire_stage_4(M, A)
M.IgniteMob()
M << "<span class='userdanger'>Your sweat bursts into flames!</span>"
M.emote("scream")
if(5)
Alkali_fire_stage_5(M, A)
M.IgniteMob()
M << "<span class='userdanger'>Your skin erupts into an inferno!</span>"
M.emote("scream")
if(M.fire_stacks < 0)
M.visible_message("<span class='warning'>[M]'s sweat sizzles and pops on contact with water!</span>")
explosion(M.loc,0,0,2)
Alkali_fire_stage_5(M, A)
return
/datum/symptom/alkali/proc/Alkali_fire_stage_4(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*5))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks/2)
M.reagents.add_reagent("clf3", 1)
return 1
/datum/symptom/alkali/proc/Alkali_fire_stage_5(mob/living/M, datum/disease/advance/A)
var/get_stacks = (sqrt(20+A.totalStageSpeed()*8))
M.adjust_fire_stacks(get_stacks)
M.adjustFireLoss(get_stacks)
M.reagents.add_reagent_list(list("napalm" = 3, "clf3" = 3))
return 1
@@ -40,4 +40,49 @@ Bonus
/datum/symptom/flesh_eating/proc/Flesheat(mob/living/M, datum/disease/advance/A)
var/get_damage = ((sqrt(16-A.totalStealth()))*5)
M.adjustBruteLoss(get_damage)
return 1
/*
//////////////////////////////////////
Autophagocytosis (AKA Programmed mass cell death)
Very noticable.
Lowers resistance.
Fast stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Deals brute damage over time.
//////////////////////////////////////
*/
/datum/symptom/flesh_death
name = "Autophagocytosis Necrosis"
stealth = -2
resistance = -2
stage_speed = 1
transmittable = -2
level = 7
severity = 6
/datum/symptom/flesh_death/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2,3)
M << "<span class='warning'>[pick("You feel your body break apart.", "Your skin rubs off like dust.")]</span>"
if(4,5)
M << "<span class='userdanger'>[pick("You feel your muscles weakening.", "Your skin begins detaching itself.", "You feel sandy.")]</span>"
Flesh_death(M, A)
return
/datum/symptom/flesh_death/proc/Flesh_death(mob/living/M, datum/disease/advance/A)
var/get_damage = ((sqrt(16-A.totalStealth()))*6)
M.adjustBruteLoss(get_damage)
M.reagents.add_reagent_list(list("heparin" = 5, "lipolicide" = 5))
return 1
@@ -29,15 +29,15 @@ Bonus
/datum/symptom/genetic_mutation/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 5)) // 15% chance
var/mob/living/carbon/M = A.affected_mob
if(!M.has_dna())
if(prob(SYMPTOM_ACTIVATION_PROB * 3)) // 15% chance
var/mob/living/carbon/C = A.affected_mob
if(!C.has_dna())
return
switch(A.stage)
if(4, 5)
M << "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>"
M.dna.remove_mutation_group(possible_mutations)
randmut(M, possible_mutations)
C << "<span class='warning'>[pick("Your skin feels itchy.", "You feel light headed.")]</span>"
C.dna.remove_mutation_group(possible_mutations)
C.randmut(possible_mutations)
return
// Archive their DNA before they were infected.
@@ -36,6 +36,6 @@ Bonus
M << "<span class='danger'>[pick("Something is following you.", "You are being watched.", "You hear a whisper in your ear.", "Thumping footsteps slam toward you from nowhere.")]</span>"
else
M << "<span class='userdanger'>[pick("Oh, your head...", "Your head pounds.", "They're everywhere! Run!", "Something in the shadows...")]</span>"
M.hallucination += 5
M.hallucination += 25
return
+194 -64
View File
@@ -26,99 +26,231 @@ Bonus
/datum/symptom/heal/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Heal(M, A)
//100% chance to activate for slow but consistent healing
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
Heal(M, A)
return
/datum/symptom/heal/proc/Heal(mob/living/M, datum/disease/advance/A)
var/get_damage = (sqrt(20+A.totalStageSpeed())*(1+rand()))
M.adjustToxLoss(-get_damage)
var/heal_amt = 0.5
if(M.toxloss > 0 && prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#66FF99")
M.adjustToxLoss(-heal_amt)
return 1
/*
//////////////////////////////////////
Metabolism
Apoptosis
Little bit hidden.
Lowers resistance.
Decreases stage speed.
Decreases transmittablity temrendously.
High Level.
Decreases transmittablity.
Bonus
Cures all diseases (except itself) and creates anti-bodies for them until the symptom dies.
Heals toxins in the affected mob's blood stream faster.
//////////////////////////////////////
*/
/datum/symptom/heal/metabolism
/datum/symptom/heal/plus
name = "Anti-Bodies Metabolism"
stealth = -1
resistance = -1
stage_speed = -1
transmittable = -4
level = 3
var/list/cured_diseases = list()
name = "Apoptoxin filter"
stealth = 0
resistance = -2
stage_speed = -2
transmittable = -2
level = 8
/datum/symptom/heal/metabolism/Heal(mob/living/M, datum/disease/advance/A)
var/cured = 0
for(var/datum/disease/D in M.viruses)
if(D != A)
cured = 1
cured_diseases += D.GetDiseaseID()
D.cure()
if(cured)
M << "<span class='notice'>You feel much better.</span>"
/datum/symptom/heal/metabolism/End(datum/disease/advance/A)
// Remove all the diseases we cured.
var/mob/living/M = A.affected_mob
if(istype(M))
if(cured_diseases.len)
for(var/res in M.resistances)
if(res in cured_diseases)
M.resistances -= res
M << "<span class='warning'>You feel weaker.</span>"
/datum/symptom/heal/plus/Heal(mob/living/M, datum/disease/advance/A)
var/heal_amt = 1
if(M.toxloss > 0 && prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#00FF00")
M.adjustToxLoss(-heal_amt)
return 1
/*
//////////////////////////////////////
Longevity
Regeneration
Medium hidden boost.
Large resistance boost.
Large stage speed boost.
Large transmittablity boost.
High Level.
Little bit hidden.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
After a certain amount of time the symptom will cure itself.
Heals brute damage slowly over time.
//////////////////////////////////////
*/
/datum/symptom/heal/longevity
/datum/symptom/heal/brute
name = "Longevity"
stealth = 3
resistance = 4
stage_speed = 4
transmittable = 4
level = 3
var/longevity = 30
name = "Regeneration"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 6
/datum/symptom/heal/longevity/Heal(mob/living/M, datum/disease/advance/A)
longevity -= 1
if(!longevity)
A.cure()
/datum/symptom/heal/brute/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 1
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, 0))
M.update_damage_overlays()
if(prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#FF3333")
return 1
/*
//////////////////////////////////////
Flesh Mending
No resistance change.
Decreases stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Heals brute damage over time. Turns cloneloss into burn damage.
//////////////////////////////////////
*/
/datum/symptom/heal/brute/plus
name = "Flesh Mending"
stealth = 0
resistance = 0
stage_speed = -2
transmittable = -2
level = 8
/datum/symptom/heal/brute/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 2
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(M.getCloneLoss() > 0)
M.adjustCloneLoss(-1)
M.take_bodypart_damage(0, 1) //Deals BURN damage, which is not cured by this symptom
new /obj/effect/overlay/temp/heal(get_turf(M), "#33FFCC")
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(heal_amt/parts.len, 0))
M.update_damage_overlays()
if(prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#CC1100")
return 1
/*
//////////////////////////////////////
Tissue Regrowth
Little bit hidden.
Lowers resistance tremendously.
Decreases stage speed tremendously.
Decreases transmittablity temrendously.
Fatal Level.
Bonus
Heals burn damage slowly over time.
//////////////////////////////////////
*/
/datum/symptom/heal/burn
name = "Tissue Regrowth"
stealth = 1
resistance = -4
stage_speed = -4
transmittable = -4
level = 6
/datum/symptom/heal/burn/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 1
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
if(prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#FF9933")
return 1
/*
//////////////////////////////////////
Heat Resistance //Needs a better name
No resistance change.
Decreases stage speed.
Decreases transmittablity.
Fatal Level.
Bonus
Heals burn damage over time, and helps stabilize body temperature.
//////////////////////////////////////
*/
/datum/symptom/heal/burn/plus
name = "Heat Resistance"
stealth = 0
resistance = 0
stage_speed = -2
transmittable = -2
level = 8
/datum/symptom/heal/burn/plus/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/heal_amt = 2
var/list/parts = M.get_damaged_bodyparts(1,1) //1,1 because it needs inputs.
if(M.bodytemperature > 310)
M.bodytemperature = max(310, M.bodytemperature - (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT))
else if(M.bodytemperature < 311)
M.bodytemperature = min(310, M.bodytemperature + (10 * heal_amt * TEMPERATURE_DAMAGE_COEFFICIENT))
if(!parts.len)
return
for(var/obj/item/bodypart/L in parts)
if(L.heal_damage(0, heal_amt/parts.len))
M.update_damage_overlays()
if(prob(20))
new /obj/effect/overlay/temp/heal(get_turf(M), "#CC6600")
return 1
/datum/symptom/heal/longevity/Start(datum/disease/advance/A)
longevity = rand(initial(longevity) - 5, initial(longevity) + 5)
/*
//////////////////////////////////////
@@ -147,12 +279,10 @@ Bonus
level = 5
/datum/symptom/heal/dna/Heal(mob/living/carbon/M, datum/disease/advance/A)
var/stage_speed = max( 20 + A.totalStageSpeed(), 0)
var/stealth_amount = max( 16 + A.totalStealth(), 0)
var/amt_healed = (sqrt(stage_speed*(3+rand())))-(sqrt(stealth_amount*rand()))
var/amt_healed = 1
M.adjustBrainLoss(-amt_healed)
//Non-power mutations, excluding race, so the virus does not force monkey -> human transformations.
var/list/unclean_mutations = (not_good_mutations|bad_mutations) - mutations_list[RACEMUT]
M.dna.remove_mutation_group(unclean_mutations)
M.radiation = max(M.radiation - 3, 0)
M.radiation = max(M.radiation - (2 * amt_healed), 0)
return 1
@@ -26,13 +26,13 @@ Bonus
/datum/symptom/oxygen/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
if (M.reagents.get_reagent_amount("salbutamol") < 20)
M.reagents.add_reagent("salbutamol", 20)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
M << "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>"
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
M.adjustOxyLoss(-3, 0)
if(M.losebreath >= 4)
M.losebreath -= 2
else
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
M << "<span class='notice'>[pick("Your lungs feel great.", "You realize you haven't been breathing.", "You don't feel the need to breathe.")]</span>"
return
@@ -26,24 +26,30 @@ Bonus
/datum/symptom/sensory_restoration/Activate(var/datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(2)
if(M.reagents.get_reagent_amount("inacusiate")<10)
M.reagents.add_reagent("inacusiate", 10)
M << "<span class='notice'>Your hearing feels clearer and crisp.</span>"
if(3)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 )
M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10))
M << "<span class='notice'>You feel sober.</span>"
if(4)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10)
M.reagents.add_reagent_list(list("antihol"=10, "inacusiate"=10, "synaphydramine"=5))
M << "<span class='notice'>You feel focused.</span>"
if(5)
if(M.reagents.get_reagent_amount("antihol") < 10 && M.reagents.get_reagent_amount("inacusiate") < 10 && M.reagents.get_reagent_amount("synaphydramine") < 10 && M.reagents.get_reagent_amount("mannitol") < 10)
M.reagents.add_reagent_list(list("mannitol"=10, "antihol"=10, "inacusiate"=10, "synaphydramine"=10))
var/mob/living/M = A.affected_mob
if(A.stage >= 2)
M.setEarDamage(0,0)
if(A.stage >= 3)
M.dizziness = 0
M.drowsyness = 0
M.slurring = 0
M.confused = 0
M.reagents.remove_all_type(/datum/reagent/consumable/ethanol, 3)
if(ishuman(M))
var/mob/living/carbon/human/H = M
H.drunkenness = max(H.drunkenness - 10, 0)
if(A.stage >= 4)
M.drowsyness = max(M.drowsyness-5, 0)
if(M.reagents.has_reagent("mindbreaker"))
M.reagents.remove_reagent("mindbreaker", 5)
if(M.reagents.has_reagent("histamine"))
M.reagents.remove_reagent("histamine", 5)
M.hallucination = max(0, M.hallucination - 10)
if(A.stage >= 5)
M.adjustBrainLoss(-3)
return
/*
@@ -72,30 +78,54 @@ Bonus
transmittable = -4
level = 6
severity = 5
var/sleepy = 0
var/sleepy_ticks = 0
/datum/symptom/sensory_destruction/Activate(var/datum/disease/advance/A)
..()
var/mob/living/M = A.affected_mob
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1)
M << "<span class='warning'>You can't feel anything.</span>"
if(2)
M << "<span class='warning'>You feel absolutely hammered.</span>"
if(prob(10))
M.reagents.add_reagent("morphine",rand(5,7))
sleepy_ticks += rand(10,14)
if(3)
M.reagents.add_reagent("ethanol",rand(5,7))
M << "<span class='warning'>You try to focus on not dying.</span>"
if(prob(15))
M.reagents.add_reagent("morphine",rand(5,7))
sleepy_ticks += rand(10,14)
if(4)
M.reagents.add_reagent_list(list("ethanol" = rand(7,15), "mindbreaker" = rand(5,10)))
M.reagents.add_reagent("ethanol",rand(6,10))
M << "<span class='warning'>u can count 2 potato!</span>"
if(prob(20))
M.reagents.add_reagent("morphine",rand(5,7))
sleepy_ticks += rand(10,14)
if(5)
M.reagents.add_reagent_list(list("impedrezene" = rand(5,15), "ethanol" = rand(7,20), "mindbreaker" = rand(5,15)))
M.reagents.add_reagent("ethanol",rand(7,13))
if(prob(25))
M.reagents.add_reagent("morphine",rand(5,7))
sleepy_ticks += rand(10,14)
if(sleepy_ticks)
if(A.stage>=4)
M.hallucination = min(M.hallucination + 10, 50)
if(A.stage>=5)
if(prob(80))
M.adjustBrainLoss(1)
if(prob(50))
M.drowsyness = max(M.drowsyness, 3)
sleepy++
sleepy_ticks--
else
sleepy = 0
switch(sleepy) //Works like morphine
if(11)
M << "<span class='warning'>You start to feel tired...</span>"
if(12 to 24)
M.drowsyness += 1
if(24 to INFINITY)
M.Sleeping(2, 0)
return
@@ -29,20 +29,22 @@ BONUS
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
M << "<span class='warning'>[pick("Your scalp itches.", "Your skin feels flakey.")]</span>"
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(3, 4)
if(!(H.hair_style == "Bald") && !(H.hair_style == "Balding Hair"))
H << "<span class='warning'>Your hair starts to fall out in clumps...</span>"
spawn(50)
H.hair_style = "Balding Hair"
H.update_hair()
addtimer(CALLBACK(src, .proc/Shed, H, FALSE), 50)
if(5)
if(!(H.facial_hair_style == "Shaved") || !(H.hair_style == "Bald"))
H << "<span class='warning'>Your hair starts to fall out in clumps...</span>"
spawn(50)
H.facial_hair_style = "Shaved"
H.hair_style = "Bald"
H.update_hair()
return
addtimer(CALLBACK(src, .proc/Shed, H, TRUE), 50)
/datum/symptom/shedding/proc/Shed(mob/living/carbon/human/H, fullbald)
if(fullbald)
H.facial_hair_style = "Shaved"
H.hair_style = "Bald"
else
H.hair_style = "Balding Hair"
H.update_hair()
@@ -21,14 +21,14 @@ BONUS
resistance = -1
stage_speed = -1
transmittable = -2
level = 4
level = 5
severity = 1
/datum/symptom/vitiligo/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "albino")
return
@@ -65,14 +65,14 @@ BONUS
resistance = -1
stage_speed = -1
transmittable = -2
level = 4
level = 5
severity = 1
/datum/symptom/revitiligo/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.skin_tone == "african2")
return
@@ -83,4 +83,4 @@ BONUS
else
H.visible_message("<span class='warning'>[H] looks a bit dark...</span>", "<span class='notice'>Your skin suddenly appears darker...</span>")
return
return
@@ -1,38 +0,0 @@
/*
//////////////////////////////////////
Stimulant //gotta go fast
Noticable.
Lowers resistance significantly.
Decreases stage speed moderately..
Decreases transmittablity tremendously.
Moderate Level.
Bonus
The body generates Ephedrine.
//////////////////////////////////////
*/
/datum/symptom/stimulant
name = "Stimulant"
stealth = -1
resistance = -3
stage_speed = -2
transmittable = -4
level = 3
/datum/symptom/stimulant/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 10))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(5)
if (M.reagents.get_reagent_amount("ephedrine") < 10)
M.reagents.add_reagent("ephedrine", 10)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
M << "<span class='notice'>[pick("You feel restless.", "You feel like running laps around the station.")]</span>"
return
@@ -3,7 +3,7 @@
var/list/list_symptoms = subtypesof(/datum/symptom)
var/list/dictionary_symptoms = list()
var/global/const/SYMPTOM_ACTIVATION_PROB = 3
var/global/const/SYMPTOM_ACTIVATION_PROB = 5
/datum/symptom
// Buffs/Debuffs the symptom has to the overall engineered disease.
+43 -1
View File
@@ -62,4 +62,46 @@ BONUS
if(1)
M << "<span class='notice'>You feel better, but no different from before.</span>"
if(5)
M << "<span class='notice'>You feel off, but nothing interesting happens.</span>"
M << "<span class='notice'>You feel off, but nothing interesting happens.</span>"
/*
//////////////////////////////////////
Viral aggressive metabolism (ex-Longevity)
No stealth.
Small resistance boost.
Reduced stage speed.
Large transmittablity boost.
High Level.
Bonus
The virus starts at stage 5 and decrease over time until it self cures.
Stages still increase naturally with stage speed.
//////////////////////////////////////
*/
/datum/symptom/viralreverse
name = "Viral aggressive metabolism"
stealth = 0
resistance = 1
stage_speed = -2
transmittable = 3
level = 3
/datum/symptom/viralreverse/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
Heal(M, A)
return
/datum/symptom/viralreverse/proc/Heal(mob/living/M, datum/disease/advance/A)
A.stage -= 1
if(A.stage < 2)
A.cure()
/datum/symptom/viralreverse/Start(datum/disease/advance/A)
A.stage = 5
@@ -75,13 +75,27 @@ Bonus
/datum/symptom/visionaid/Activate(datum/disease/advance/A)
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5)
if (M.reagents.get_reagent_amount("oculine") < 20)
M.reagents.add_reagent("oculine", 20)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 5))
M << "<span class='notice'>[pick("Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")]</span>"
var/mob/living/M = A.affected_mob
switch(A.stage)
if(4, 5) //basically oculine
if(M.disabilities & BLIND)
if(prob(20))
M << "<span class='warning'>Your vision slowly returns...</span>"
M.cure_blind()
M.cure_nearsighted()
M.blur_eyes(35)
else if(M.disabilities & NEARSIGHT)
M << "<span class='warning'>The blackness in your peripheral vision fades.</span>"
M.cure_nearsighted()
M.blur_eyes(10)
else if(M.eye_blind || M.eye_blurry)
M.set_blindness(0)
M.set_blurriness(0)
else if(M.eye_damage > 0)
M.adjust_eye_damage(-1)
else
if(prob(SYMPTOM_ACTIVATION_PROB * 3))
M << "<span class='notice'>[pick("Your eyes feel great.", "You are now blinking manually.", "You don't feel the need to blink.")]</span>"
return
@@ -28,7 +28,7 @@ BONUS
..()
if(prob(SYMPTOM_ACTIVATION_PROB * 2))
var/mob/living/M = A.affected_mob
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
switch(A.stage)
if(1)
+2 -2
View File
@@ -18,7 +18,7 @@
..()
if(!affected_mob.dna)
cure()
if(NOTRANSSTING in affected_mob.dna.species.specflags) //Only species that can be spread by transformation sting can be spread by the retrovirus
if(NOTRANSSTING in affected_mob.dna.species.species_traits) //Only species that can be spread by transformation sting can be spread by the retrovirus
cure()
if(!strain_data["dna"])
@@ -38,7 +38,7 @@
if(prob(1))
affected_mob << "<span class='danger'>Your muscles ache.</span>"
if(prob(20))
affected_mob.take_organ_damage(1)
affected_mob.take_bodypart_damage(1)
if(prob(1))
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
if(prob(20))
+2 -2
View File
@@ -26,7 +26,7 @@
if(prob(1))
affected_mob << "<span class='danger'>Your muscles ache.</span>"
if(prob(20))
affected_mob.take_organ_damage(1)
affected_mob.take_bodypart_damage(1)
if(prob(1))
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
if(prob(20))
@@ -45,7 +45,7 @@
if(prob(1))
affected_mob << "<span class='danger'>Your muscles ache.</span>"
if(prob(20))
affected_mob.take_organ_damage(1)
affected_mob.take_bodypart_damage(1)
if(prob(1))
affected_mob << "<span class='danger'>Your stomach hurts.</span>"
if(prob(20))
+2 -2
View File
@@ -22,7 +22,7 @@
affected_mob.emote("cough")
if(prob(1))
affected_mob << "<span class='danger'>You're burning in your own skin!</span>"
affected_mob.take_organ_damage(0,5)
affected_mob.take_bodypart_damage(0,5)
if(3)
affected_mob.bodytemperature += 20
@@ -32,5 +32,5 @@
affected_mob.emote("cough")
if(prob(5))
affected_mob << "<span class='danger'>You're burning in your own skin!</span>"
affected_mob.take_organ_damage(0,5)
affected_mob.take_bodypart_damage(0,5)
return
+6 -3
View File
@@ -22,7 +22,8 @@
if(!M.anchored && (M.flags & CONDUCT))
step_towards(M,affected_mob)
for(var/mob/living/silicon/S in orange(2,affected_mob))
if(istype(S, /mob/living/silicon/ai)) continue
if(isAI(S))
continue
step_towards(S,affected_mob)
if(3)
if(prob(2))
@@ -37,7 +38,8 @@
for(i=0,i<iter,i++)
step_towards(M,affected_mob)
for(var/mob/living/silicon/S in orange(4,affected_mob))
if(istype(S, /mob/living/silicon/ai)) continue
if(isAI(S))
continue
var/i
var/iter = rand(1,2)
for(i=0,i<iter,i++)
@@ -55,7 +57,8 @@
for(i=0,i<iter,i++)
step_towards(M,affected_mob)
for(var/mob/living/silicon/S in orange(6,affected_mob))
if(istype(S, /mob/living/silicon/ai)) continue
if(isAI(S))
continue
var/i
var/iter = rand(1,3)
for(i=0,i<iter,i++)
+27
View File
@@ -0,0 +1,27 @@
/datum/disease/parrot_possession
name = "Parrot Possession"
max_stages = 1
spread_text = "Paranormal"
spread_flags = SPECIAL
disease_flags = CURABLE
cure_text = "Holy Water."
cures = list("holywater")
cure_chance = 20
agent = "Avian Vengence"
viable_mobtypes = list(/mob/living/carbon/human)
desc = "Subject is possesed by the vengeful spirit of a parrot. Call the priest."
severity = MEDIUM
var/mob/living/simple_animal/parrot/Poly/ghost/parrot
/datum/disease/parrot_possession/stage_act()
..()
if(!parrot || parrot.loc != affected_mob)
cure()
else if(prob(parrot.speak_chance))
affected_mob.say(pick(parrot.speech_buffer))
/datum/disease/parrot_possession/cure()
if(parrot && parrot.loc == affected_mob)
parrot.loc = affected_mob.loc
affected_mob.visible_message("<span class='danger'>[parrot] is violently driven out of [affected_mob]!</span>", "<span class='userdanger'>[parrot] bursts out of your chest!</span>")
..()
+4 -12
View File
@@ -12,21 +12,17 @@
/datum/disease/rhumba_beat/stage_act()
..()
if(affected_mob.ckey == "rosham")
src.cure()
return
switch(stage)
if(1)
if(affected_mob.ckey == "rosham")
src.cure()
if(2)
if(affected_mob.ckey == "rosham")
src.cure()
if(prob(45))
affected_mob.adjustToxLoss(5)
affected_mob.updatehealth()
if(prob(1))
affected_mob << "<span class='danger'>You feel strange...</span>"
if(3)
if(affected_mob.ckey == "rosham")
src.cure()
if(prob(5))
affected_mob << "<span class='danger'>You feel the urge to dance...</span>"
else if(prob(5))
@@ -34,8 +30,6 @@
else if(prob(10))
affected_mob << "<span class='danger'>You feel the need to chick chicky boom...</span>"
if(4)
if(affected_mob.ckey == "rosham")
src.cure()
if(prob(10))
affected_mob.emote("gasp")
affected_mob << "<span class='danger'>You feel a burning beat inside...</span>"
@@ -43,10 +37,8 @@
affected_mob.adjustToxLoss(5)
affected_mob.updatehealth()
if(5)
if(affected_mob.ckey == "rosham")
src.cure()
affected_mob << "<span class='danger'>Your body is unable to contain the Rhumba Beat...</span>"
if(prob(50))
affected_mob.gib()
else
return
return
+10 -10
View File
@@ -45,20 +45,20 @@
if(affected_mob.notransform)
return
affected_mob.notransform = 1
for(var/obj/item/W in affected_mob)
if(istype(W, /obj/item/weapon/implant))
qdel(W)
continue
W.layer = initial(W.layer)
W.loc = affected_mob.loc
W.dropped(affected_mob)
for(var/obj/item/W in affected_mob.get_equipped_items())
affected_mob.dropItemToGround(W)
for(var/obj/item/I in affected_mob.held_items)
affected_mob.dropItemToGround(I)
var/mob/living/new_mob = new new_form(affected_mob.loc)
if(istype(new_mob))
new_mob.a_intent = "harm"
new_mob.a_intent = INTENT_HARM
if(affected_mob.mind)
affected_mob.mind.transfer_to(new_mob)
else
new_mob.key = affected_mob.key
new_mob.name = affected_mob.real_name
new_mob.real_name = new_mob.name
qdel(affected_mob)
@@ -187,7 +187,7 @@
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
stage4 = list("<span class='danger'>You are turning into a slime.</span>")
stage5 = list("<span class='danger'>You have become a slime.</span>")
new_form = /mob/living/simple_animal/slime
new_form = /mob/living/simple_animal/slime/random
/datum/disease/transformation/slime/stage_act()
..()
@@ -239,4 +239,4 @@
stage3 = list("<span class='danger'>Your appendages are melting away.</span>", "<span class='danger'>Your limbs begin to lose their shape.</span>")
stage4 = list("<span class='danger'>You're ravenous.</span>")
stage5 = list("<span class='danger'>You have become a morph.</span>")
new_form = /mob/living/simple_animal/hostile/morph
new_form = /mob/living/simple_animal/hostile/morph
+10 -13
View File
@@ -9,7 +9,7 @@
viable_mobtypes = list(/mob/living/carbon/human)
disease_flags = CAN_CARRY|CAN_RESIST|CURABLE
permeability_mod = 0.75
desc = "Some speculate, that this virus is the cause of Wizard Federation existance. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
desc = "Some speculate that this virus is the cause of the Space Wizard Federation's existence. Subjects affected show the signs of mental retardation, yelling obscure sentences or total gibberish. On late stages subjects sometime express the feelings of inner power, and, cite, 'the ability to control the forces of cosmos themselves!' A gulp of strong, manly spirits usually reverts them to normal, humanlike, condition."
severity = HARMFUL
required_organs = list(/obj/item/bodypart/head)
@@ -55,35 +55,32 @@ STI KALY - blind
/datum/disease/wizarditis/proc/spawn_wizard_clothes(chance = 0)
if(istype(affected_mob, /mob/living/carbon/human))
if(ishuman(affected_mob))
var/mob/living/carbon/human/H = affected_mob
if(prob(chance))
if(!istype(H.head, /obj/item/clothing/head/wizard))
if(!H.unEquip(H.head))
if(!H.dropItemToGround(H.head))
qdel(H.head)
H.equip_to_slot_or_del(new /obj/item/clothing/head/wizard(H), slot_head)
return
if(prob(chance))
if(!istype(H.wear_suit, /obj/item/clothing/suit/wizrobe))
if(!H.unEquip(H.wear_suit))
if(!H.dropItemToGround(H.wear_suit))
qdel(H.wear_suit)
H.equip_to_slot_or_del(new /obj/item/clothing/suit/wizrobe(H), slot_wear_suit)
return
if(prob(chance))
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal))
if(!H.unEquip(H.shoes))
if(!istype(H.shoes, /obj/item/clothing/shoes/sandal/magic))
if(!H.dropItemToGround(H.shoes))
qdel(H.shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/sandal/magic(H), slot_shoes)
return
else
var/mob/living/carbon/H = affected_mob
if(prob(chance))
if(!istype(H.r_hand, /obj/item/weapon/staff))
H.drop_r_hand()
H.put_in_r_hand( new /obj/item/weapon/staff(H) )
return
return
var/obj/item/weapon/staff/S = new(H)
if(!H.put_in_hands(S))
qdel(S)
/datum/disease/wizarditis/proc/teleport()
+60 -27
View File
@@ -1,3 +1,5 @@
/////////////////////////// DNA DATUM
/datum/dna
var/unique_enzymes
var/struc_enzymes
@@ -9,13 +11,15 @@
var/list/mutations = list() //All mutations are from now on here
var/list/temporary_mutations = list() //Timers for temporary mutations
var/list/previous = list() //For temporary name/ui/ue/blood_type modifications
var/mob/living/carbon/holder
var/mob/living/holder
/datum/dna/New(mob/living/carbon/new_holder)
/datum/dna/New(mob/living/new_holder)
if(new_holder)
holder = new_holder
/datum/dna/proc/transfer_identity(mob/living/carbon/destination, transfer_SE = 0)
if(!istype(destination))
return
destination.dna.unique_enzymes = unique_enzymes
destination.dna.uni_identity = uni_identity
destination.dna.blood_type = blood_type
@@ -164,12 +168,36 @@
features = random_features()
/datum/dna/stored //subtype used by brain mob's stored_dna
/datum/dna/stored/add_mutation(mutation_name) //no mutation changes on stored dna.
return
/datum/dna/stored/remove_mutation(mutation_name)
return
/datum/dna/stored/check_mutation(mutation_name)
return
/datum/dna/stored/remove_all_mutations()
return
/datum/dna/stored/remove_mutation_group(list/group)
return
/////////////////////////// DNA MOB-PROCS //////////////////////
/mob/proc/set_species(datum/species/mrace, icon_update = 1)
return
/mob/living/brain/set_species(datum/species/mrace, icon_update = 1)
if(mrace)
if(ispath(mrace))
stored_dna.species = new mrace()
else
stored_dna.species = mrace //not calling any species update procs since we're a brain, not a monkey/human
/mob/living/carbon/set_species(datum/species/mrace, icon_update = 1)
if(mrace && has_dna())
dna.species.on_species_loss(src)
@@ -238,7 +266,7 @@
return
gender = (deconstruct_block(getblock(dna.uni_identity, DNA_GENDER_BLOCK), 2)-1) ? FEMALE : MALE
mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
/mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutations_overlay_update=0)
..()
var/structure = dna.uni_identity
hair_color = sanitize_hexcolor(getblock(structure, DNA_HAIR_COLOR_BLOCK))
@@ -259,12 +287,12 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat
/mob/proc/domutcheck()
return
/mob/living/carbon/domutcheck()
/mob/living/carbon/domutcheck(force_powers=0) //Set force_powers to 1 to bypass the power chance
if(!has_dna())
return
for(var/datum/mutation/human/A in good_mutations | bad_mutations | not_good_mutations)
if(ismob(A.check_block(src)))
if(ismob(A.check_block(src, force_powers)))
return //we got monkeyized/humanized, this mob will be deleted, no need to continue.
update_mutations_overlay()
@@ -288,41 +316,46 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat
return 0
return getleftblocks(istring, blocknumber, blocksize) + replacement + getrightblocks(istring, blocknumber, blocksize)
/proc/randmut(mob/living/carbon/M, list/candidates, difficulty = 2)
if(!M.has_dna())
/mob/living/carbon/proc/randmut(list/candidates, difficulty = 2)
if(!has_dna())
return
var/datum/mutation/human/num = pick(candidates)
. = num.force_give(M)
return
. = num.force_give(src)
/proc/randmutb(mob/living/carbon/M)
if(!M.has_dna())
/mob/living/carbon/proc/randmutb()
if(!has_dna())
return
var/datum/mutation/human/HM = pick((bad_mutations | not_good_mutations) - mutations_list[RACEMUT])
. = HM.force_give(M)
. = HM.force_give(src)
/proc/randmutg(mob/living/carbon/M)
if(!M.has_dna())
/mob/living/carbon/proc/randmutg()
if(!has_dna())
return
var/datum/mutation/human/HM = pick(good_mutations)
. = HM.force_give(M)
. = HM.force_give(src)
/proc/randmuti(mob/living/carbon/M)
if(!M.has_dna())
/mob/living/carbon/proc/randmutvg()
if(!has_dna())
return
var/datum/mutation/human/HM = pick((good_mutations) - mutations_list[HULK] - mutations_list[DWARFISM])
. = HM.force_give(src)
/mob/living/carbon/proc/randmuti()
if(!has_dna())
return
var/num = rand(1, DNA_UNI_IDENTITY_BLOCKS)
var/newdna = setblock(M.dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters))
M.dna.uni_identity = newdna
return
var/newdna = setblock(dna.uni_identity, num, random_string(DNA_BLOCK_SIZE, hex_characters))
dna.uni_identity = newdna
updateappearance(mutations_overlay_update=1)
/proc/clean_dna(mob/living/carbon/M)
if(!M.has_dna())
/mob/living/carbon/proc/clean_dna()
if(!has_dna())
return
M.dna.remove_all_mutations()
dna.remove_all_mutations()
/proc/clean_randmut(mob/living/carbon/M, list/candidates, difficulty = 2)
clean_dna(M)
randmut(M, candidates, difficulty)
/mob/living/carbon/proc/clean_randmut(list/candidates, difficulty = 2)
clean_dna()
randmut(candidates, difficulty)
/proc/scramble_dna(mob/living/carbon/M, ui=FALSE, se=FALSE, probability)
if(!M.has_dna())
@@ -356,4 +389,4 @@ mob/living/carbon/human/updateappearance(icon_update=1, mutcolor_update=0, mutat
value = values
return value
/////////////////////////// DNA HELPER-PROCS
/////////////////////////// DNA HELPER-PROCS
+9 -6
View File
@@ -9,7 +9,9 @@
// This isn't applied to the dog, but stores the icon_state of the
// sprite that the associated item uses
var/icon_file
var/icon_state
var/obj_icon_state
var/obj_alpha
var/obj_color
/datum/dog_fashion/New(mob/M)
name = replacetext(name, "REAL_NAME", M.real_name)
@@ -30,8 +32,11 @@
D.speak_emote = speak_emote
/datum/dog_fashion/proc/get_image(var/dir)
if(icon_file && icon_state)
return image(icon_file, icon_state = icon_state, dir = dir)
if(icon_file && obj_icon_state)
var/image/corgI = image(icon_file, icon_state = obj_icon_state, dir = dir)
corgI.alpha = obj_alpha
corgI.color = obj_color
return corgI
/datum/dog_fashion/head
@@ -40,8 +45,6 @@
/datum/dog_fashion/back
icon_file = 'icons/mob/corgi_back.dmi'
/datum/dog_fashion/head
/datum/dog_fashion/head/helmet
name = "Sergeant REAL_NAME"
desc = "The ever-loyal, the ever-vigilant."
@@ -129,7 +132,7 @@
emote_see = list("stumbles around.", "shivers.")
emote_hear = list("howls!","groans.")
desc = "Spooky!"
icon_state = "sheet"
obj_icon_state = "sheet"
/datum/dog_fashion/head/santa
name = "Santa's Corgi Helper"
+108
View File
@@ -0,0 +1,108 @@
#define EMOTE_VISIBLE 1
#define EMOTE_AUDIBLE 2
var/global/list/emote_list = list()
/datum/emote
var/key = "" //What calls the emote
var/key_third_person = "" //This will also call the emote
var/message = "" //Message displayed when emote is used
var/message_mime = "" //Message displayed if the user is a mime
var/message_alien = "" //Message displayed if the user is a grown alien
var/message_larva = "" //Message displayed if the user is an alien larva
var/message_robot = "" //Message displayed if the user is a robot
var/message_AI = "" //Message displayed if the user is an AI
var/message_monkey = "" //Message displayed if the user is a monkey
var/message_param = "" //Message to display if a param was given
var/emote_type = EMOTE_VISIBLE //Whether the emote is visible or audible
var/restraint_check = FALSE //Checks if the mob is restrained before performing the emote
var/muzzle_ignore = FALSE //Will only work if the emote is EMOTE_AUDIBLE
var/list/mob_type_allowed_typecache = list() //Types that are allowed to use that emote
var/list/mob_type_blacklist_typecache = list() //Types that are NOT allowed to use that emote
var/stat_allowed = CONSCIOUS
/datum/emote/New()
..()
if(key_third_person)
emote_list[key_third_person] = src
mob_type_allowed_typecache = typecacheof(mob_type_allowed_typecache)
mob_type_blacklist_typecache = typecacheof(mob_type_blacklist_typecache)
/datum/emote/proc/run_emote(mob/user, params = null, type_override = null)
. = TRUE
if(!can_run_emote(user))
return FALSE
var/msg = select_message_type(user)
if(params && message_param)
msg = select_param(user, params)
if(findtext(msg, "their"))
msg = replacetext(msg, "their", user.p_their())
if(findtext(msg, "them"))
msg = replacetext(msg, "them", user.p_them())
if(findtext(msg, "%s"))
msg = replacetext(msg, "%s", user.p_s())
var/mob/living/L = user
for(var/obj/item/weapon/implant/I in L.implants)
I.trigger(key, L)
if(!msg)
return FALSE
msg = "<b>[user]</b> " + msg
for(var/mob/M in dead_mob_list)
if(!M.client || isnewplayer(M))
continue
var/T = get_turf(src)
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(T, null)))
M.show_message(msg)
if(emote_type == EMOTE_AUDIBLE)
user.audible_message(msg)
else
user.visible_message(msg)
log_emote("[key_name(user)] : [msg]")
/datum/emote/proc/select_message_type(mob/user)
. = message
if(!muzzle_ignore && user.is_muzzled() && emote_type == EMOTE_AUDIBLE)
return "makes a [pick("strong ", "weak ", "")]noise."
if(user.mind && user.mind.miming && message_mime)
. = message_mime
if(isalienadult(user) && message_alien)
. = message_alien
else if(islarva(user) && message_larva)
. = message_larva
else if(iscyborg(user) && message_robot)
. = message_robot
else if(isAI(user) && message_AI)
. = message_AI
else if(ismonkey(user) && message_monkey)
. = message_monkey
/datum/emote/proc/select_param(mob/user, params)
return replacetext(message_param, "%t", params)
/datum/emote/proc/can_run_emote(mob/user, help_check)
. = TRUE
if(!is_type_in_typecache(user, mob_type_allowed_typecache))
return FALSE
if(is_type_in_typecache(user, mob_type_blacklist_typecache))
return FALSE
if(!help_check)
if(user.stat > stat_allowed || (user.status_flags & FAKEDEATH))
return FALSE
if(restraint_check && user.restrained())
return FALSE
/datum/emote/sound
var/sound //Sound to play when emote is called
var/vary = FALSE //used for the honk borg emote
mob_type_allowed_typecache = list(/mob/living/brain, /mob/living/silicon)
/datum/emote/sound/run_emote(mob/user, params)
. = ..()
if(.)
playsound(user.loc, sound, 50, vary)
+90
View File
@@ -0,0 +1,90 @@
//Just new and forget
/datum/forced_movement
var/atom/movable/victim
var/atom/target
var/last_processed
var/steps_per_tick
var/allow_climbing
var/datum/callback/on_step
var/moved_at_all = FALSE
//as fast as ssfastprocess
/datum/forced_movement/New(atom/movable/_victim, atom/_target, _steps_per_tick = 0.5, _allow_climbing = FALSE, datum/callback/_on_step = null)
victim = _victim
target = _target
steps_per_tick = _steps_per_tick
allow_climbing = _allow_climbing
on_step = _on_step
. = ..()
if(_victim && _target && _steps_per_tick && !_victim.force_moving)
last_processed = world.time
_victim.force_moving = src
START_PROCESSING(SSfastprocess, src)
else
qdel(src) //if you want to overwrite the current forced movement, call qdel(victim.force_moving) before creating this
/datum/forced_movement/Destroy()
if(victim.force_moving == src)
victim.force_moving = null
if(moved_at_all)
victim.forceMove(victim.loc) //get the side effects of moving here that require us to currently not be force_moving aka reslipping on ice
STOP_PROCESSING(SSfastprocess, src)
victim = null
target = null
return ..()
/datum/forced_movement/process()
if(qdeleted(victim) || !victim.loc || qdeleted(target) || !target.loc)
qdel(src)
return
var/steps_to_take = round(steps_per_tick * (world.time - last_processed))
if(steps_to_take)
for(var/i in 1 to steps_to_take)
if(TryMove())
moved_at_all = TRUE
if(on_step)
on_step.InvokeAsync()
else
qdel(src)
return
last_processed = world.time
/datum/forced_movement/proc/TryMove(recursive = FALSE)
var/atom/movable/vic = victim //sanic
var/atom/tar = target
if(!recursive)
. = step_towards(vic, tar)
//shit way for getting around corners
if(!.)
if(tar.x > vic.x)
if(step(vic, EAST))
. = TRUE
else if(tar.x < vic.x)
if(step(vic, WEST))
. = TRUE
if(!.)
if(tar.y > vic.y)
if(step(vic, NORTH))
. = TRUE
else if(tar.y < vic.y)
if(step(vic, SOUTH))
. = TRUE
if(!.)
if(recursive)
return FALSE
else
. = TryMove(TRUE)
. = . && (vic.loc != tar.loc)
/mob/Bump(atom/A)
. = ..()
if(force_moving && force_moving.allow_climbing && istype(A,/obj/structure))
var/obj/structure/S = A
if(S.climbable)
S.do_climb(src)
+5
View File
@@ -0,0 +1,5 @@
/datum/proc/freon_gas_act()
return 0
/datum/proc/water_vapor_gas_act() // We get it
return 0 // You vape
+25 -39
View File
@@ -10,59 +10,45 @@
..()
events = new
/datum/events/Destroy()
for(var/elist in events)
for(var/e in events[elist])
qdel(e)
events = null
return ..()
/datum/events/proc/addEventType(event_type as text)
if(!(event_type in events) || !islist(events[event_type]))
events[event_type] = list()
return 1
return
return TRUE
return FALSE
// Arguments: event_type as text, proc_holder as datum, proc_name as text
// Returns: New event, null on error.
/datum/events/proc/addEvent(event_type as text, proc_holder, proc_name as text)
if(!event_type || !proc_holder || !proc_name)
/datum/events/proc/addEvent(event_type as text, datum/callback/cb)
if(!event_type || !cb)
return
addEventType(event_type)
var/list/event = events[event_type]
var/datum/event/E = new /datum/event(proc_holder,proc_name)
event += E
return E
event += cb
return cb
// Arguments: event_type as text, any number of additional arguments to pass to event handler
// Returns: null
/datum/events/proc/fireEvent()
//world << "Events in [args[1]] called"
var/list/event = listgetindex(events,args[1])
/datum/events/proc/fireEvent(eventName, ...)
var/list/event = listgetindex(events,eventName)
if(istype(event))
spawn(0)
for(var/datum/event/E in event)
if(!E.Fire(arglist(args.Copy(2))))
clearEvent(args[1],E)
return
for(var/E in event)
var/datum/callback/cb = E
cb.InvokeAsync(arglist(args.Copy(2)))
// Arguments: event_type as text, E as /datum/event
// Returns: 1 if event cleared, null on error
// Returns: TRUE if event cleared, FALSE on error
/datum/events/proc/clearEvent(event_type as text, datum/event/E)
if(!event_type || !E)
return
/datum/events/proc/clearEvent(event_type as text, datum/callback/cb)
if(!event_type || !cb)
return FALSE
var/list/event = listgetindex(events,event_type)
event -= E
return 1
/datum/event
var/listener
var/proc_name
/datum/event/New(tlistener,tprocname)
listener = tlistener
proc_name = tprocname
return ..()
/datum/event/proc/Fire()
//world << "Event fired"
if(listener)
call(listener,proc_name)(arglist(args))
return 1
return
event -= cb
qdel(cb)
return TRUE
+40 -17
View File
@@ -8,22 +8,24 @@ var/global/datum/getrev/revdata = new()
/datum/getrev/New()
var/head_file = return_file_text(".git/logs/HEAD")
var/regex/head_log = new("(\\w{40}) (\\w{40}).+> (\\d{10}).+\n\\Z")
head_log.Find(head_file)
parentcommit = head_log.group[1]
commit = head_log.group[2]
var/unix_time = text2num(head_log.group[3])
if(SERVERTOOLS && fexists("..\\prtestjob.lk"))
testmerge = file2list("..\\prtestjob.lk")
date = unix2date(unix_time)
var/testlen = max(testmerge.len - 1, 0)
var/regex/head_log = new("(\\w{40}) .+> (\\d{10}).+(?=(\n.*(\\w{40}).*){[testlen]}\n*\\Z)")
head_log.Find(head_file)
parentcommit = head_log.group[1]
date = unix2date(text2num(head_log.group[2]))
commit = head_log.group[4]
world.log << "Running /tg/ revision:"
world.log << "[date]"
world.log << commit
if(testmerge.len)
world.log << commit
for(var/line in testmerge)
if(line)
world.log << "Test merge active of PR #[line]"
world.log << "Based off master commit [parentcommit]"
else
world.log << parentcommit
world.log << "Current map - [MAP_NAME]" //can't think of anywhere better to put it
/client/verb/showrevinfo()
@@ -31,7 +33,7 @@ var/global/datum/getrev/revdata = new()
set name = "Show Server Revision"
set desc = "Check the current server code revision"
if(revdata.commit)
if(revdata.parentcommit)
src << "<b>Server revision compiled on:</b> [revdata.date]"
if(revdata.testmerge.len)
for(var/line in revdata.testmerge)
@@ -39,7 +41,7 @@ var/global/datum/getrev/revdata = new()
src << "Test merge active of PR <a href='[config.githuburl]/pull/[line]'>#[line]</a>"
src << "Based off master commit <a href='[config.githuburl]/commit/[revdata.parentcommit]'>[revdata.parentcommit]</a>"
else
src << "<a href='[config.githuburl]/commit/[revdata.commit]'>[revdata.commit]</a>"
src << "<a href='[config.githuburl]/commit/[revdata.parentcommit]'>[revdata.parentcommit]</a>"
else
src << "Revision unknown"
src << "<b>Current Infomational Settings:</b>"
@@ -50,12 +52,33 @@ var/global/datum/getrev/revdata = new()
src << "Enforce Continuous Rounds: [config.continuous.len] of [config.modes.len] roundtypes"
src << "Allow Midround Antagonists: [config.midround_antag.len] of [config.modes.len] roundtypes"
if(config.show_game_type_odds)
src <<"<b>Game Mode Odds:</b>"
if(ticker.current_state == GAME_STATE_PLAYING)
src <<"<b>Game Mode Odds for current round:</b>"
var/prob_sum = 0
var/list/probs = list()
var/list/modes = config.gamemode_cache
for(var/mode in modes)
var/datum/game_mode/M = mode
var/ctag = initial(M.config_tag)
if(!(ctag in config.probabilities))
continue
if((config.min_pop[ctag] && (config.min_pop[ctag] > ticker.totalPlayersReady)) || (initial(M.required_players) > ticker.totalPlayersReady))
continue
if(config.max_pop[ctag] && (config.max_pop[ctag] < ticker.totalPlayersReady))
continue
probs[ctag] = 1
prob_sum += config.probabilities[ctag]
for(var/ctag in probs)
if(config.probabilities[ctag] > 0)
var/percentage = round(config.probabilities[ctag] / prob_sum * 100, 0.1)
src << "[ctag] [percentage]%"
src <<"<b>All Game Mode Odds:</b>"
var/sum = 0
for(var/i=1,i<=config.probabilities.len,i++)
sum += config.probabilities[config.probabilities[i]]
for(var/i=1,i<=config.probabilities.len,i++)
if(config.probabilities[config.probabilities[i]] > 0)
var/percentage = round(config.probabilities[config.probabilities[i]] / sum * 100, 0.1)
src << "[config.probabilities[i]] [percentage]%"
return
for(var/ctag in config.probabilities)
sum += config.probabilities[ctag]
for(var/ctag in config.probabilities)
if(config.probabilities[ctag] > 0)
var/percentage = round(config.probabilities[ctag] / sum * 100, 0.1)
src << "[ctag] [percentage]%"
return
+7 -3
View File
@@ -40,7 +40,7 @@
atmos_machines += A
continue
SSobj.setup_template_objects(atoms)
SSobj.InitializeAtoms(atoms)
SSmachine.setup_template_powernets(cables)
SSair.setup_template_machinery(atmos_machines)
@@ -94,8 +94,8 @@
/proc/preloadRuinTemplates()
// Still supporting bans by filename
var/list/banned = generateMapList("config/lavaRuinBlacklist.txt")
banned += generateMapList("config/spaceRuinBlacklist.txt")
var/list/banned = generateMapList("config/lavaruinblacklist.txt")
banned += generateMapList("config/spaceruinblacklist.txt")
for(var/item in subtypesof(/datum/map_template/ruin))
var/datum/map_template/ruin/ruin_type = item
@@ -117,12 +117,16 @@
/proc/preloadShuttleTemplates()
var/list/unbuyable = generateMapList("config/unbuyableshuttles.txt")
for(var/item in subtypesof(/datum/map_template/shuttle))
var/datum/map_template/shuttle/shuttle_type = item
if(!(initial(shuttle_type.suffix)))
continue
var/datum/map_template/shuttle/S = new shuttle_type()
if(unbuyable.Find(S.mappath))
S.can_be_bought = FALSE
shuttle_templates[S.shuttle_id] = S
map_templates[S.shuttle_id] = S
+14 -6
View File
@@ -82,9 +82,9 @@
/datum/teleport/proc/playSpecials(atom/location,datum/effect_system/effect,sound)
if(location)
if(effect)
addtimer(src, "do_effect", 0, FALSE, location, effect)
INVOKE_ASYNC(src, .proc/do_effect, location, effect)
if(sound)
addtimer(src, "do_sound", 0, FALSE, location, sound)
INVOKE_ASYNC(src, .proc/do_sound, location, sound)
/datum/teleport/proc/do_effect(atom/location, datum/effect_system/effect)
src = null
@@ -106,6 +106,8 @@
if(!center)
center = destination
for(var/turf/T in range(precision,center))
if(T.is_transition_turf())
continue // Avoid picking these.
var/area/A = T.loc
if(!A.noteleport)
posturfs.Add(T)
@@ -114,7 +116,7 @@
else
destturf = get_turf(destination)
if(!destturf || !curturf)
if(!destturf || !curturf || destturf.is_transition_turf())
return 0
var/area/A = get_area(curturf)
@@ -165,14 +167,14 @@
var/list/bagholding = teleatom.search_contents_for(/obj/item/weapon/storage/backpack/holding)
if(bagholding.len)
precision = max(rand(1,100)*bagholding.len,100)
if(istype(teleatom, /mob/living))
if(isliving(teleatom))
var/mob/living/MM = teleatom
MM << "<span class='warning'>The bluespace interface on your bag of holding interferes with the teleport!</span>"
return 1
// Safe location finder
/proc/find_safe_turf(zlevel = ZLEVEL_STATION, list/zlevels)
/proc/find_safe_turf(zlevel = ZLEVEL_STATION, list/zlevels, extended_safety_checks = FALSE)
if(!zlevels)
zlevels = list(zlevel)
var/cycles = 1000
@@ -183,7 +185,7 @@
var/z = pick(zlevels)
var/random_location = locate(x,y,z)
if(!(istype(random_location, /turf/open/floor)))
if(!isfloorturf(random_location))
continue
var/turf/open/floor/F = random_location
if(!F.air)
@@ -215,5 +217,11 @@
if((pressure <= 20) || (pressure >= 550))
continue
if(extended_safety_checks)
if(istype(F, /turf/open/floor/plating/lava)) //chasms aren't /floor, and so are pre-filtered
var/turf/open/floor/plating/lava/L = F
if(!L.is_safe())
continue
// DING! You have passed the gauntlet, and are "probably" safe.
return F
-2
View File
@@ -12,8 +12,6 @@ var/datum/atom_hud/huds = list( \
ANTAG_HUD_OPS = new/datum/atom_hud/antag(), \
ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), \
ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), \
ANTAG_HUD_HOG_BLUE = new/datum/atom_hud/antag(),\
ANTAG_HUD_HOG_RED = new/datum/atom_hud/antag(),\
ANTAG_HUD_TRAITOR = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_NINJA = new/datum/atom_hud/antag/hidden(),\
ANTAG_HUD_CHANGELING = new/datum/atom_hud/antag/hidden(),\
+263 -28
View File
@@ -6,7 +6,11 @@
var/temporary = 0
var/datum/martial_art/base = null // The permanent style
var/deflection_chance = 0 //Chance to deflect projectiles
var/block_chance = 0 //Chance to block melee attacks using items while on throw mode.
var/restraining = 0 //used in cqc's disarm_act to check if the disarmed is being restrained and so whether they should be put in a chokehold or not
var/help_verb = null
var/no_guns = FALSE
var/allow_temp_override = TRUE //if this martial art can be overridden by temporary martial arts
/datum/martial_art/proc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
return 0
@@ -21,6 +25,7 @@
if(D != current_target)
current_target = D
streak = ""
restraining = 0
streak = streak+element
if(length(streak) > max_streak_length)
streak = copytext(streak,2)
@@ -28,16 +33,26 @@
/datum/martial_art/proc/basic_hit(mob/living/carbon/human/A,mob/living/carbon/human/D)
A.do_attack_animation(D)
var/damage = rand(A.dna.species.punchdamagelow, A.dna.species.punchdamagehigh)
var/atk_verb = A.dna.species.attack_verb
if(D.lying)
atk_verb = "kick"
switch(atk_verb)
if("kick")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
if("slash")
A.do_attack_animation(D, ATTACK_EFFECT_CLAW)
if("smash")
A.do_attack_animation(D, ATTACK_EFFECT_SMASH)
else
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
if(!damage)
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>")
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(A, D, "attempted to [atk_verb]")
return 0
@@ -46,7 +61,7 @@
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>")
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
D.apply_damage(damage, BRUTE, affecting, armor_block)
@@ -62,12 +77,14 @@
return 1
/datum/martial_art/proc/teach(mob/living/carbon/human/H,make_temporary=0)
if(help_verb)
H.verbs += help_verb
if(make_temporary)
temporary = 1
if(H.martial_art && temporary)
if(temporary && H.martial_art)
if(!H.martial_art.allow_temp_override)
return
base = H.martial_art
if(help_verb)
H.verbs += help_verb
H.martial_art = src
/datum/martial_art/proc/remove(mob/living/carbon/human/H)
@@ -90,14 +107,15 @@
/datum/martial_art/boxing/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
var/atk_verb = pick("left hook","right hook","straight punch")
var/damage = rand(5, 8) + A.dna.species.punchdamagelow
if(!damage)
playsound(D.loc, A.dna.species.miss_sound, 25, 1, -1)
D.visible_message("<span class='warning'>[A] has attempted to hit [D] with a [atk_verb]!</span>")
D.visible_message("<span class='warning'>[A] has attempted to [atk_verb] [D]!</span>", \
"<span class='userdanger'>[A] has attempted to [atk_verb] [D]!</span>", null, COMBAT_MESSAGE_RANGE)
add_logs(A, D, "attempted to hit", atk_verb)
return 0
@@ -107,11 +125,11 @@
playsound(D.loc, A.dna.species.attack_sound, 25, 1, -1)
D.visible_message("<span class='danger'>[A] has hit [D] with a [atk_verb]!</span>", \
"<span class='userdanger'>[A] has hit [D] with a [atk_verb]!</span>")
D.visible_message("<span class='danger'>[A] has [atk_verb]ed [D]!</span>", \
"<span class='userdanger'>[A] has [atk_verb]ed [D]!</span>", null, COMBAT_MESSAGE_RANGE)
D.apply_damage(damage, STAMINA, affecting, armor_block)
add_logs(A, D, "punched")
add_logs(A, D, "punched (boxing) ")
if(D.getStaminaLoss() > 50)
var/knockout_prob = D.getStaminaLoss() + rand(-15,15)
if((D.stat != DEAD) && prob(knockout_prob))
@@ -120,6 +138,7 @@
D.apply_effect(10,WEAKEN,armor_block)
D.SetSleeping(5)
D.forcesay(hit_appends)
add_logs(A, D, "knocked out (boxing) ")
else if(D.lying)
D.forcesay(hit_appends)
return 1
@@ -170,6 +189,7 @@
for(var/turf/T in range(1,A))
turfs.Add(T)
R.cast(turfs)
add_logs(A, D, "tornado sweeped(Plasma Fist)")
return
/datum/martial_art/plasma_fist/proc/Throwback(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -179,15 +199,17 @@
var/atom/throw_target = get_edge_target_turf(D, get_dir(D, get_step_away(D, A)))
D.throw_at(throw_target, 200, 4,A)
A.say("HYAH!")
add_logs(A, D, "threw back (Plasma Fist)")
return
/datum/martial_art/plasma_fist/proc/Plasma(mob/living/carbon/human/A, mob/living/carbon/human/D)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
playsound(D.loc, 'sound/weapons/punch1.ogg', 50, 1, -1)
A.say("PLASMA FIST!")
D.visible_message("<span class='danger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>", \
"<span class='userdanger'>[A] has hit [D] with THE PLASMA FIST TECHNIQUE!</span>")
D.gib()
add_logs(A, D, "gibbed (Plasma Fist)")
return
/datum/martial_art/plasma_fist/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -230,6 +252,8 @@
/datum/martial_art/the_sleeping_carp
name = "The Sleeping Carp"
deflection_chance = 100
no_guns = TRUE
allow_temp_override = FALSE
help_verb = /mob/living/carbon/human/proc/sleeping_carp_help
/datum/martial_art/the_sleeping_carp/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -257,7 +281,7 @@
/datum/martial_art/the_sleeping_carp/proc/wristWrench(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.stunned && !D.weakened)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] grabs [D]'s wrist and wrenches it sideways!</span>", \
"<span class='userdanger'>[A] grabs your wrist and violently wrenches it to the side!</span>")
playsound(get_turf(A), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
@@ -266,22 +290,24 @@
D.apply_damage(5, BRUTE, pick("l_arm", "r_arm"))
D.Stun(3)
return 1
add_logs(A, D, "wrist wrenched (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/backKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(A.dir == D.dir && !D.stat && !D.weakened)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] kicks [D] in the back!</span>", \
"<span class='userdanger'>[A] kicks you in the back, making you stumble and fall!</span>")
step_to(D,get_step(D,D.dir),1)
D.Weaken(4)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
add_logs(A, D, "back-kicked (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/kneeStomach(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.weakened)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] knees [D] in the stomach!</span>", \
"<span class='userdanger'>[A] winds you with a knee in the stomach!</span>")
D.audible_message("<b>[D]</b> gags!")
@@ -289,11 +315,12 @@
D.Stun(2)
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
return 1
add_logs(A, D, "stomach kneed (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/headKick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat && !D.weakened)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
D.visible_message("<span class='warning'>[A] kicks [D] in the head!</span>", \
"<span class='userdanger'>[A] kicks you in the jaw!</span>")
D.apply_damage(20, BRUTE, "head")
@@ -301,11 +328,12 @@
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 50, 1, -1)
D.Stun(4)
return 1
add_logs(A, D, "head kicked (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/proc/elbowDrop(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(D.weakened || D.resting || D.stat)
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
D.visible_message("<span class='warning'>[A] elbow drops [D]!</span>", \
"<span class='userdanger'>[A] piledrives you with their elbow!</span>")
if(D.stat)
@@ -313,6 +341,7 @@
D.apply_damage(50, BRUTE, "chest")
playsound(get_turf(D), 'sound/weapons/punch1.ogg', 75, 1, -1)
return 1
add_logs(A, D, "elbow dropped (Sleeping Carp)")
return basic_hit(A,D)
/datum/martial_art/the_sleeping_carp/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -324,18 +353,21 @@
else
A.start_pulling(D, 1)
if(A.pulling)
D.drop_r_hand()
D.drop_l_hand()
D.drop_all_held_items()
D.stop_pulling()
add_logs(A, D, "grabbed", addition="aggressively")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
if(A.a_intent == INTENT_GRAB)
add_logs(A, D, "grabbed", addition="aggressively")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
else
add_logs(A, D, "grabbed", addition="passively")
A.grab_state = GRAB_PASSIVE
return 1
/datum/martial_art/the_sleeping_carp/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("H",D)
if(check_streak(A,D))
return 1
A.do_attack_animation(D)
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
var/atk_verb = pick("punches", "kicks", "chops", "hits", "slams")
D.visible_message("<span class='danger'>[A] [atk_verb] [D]!</span>", \
"<span class='userdanger'>[A] [atk_verb] you!</span>")
@@ -344,6 +376,7 @@
if(prob(D.getBruteLoss()) && !D.lying)
D.visible_message("<span class='warning'>[D] stumbles and falls!</span>", "<span class='userdanger'>The blow sends you to the ground!</span>")
D.Weaken(4)
add_logs(A, D, "[atk_verb] (Sleeping Carp)")
return 1
@@ -366,6 +399,190 @@
usr << "<span class='notice'>Head Kick</span>: Disarm Harm Harm. Decent damage, forces opponent to drop item in hand."
usr << "<span class='notice'>Elbow Drop</span>: Harm Disarm Harm Disarm Harm. Opponent must be on the ground. Deals huge damage, instantly kills anyone in critical condition."
//CQC
#define SLAM_COMBO "GH"
#define KICK_COMBO "HH"
#define RESTRAIN_COMBO "GG"
#define PRESSURE_COMBO "DG"
#define CONSECUTIVE_COMBO "DDH"
/datum/martial_art/cqc
name = "CQC"
help_verb = /mob/living/carbon/human/proc/CQC_help
block_chance = 75
/datum/martial_art/cqc/proc/drop_restraining()
restraining = 0
/datum/martial_art/cqc/proc/check_streak(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(findtext(streak,SLAM_COMBO))
streak = ""
Slam(A,D)
return 1
if(findtext(streak,KICK_COMBO))
streak = ""
Kick(A,D)
return 1
if(findtext(streak,RESTRAIN_COMBO))
streak = ""
Restrain(A,D)
return 1
if(findtext(streak,PRESSURE_COMBO))
streak = ""
Pressure(A,D)
return 1
if(findtext(streak,CONSECUTIVE_COMBO))
streak = ""
Consecutive(A,D)
return 0
/datum/martial_art/cqc/proc/Slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat || !D.weakened)
D.visible_message("<span class='warning'>[A] slams [D] into the ground!</span>", \
"<span class='userdanger'>[A] slams you into the ground!</span>")
playsound(get_turf(A), 'sound/weapons/slam.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
D.Weaken(6)
add_logs(A, D, "cqc slammed")
return 1
/datum/martial_art/cqc/proc/Kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat || !D.weakened)
D.visible_message("<span class='warning'>[A] kicks [D] back!</span>", \
"<span class='userdanger'>[A] kicks you back!</span>")
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
var/atom/throw_target = get_edge_target_turf(D, A.dir)
D.throw_at(throw_target, 1, 14, A)
D.apply_damage(10, BRUTE)
add_logs(A, D, "cqc kicked")
if(D.weakened && D.stat != DEAD)
D.visible_message("<span class='warning'>[A] kicks [D]'s head, knocking them out!</span>", \
"<span class='userdanger'>[A] kicks your head, knocking you out!</span>")
playsound(get_turf(A), 'sound/weapons/genhit1.ogg', 50, 1, -1)
D.SetSleeping(15)
D.adjustBrainLoss(25)
return 1
/datum/martial_art/cqc/proc/Pressure(mob/living/carbon/human/A, mob/living/carbon/human/D)
D.visible_message("<span class='warning'>[A] forces their arm on [D]'s neck!</span>")
D.adjustStaminaLoss(60)
playsound(get_turf(A), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
return 1
/datum/martial_art/cqc/proc/Restrain(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(restraining)
return
if(!D.stat)
D.visible_message("<span class='warning'>[A] locks [D] into a restraining position!</span>", \
"<span class='userdanger'>[A] locks you into a restraining position!</span>")
D.adjustStaminaLoss(20)
D.Stun(5)
restraining = 1
addtimer(CALLBACK(src, .proc/drop_restraining), 50, TIMER_UNIQUE)
return 1
/datum/martial_art/cqc/proc/Consecutive(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D.stat)
D.visible_message("<span class='warning'>[A] strikes [D]'s abdomen, neck and back consecutively</span>", \
"<span class='userdanger'>[A] strikes your abdomen, neck and back consecutively!</span>")
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
var/obj/item/I = D.get_active_held_item()
if(I)
D.drop_item()
A.put_in_hands(I)
D.adjustStaminaLoss(50)
D.apply_damage(25, BRUTE)
return 1
/datum/martial_art/cqc/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("G",D)
if(check_streak(A,D))
return 1
if(A.grab_state >= GRAB_AGGRESSIVE)
D.grabbedby(A, 1)
else
A.start_pulling(D, 1)
if(A.pulling)
D.stop_pulling()
add_logs(A, D, "grabbed", addition="aggressively")
A.grab_state = GRAB_AGGRESSIVE //Instant aggressive grab
return 1
/datum/martial_art/cqc/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("H",D)
if(check_streak(A,D))
return 1
add_logs(A, D, "CQC'd")
A.do_attack_animation(D)
var/picked_hit_type = pick("CQC'd", "Big Bossed")
var/bonus_damage = 13
if(D.weakened || D.resting || D.lying)
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
playsound(get_turf(D), 'sound/weapons/cqchit2.ogg', 50, 1, -1)
else
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
add_logs(A, D, "[picked_hit_type] with CQC")
if(A.resting && !D.stat && !D.weakened)
D.visible_message("<span class='warning'>[A] leg sweeps [D]!", \
"<span class='userdanger'>[A] leg sweeps you!</span>")
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(10, BRUTE)
D.Weaken(3)
add_logs(A, D, "cqc sweeped")
return 1
/datum/martial_art/cqc/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
add_to_streak("D",D)
if(check_streak(A,D))
return 1
if(prob(65))
if(!D.stat || !D.weakened || !restraining)
var/obj/item/I = D.get_active_held_item()
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>")
playsound(get_turf(D), 'sound/weapons/cqchit1.ogg', 50, 1, -1)
if(I)
D.drop_item()
A.put_in_hands(I)
D.Jitter(2)
D.apply_damage(5, BRUTE)
else
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
add_logs(A, D, "disarmed with CQC")
if(restraining && A.pulling == D)
D.visible_message("<span class='danger'>[A] puts [D] into a chokehold!</span>", \
"<span class='userdanger'>[A] puts you into a chokehold!</span>")
D.SetSleeping(20)
restraining = 0
if(A.grab_state < GRAB_NECK)
A.grab_state = GRAB_NECK
else
restraining = 0
return 0
return 1
/mob/living/carbon/human/proc/CQC_help()
set name = "Recall Teachings"
set desc = "You try to remember some of the basics of CQC."
set category = "CQC"
usr << "<b><i>You try to remember some of the basics of CQC.</i></b>"
usr << "<span class='notice'>Slam</span>: Grab Harm. Slam opponent into the ground, weakens and knocks down."
usr << "<span class='notice'>CQC Kick</span>: Harm Disarm Harm. Knocks opponent away. Knocks out stunned or weakened opponents."
usr << "<span class='notice'>Restrain</span>: Grab Grab. Locks opponents into a restraining position, disarm to knock them out with a choke hold."
usr << "<span class='notice'>Pressure</span>: Disarm Grab. Decent stamina damage."
usr << "<span class='notice'>Consecutive CQC</span>: Harm Harm Disarm. Mainly offensive move, huge damage and decent stamina damage."
usr << "<b><i>In addition, by having your throw mode on when being attacked, you enter an active defense mode where you have a chance to block and sometimes even counter attacks done to you.</i></b>"
//ITEMS
/obj/item/clothing/gloves/boxing
@@ -427,6 +644,23 @@
name = "empty scroll"
icon_state = "blankscroll"
/obj/item/weapon/cqc_manual
name = "old manual"
desc = "A small, black manual. There are drawn instructions of tactical hand-to-hand combat."
icon = 'icons/obj/library.dmi'
icon_state ="cqcmanual"
/obj/item/weapon/cqc_manual/attack_self(mob/living/carbon/human/user)
if(!istype(user) || !user)
return
user <<"<span class='boldannounce'>You remember the basics of CQC.</span>"
var/datum/martial_art/cqc/D = new(null)
D.teach(user)
user.drop_item()
visible_message("<span class='warning'>[src] beeps ominously, and a moment later it bursts up in flames.</span>")
new /obj/effect/decal/cleanable/ash(get_turf(src))
qdel(src)
/obj/item/weapon/sleeping_carp_scroll
name = "mysterious scroll"
desc = "A scroll filled with strange markings. It seems to be drawings of some sort of martial art."
@@ -449,7 +683,7 @@
name = "bo staff"
desc = "A long, tall staff made of polished wood. Traditionally used in ancient old-Earth martial arts. Can be wielded to both kill and incapacitate."
force = 10
w_class = 4
w_class = WEIGHT_CLASS_BULKY
slot_flags = SLOT_BACK
force_unwielded = 10
force_wielded = 24
@@ -473,9 +707,9 @@
var/mob/living/carbon/human/H = user
H.apply_damage(2*force, BRUTE, "head")
else
user.take_organ_damage(2*force)
user.take_bodypart_damage(2*force)
return
if(isrobot(target))
if(iscyborg(target))
return ..()
if(!isliving(target))
return ..()
@@ -483,7 +717,7 @@
if(C.stat)
user << "<span class='warning'>It would be dishonorable to attack a foe while they cannot retaliate.</span>"
return
if(user.a_intent == "disarm")
if(user.a_intent == INTENT_DISARM)
if(!wielded)
return ..()
if(!ishuman(target))
@@ -505,7 +739,7 @@
H.Weaken(4)
if(H.staminaloss && !H.sleeping)
var/total_health = (H.health - H.staminaloss)
if(total_health <= config.health_threshold_crit && !H.stat)
if(total_health <= HEALTH_THRESHOLD_CRIT && !H.stat)
H.visible_message("<span class='warning'>[user] delivers a heavy hit to [H]'s head, knocking them out cold!</span>", \
"<span class='userdanger'>[user] knocks you unconscious!</span>")
H.SetSleeping(30)
@@ -516,4 +750,5 @@
/obj/item/weapon/twohanded/bostaff/hit_reaction(mob/living/carbon/human/owner, attack_text, final_block_chance)
if(wielded)
return ..()
return 0
return 0
+28 -21
View File
@@ -17,7 +17,7 @@
H.martial_art.streak = "neck_chop"
/datum/action/leg_sweep
name = "Leg Sweep - Trips the victim, rendering them prone and unable to move for a short time."
name = "Leg Sweep - Trips the victim, knocking them down for a brief moment."
button_icon_state = "legsweep"
/datum/action/leg_sweep/Trigger()
@@ -79,14 +79,17 @@
playsound(get_turf(A), 'sound/effects/hit_kick.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
D.Weaken(2)
add_logs(A, D, "leg sweeped")
return 1
/datum/martial_art/krav_maga/proc/quick_choke(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)//is actually lung punch
D.visible_message("<span class='warning'>[A] pounds [D] on the chest!</span>", \
"<span class='userdanger'>[A] slams your chest! You can't breathe!</span>")
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.losebreath += 5
if(D.losebreath <= 10)
D.losebreath = Clamp(D.losebreath + 5, 0, 10)
D.adjustOxyLoss(10)
add_logs(A, D, "quickchoked")
return 1
/datum/martial_art/krav_maga/proc/neck_chop(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
@@ -94,46 +97,45 @@
"<span class='userdanger'>[A] karate chops your neck, rendering you unable to speak!</span>")
playsound(get_turf(A), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.apply_damage(5, BRUTE)
D.silent += 10
if(D.silent <= 10)
D.silent = Clamp(D.silent + 10, 0, 10)
add_logs(A, D, "neck chopped")
return 1
datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
/datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
add_logs(A, D, "grabbed with krav maga")
..()
/datum/martial_art/krav_maga/harm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
add_logs(A, D, "punched")
A.do_attack_animation(D)
var/picked_hit_type = pick("punches", "kicks")
var/bonus_damage = 10
if(D.weakened || D.resting || D.lying)
bonus_damage += 5
picked_hit_type = "stomps on"
D.apply_damage(bonus_damage, BRUTE)
if(picked_hit_type == "kicks" || picked_hit_type == "stomps")
if(picked_hit_type == "kicks" || picked_hit_type == "stomps on")
A.do_attack_animation(D, ATTACK_EFFECT_KICK)
playsound(get_turf(D), 'sound/effects/hit_kick.ogg', 50, 1, -1)
else
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
playsound(get_turf(D), 'sound/effects/hit_punch.ogg', 50, 1, -1)
D.visible_message("<span class='danger'>[A] [picked_hit_type] [D]!</span>", \
"<span class='userdanger'>[A] [picked_hit_type] you!</span>")
add_logs(A, D, "[picked_hit_type] with Krav Maga")
return 1
/datum/martial_art/krav_maga/disarm_act(var/mob/living/carbon/human/A, var/mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
if(prob(60))
if(D.hand)
if(istype(D.l_hand, /obj/item))
var/obj/item/I = D.l_hand
D.drop_item()
A.put_in_hands(I)
else
if(istype(D.r_hand, /obj/item))
var/obj/item/I = D.r_hand
D.drop_item()
var/obj/item/I = D.get_active_held_item()
if(I)
if(D.drop_item())
A.put_in_hands(I)
D.visible_message("<span class='danger'>[A] has disarmed [D]!</span>", \
"<span class='userdanger'>[A] has disarmed [D]!</span>")
@@ -142,30 +144,35 @@ datum/martial_art/krav_maga/grab_act(var/mob/living/carbon/human/A, var/mob/livi
D.visible_message("<span class='danger'>[A] attempted to disarm [D]!</span>", \
"<span class='userdanger'>[A] attempted to disarm [D]!</span>")
playsound(D, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
add_logs(A, D, "disarmed with krav maga")
return 1
//Krav Maga Gloves
/obj/item/clothing/gloves/color/black/krav_maga
can_be_cut = 0
/obj/item/clothing/gloves/krav_maga
var/datum/martial_art/krav_maga/style = new
/obj/item/clothing/gloves/color/black/krav_maga/equipped(mob/user, slot)
/obj/item/clothing/gloves/krav_maga/equipped(mob/user, slot)
if(!ishuman(user))
return
if(slot == slot_gloves)
var/mob/living/carbon/human/H = user
style.teach(H,1)
/obj/item/clothing/gloves/color/black/krav_maga/dropped(mob/user)
/obj/item/clothing/gloves/krav_maga/dropped(mob/user)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.get_item_by_slot(slot_gloves) == src)
style.remove(H)
/obj/item/clothing/gloves/color/black/krav_maga/sec//more obviously named, given to sec
/obj/item/clothing/gloves/krav_maga/sec//more obviously named, given to sec
name = "krav maga gloves"
desc = "These gloves can teach you to perform Krav Maga using nanochips."
icon_state = "fightgloves"
item_state = "fightgloves"
item_state = "fightgloves"
cold_protection = HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
heat_protection = HANDS
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
resistance_flags = 0
+9 -3
View File
@@ -112,6 +112,7 @@
/datum/martial_art/wrestling/harm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
add_logs(A, D, "punched with wrestling")
..()
/datum/martial_art/wrestling/proc/throw_wrassle(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -181,9 +182,8 @@
if (T && isturf(T))
if (!D.stat)
D.emote("scream")
D.throw_at(T, 10, 4)
D.Weaken(2)
D.throw_at(T, 10, 4, callback = CALLBACK(D, /mob/living/carbon/human/.Weaken, 2))
add_logs(A, D, "has thrown with wrestling")
return 0
/datum/martial_art/wrestling/proc/slam(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -297,6 +297,7 @@
D.pixel_y = 0
add_logs(A, D, "body-slammed")
return 0
/datum/martial_art/wrestling/proc/strike(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -316,6 +317,7 @@
D.adjustBruteLoss(rand(10,20))
playsound(A.loc, "swing_hit", 50, 1)
D.Paralyse(1)
add_logs(A, D, "headbutted")
/datum/martial_art/wrestling/proc/kick(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D)
@@ -332,6 +334,7 @@
if (T && isturf(T))
D.Weaken(1)
D.throw_at(T, 3, 2)
add_logs(A, D, "roundhouse-kicked")
/datum/martial_art/wrestling/proc/drop(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(!D)
@@ -402,11 +405,13 @@
else
if (A)
A.pixel_y = 0
add_logs(A, D, "leg-dropped")
return
/datum/martial_art/wrestling/disarm_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
if(check_streak(A,D))
return 1
add_logs(A, D, "wrestling-disarmed")
..()
/datum/martial_art/wrestling/grab_act(mob/living/carbon/human/A, mob/living/carbon/human/D)
@@ -418,4 +423,5 @@
D.visible_message("<span class='danger'>[A] gets [D] in a cinch!</span>", \
"<span class='userdanger'>[A] gets [D] in a cinch!</span>")
D.Stun(rand(3,5))
add_logs(A, D, "cinched")
return 1
+20 -4
View File
@@ -26,7 +26,6 @@
for(var/mat_type in subtypesof(/datum/material))
var/datum/material/MT = mat_type
possible_mats[initial(MT.id)] = mat_type
for(var/id in mat_list)
if(possible_mats[id])
var/mat_path = possible_mats[id]
@@ -138,18 +137,18 @@
//For spawning mineral sheets; internal use only
/datum/material_container/proc/retrieve(sheet_amt, datum/material/M)
if(!M.sheet_type)
return 0
if(sheet_amt > 0)
if(M.amount < (sheet_amt * MINERAL_MATERIAL_AMOUNT))
sheet_amt = round(M.amount / MINERAL_MATERIAL_AMOUNT)
var/count = 0
while(sheet_amt > MAX_STACK_SIZE)
new M.sheet_type(get_turf(owner), MAX_STACK_SIZE)
count += MAX_STACK_SIZE
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
sheet_amt -= MAX_STACK_SIZE
if(round(M.amount / MINERAL_MATERIAL_AMOUNT))
if(round((sheet_amt * MINERAL_MATERIAL_AMOUNT) / MINERAL_MATERIAL_AMOUNT))
new M.sheet_type(get_turf(owner), sheet_amt)
count += sheet_amt
use_amount_type(sheet_amt * MINERAL_MATERIAL_AMOUNT, M.id)
@@ -216,11 +215,13 @@
var/amount = 0
var/id = null
var/sheet_type = null
var/coin_type = null
/datum/material/metal
name = "Metal"
id = MAT_METAL
sheet_type = /obj/item/stack/sheet/metal
coin_type = /obj/item/weapon/coin/iron
/datum/material/glass
name = "Glass"
@@ -231,28 +232,43 @@
name = "Silver"
id = MAT_SILVER
sheet_type = /obj/item/stack/sheet/mineral/silver
coin_type = /obj/item/weapon/coin/silver
/datum/material/gold
name = "Gold"
id = MAT_GOLD
sheet_type = /obj/item/stack/sheet/mineral/gold
coin_type = /obj/item/weapon/coin/gold
/datum/material/diamond
name = "Diamond"
id = MAT_DIAMOND
sheet_type = /obj/item/stack/sheet/mineral/diamond
coin_type = /obj/item/weapon/coin/diamond
/datum/material/uranium
name = "Uranium"
id = MAT_URANIUM
sheet_type = /obj/item/stack/sheet/mineral/uranium
coin_type = /obj/item/weapon/coin/uranium
/datum/material/plasma
name = "Solid Plasma"
id = MAT_PLASMA
sheet_type = /obj/item/stack/sheet/mineral/plasma
coin_type = /obj/item/weapon/coin/plasma
/datum/material/bananium
name = "Bananium"
id = MAT_BANANIUM
sheet_type = /obj/item/stack/sheet/mineral/bananium
coin_type = /obj/item/weapon/coin/clown
/datum/material/titanium
name = "Titanium"
id = MAT_TITANIUM
sheet_type = /obj/item/stack/sheet/mineral/titanium
/datum/material/biomass
name = "Biomass"
id = MAT_BIOMASS
+211 -432
View File
@@ -61,6 +61,7 @@
var/datum/devilinfo/devilinfo //Information about the devil, if any.
var/damnation_type = 0
var/datum/mind/soulOwner //who owns the soul. Under normal circumstances, this will point to src
var/isholy = FALSE //is this person a chaplain or admin role allowed to use bibles
var/mob/living/enslaved_to //If this mind's master is another mob (i.e. adamantine golems)
@@ -83,10 +84,16 @@
if(new_character.mind) //disassociate any mind currently in our new body's mind variable
new_character.mind.current = null
if(istype(current) && islist(current.antag_datums)) //wow apparently current isn't always living good fucking job SOMEONE
for(var/i in current.antag_datums)
var/datum/antagonist/D = i
D.transfer_to_new_body(new_character)
var/datum/atom_hud/antag/hud_to_transfer = antag_hud//we need this because leave_hud() will clear this list
leave_all_huds() //leave all the huds in the old body, so it won't get huds if somebody else enters it
current = new_character //associate ourself with our new body
new_character.mind = src //and associate our new body with ourself
if(iscarbon(new_character))
var/mob/living/carbon/C = new_character
C.last_mind = src
transfer_antag_huds(hud_to_transfer) //inherit the antag HUD
transfer_actions(new_character)
@@ -174,16 +181,6 @@
ticker.mode.remove_gangster(src,0,1,1)
remove_objectives()
/datum/mind/proc/remove_hog_follower_prophet()
ticker.mode.red_deity_followers -= src
ticker.mode.red_deity_prophets -= src
ticker.mode.blue_deity_prophets -= src
ticker.mode.blue_deity_followers -= src
ticker.mode.update_hog_icons_removed(src, "red")
ticker.mode.update_hog_icons_removed(src, "blue")
/datum/mind/proc/remove_antag_equip()
var/list/Mob_Contents = current.get_contents()
for(var/obj/item/I in Mob_Contents)
@@ -208,9 +205,36 @@
ticker.mode.update_wiz_icons_removed(src)
ticker.mode.update_cult_icons_removed(src)
ticker.mode.update_rev_icons_removed(src)
gang_datum.remove_gang_hud(src)
if(gang_datum)
gang_datum.remove_gang_hud(src)
//Link a new mobs mind to the creator of said mob. They will join any team they are currently on, and will only switch teams when their creator does.
/datum/mind/proc/enslave_mind_to_creator(mob/living/creator)
if(iscultist(creator))
ticker.mode.add_cultist(src)
else if(is_gangster(creator))
ticker.mode.add_gangster(src, creator.mind.gang_datum, TRUE)
else if(is_revolutionary_in_general(creator))
ticker.mode.add_revolutionary(src)
else if(is_servant_of_ratvar(creator))
add_servant_of_ratvar(current)
else if(is_nuclear_operative(creator))
make_Nuke(null, null, 0, FALSE)
enslaved_to = creator
current.faction = creator.faction.Copy()
if(creator.mind.special_role)
message_admins("[key_name_admin(current)](<A HREF='?_src_=holder;adminmoreinfo=\ref[current]'>?</A>) has been created by [key_name_admin(creator)](<A HREF='?_src_=holder;adminmoreinfo=\ref[creator]'>?</A>), an antagonist.")
current << "<span class='userdanger'>Despite your creators current allegiances, your true master remains [creator.real_name]. If their loyalities change, so do yours. This will never change unless your creator's body is destroyed.</span>"
/datum/mind/proc/show_memory(mob/recipient, window=1)
if(!recipient)
recipient = current
@@ -251,7 +275,7 @@
)
var/text = ""
if (istype(current, /mob/living/carbon/human) || istype(current, /mob/living/carbon/monkey))
if(ishuman(current))
/** REVOLUTION ***/
text = "revolution"
if (ticker.mode.config_tag=="revolution")
@@ -276,7 +300,7 @@
text += " <a href='?src=\ref[src];revolution=reequip'>Reequip</a> (gives traitor uplink)."
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];revolution=autoobjectives'>Set to kill all heads</a>."
else if(isloyal(current))
else if(current.isloyal())
text += "head|<b>LOYAL</b>|employee|<a href='?src=\ref[src];revolution=headrev'>headrev</a>|rev"
else if (src in ticker.mode.revolutionaries)
text += "head|loyal|<a href='?src=\ref[src];revolution=clear'>employee</a>|<a href='?src=\ref[src];revolution=headrev'>headrev</a>|<b>REV</b>"
@@ -295,7 +319,7 @@
if (ticker.mode.config_tag=="gang")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
text += "[isloyal(current) ? "<B>LOYAL</B>" : "loyal"]|"
text += "[current.isloyal() ? "<B>LOYAL</B>" : "loyal"]|"
if(src in ticker.mode.get_all_gangsters())
text += "<a href='?src=\ref[src];gang=clear'>none</a>"
else
@@ -330,100 +354,23 @@
sections["gang"] = text
/** CULT ***/
text = "cult"
if (ticker.mode.config_tag=="cult")
/** Abductors **/
text = "Abductor"
if(ticker.mode.config_tag == "abductor")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (src in ticker.mode.cult)
text += "loyal|<a href='?src=\ref[src];cult=clear'>employee</a>|<b>CULTIST</b>"
text += "<br>Give <a href='?src=\ref[src];cult=tome'>tome</a>|<a href='?src=\ref[src];cult=amulet'>amulet</a>."
/*
if (objectives.len==0)
text += "<br>Objectives are empty! Set to sacrifice and <a href='?src=\ref[src];cult=escape'>escape</a> or <a href='?src=\ref[src];cult=summon'>summon</a>."
*/
else if(isloyal(current))
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
if(src in ticker.mode.abductors)
text += "<b>Abductor</b>|<a href='?src=\ref[src];abductor=clear'>human</a>"
text += "|<a href='?src=\ref[src];common=undress'>undress</a>|<a href='?src=\ref[src];abductor=equip'>equip</a>"
else
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
text += "<a href='?src=\ref[src];abductor=abductor'>Abductor</a>|<b>human</b>"
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["cult"] = text
/** CLOCKWORK CULT **/
text = "clockwork cult"
if(ticker.mode.config_tag == "clockwork cult")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in ticker.mode.servants_of_ratvar)
text += "loyal|<a href='?src=\ref[src];clockcult=clear'>employee</a>|<b>SERVANT</b>"
text += "<br><a href='?src=\ref[src];clockcult=slab'>Give slab</a>"
else if(isloyal(current))
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
else
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
if(current && current.client && (ROLE_SERVANT_OF_RATVAR in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["clockcult"] = text
/** WIZARD ***/
text = "wizard"
if (ticker.mode.config_tag=="wizard")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if ((src in ticker.mode.wizards) || (src in ticker.mode.apprentices))
text += "<b>YES</b>|<a href='?src=\ref[src];wizard=clear'>no</a>"
text += "<br><a href='?src=\ref[src];wizard=lair'>To lair</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];wizard=dressup'>dress up</a>, <a href='?src=\ref[src];wizard=name'>let choose name</a>."
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];wizard=autoobjectives'>Randomize!</a>"
else
text += "<a href='?src=\ref[src];wizard=wizard'>yes</a>|<b>NO</b>"
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["wizard"] = text
/** CHANGELING ***/
text = "changeling"
if (ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if ((src in ticker.mode.changelings) && special_role)
text += "<b>YES</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
else if(src in ticker.mode.changelings) //Station Aligned Changeling
text += "<b>YES (but not an antag)</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
else
text += "<a href='?src=\ref[src];changeling=changeling'>yes</a>|<b>NO</b>"
// var/datum/game_mode/changeling/changeling = ticker.mode
// if (istype(changeling) && changeling.changelingdeath)
// text += "<br>All the changelings are dead! Restart in [round((changeling.TIME_TO_GET_REVIVED-(world.time-changeling.changelingdeathtime))/10)] seconds."
if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["changeling"] = text
sections["abductor"] = text
/** NUCLEAR ***/
text = "nuclear"
@@ -450,6 +397,71 @@
sections["nuclear"] = text
/** WIZARD ***/
text = "wizard"
if (ticker.mode.config_tag=="wizard")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if ((src in ticker.mode.wizards) || (src in ticker.mode.apprentices))
text += "<b>YES</b>|<a href='?src=\ref[src];wizard=clear'>no</a>"
text += "<br><a href='?src=\ref[src];wizard=lair'>To lair</a>, <a href='?src=\ref[src];common=undress'>undress</a>, <a href='?src=\ref[src];wizard=dressup'>dress up</a>, <a href='?src=\ref[src];wizard=name'>let choose name</a>."
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];wizard=autoobjectives'>Randomize!</a>"
else
text += "<a href='?src=\ref[src];wizard=wizard'>yes</a>|<b>NO</b>"
if(current && current.client && (ROLE_WIZARD in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["wizard"] = text
/** CULT ***/
text = "cult"
if (ticker.mode.config_tag=="cult")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(iscultist(current))
text += "loyal|<a href='?src=\ref[src];cult=clear'>employee</a>|<b>CULTIST</b>"
text += "<br>Give <a href='?src=\ref[src];cult=tome'>tome</a>|<a href='?src=\ref[src];cult=amulet'>amulet</a>."
else if(current.isloyal())
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
else if(is_convertable_to_cult(current))
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];cult=cultist'>cultist</a>"
else
text += "loyal|<b>EMPLOYEE</b>|<i>cannot serve Nar-Sie</i>"
if(current && current.client && (ROLE_CULTIST in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["cult"] = text
/** CLOCKWORK CULT **/
text = "clockwork cult"
if(ticker.mode.config_tag == "clockwork cult")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(is_servant_of_ratvar(current))
text += "loyal|<a href='?src=\ref[src];clockcult=clear'>employee</a>|<b>SERVANT</b>"
text += "<br><a href='?src=\ref[src];clockcult=slab'>Give slab</a>"
else if(current.isloyal())
text += "<b>LOYAL</b>|employee|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
else if(is_eligible_servant(current))
text += "loyal|<b>EMPLOYEE</b>|<a href='?src=\ref[src];clockcult=servant'>servant</a>"
else
text += "loyal|<b>EMPLOYEE</b>|<i>cannot serve Ratvar</i>"
if(current && current.client && (ROLE_SERVANT_OF_RATVAR in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["clockcult"] = text
/** TRAITOR ***/
text = "traitor"
if (ticker.mode.config_tag=="traitor" || ticker.mode.config_tag=="traitorchan")
@@ -469,66 +481,43 @@
sections["traitor"] = text
/** Abductors **/
if(ishuman(current) || ismonkey(current))
text = "Abductor"
if(ticker.mode.config_tag == "abductor")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in ticker.mode.abductors)
text += "<b>Abductor</b>|<a href='?src=\ref[src];abductor=clear'>human</a>"
text += "|<a href='?src=\ref[src];common=undress'>undress</a>|<a href='?src=\ref[src];abductor=equip'>equip</a>"
else
text += "<a href='?src=\ref[src];abductor=abductor'>Abductor</a>|<b>human</b>"
/** CHANGELING ***/
text = "changeling"
if (ticker.mode.config_tag=="changeling" || ticker.mode.config_tag=="traitorchan")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if ((src in ticker.mode.changelings) && special_role)
text += "<b>YES</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
else if(src in ticker.mode.changelings) //Station Aligned Changeling
text += "<b>YES (but not an antag)</b>|<a href='?src=\ref[src];changeling=clear'>no</a>"
if (objectives.len==0)
text += "<br>Objectives are empty! <a href='?src=\ref[src];changeling=autoobjectives'>Randomize!</a>"
if(changeling && changeling.stored_profiles.len && (current.real_name != changeling.first_prof.name) )
text += "<br><a href='?src=\ref[src];changeling=initialdna'>Transform to initial appearance.</a>"
else
text += "<a href='?src=\ref[src];changeling=changeling'>yes</a>|<b>NO</b>"
if(current && current.client && (ROLE_ABDUCTOR in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
if(current && current.client && (ROLE_CHANGELING in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["abductor"] = text
sections["changeling"] = text
/** HAND OF GOD **/
text = "hand of god"
if(ticker.mode.config_tag == "handofgod")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (src in ticker.mode.red_deities)
text += "<b>RED GOD</b>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
else if(src in ticker.mode.red_deity_prophets)
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<b>RED PROPHET</b>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
else if (src in ticker.mode.red_deity_followers)
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<b>RED FOLLOWER</b>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
else if (src in ticker.mode.blue_deities)
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<b>BLUE GOD</b>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
else if (src in ticker.mode.blue_deity_prophets)
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<b>BLUE PROPHET</b>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
else if (src in ticker.mode.blue_deity_followers)
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<a href='?src=\ref[src];handofgod=clear'>employee</a>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<b>BLUE FOLLOWER</b>"
else
text += "<a href='?src=\ref[src];handofgod=red_god'>red god</a>|<a href='?src=\ref[src];handofgod=red prophet'>red prophet</a>|<a href='?src=\ref[src];handofgod=red follower'>red follower</a>|<B>EMPLOYEE</b>|<a href='?src=\ref[src];handofgod=blue god'>blue god</a>|<a href='?src=\ref[src];handofgod=blue prophet'>blue prophet</a>|<a href='?src=\ref[src];handofgod=blue follower'>blue follower</a>"
if(current && current.client && (ROLE_HOG_GOD in current.client.prefs.be_special))
text += "|HOG God Enabled in Prefs"
else
text += "|HOG God Disabled in Prefs"
if(current && current.client && (ROLE_HOG_CULTIST in current.client.prefs.be_special))
text += "|HOG Cultist Enabled in Prefs"
else
text += "|HOG Disabled in Prefs"
sections["follower"] = text
/** MONKEY ***/
if (istype(current, /mob/living/carbon))
/** MONKEY ***/
text = "monkey"
if (ticker.mode.config_tag=="monkey")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if (istype(current, /mob/living/carbon/human))
if (ishuman(current))
text += "<a href='?src=\ref[src];monkey=healthy'>healthy</a>|<a href='?src=\ref[src];monkey=infected'>infected</a>|<b>HUMAN</b>|other"
else if (istype(current, /mob/living/carbon/monkey))
else if (ismonkey(current))
var/found = 0
for(var/datum/disease/D in current.viruses)
if(istype(D, /datum/disease/transformation/jungle_fever)) found = 1
@@ -569,7 +558,7 @@
/** SILICON ***/
if (istype(current, /mob/living/silicon))
if(issilicon(current))
text = "silicon"
var/mob/living/silicon/robot/robot = current
if (istype(robot) && robot.emagged)
@@ -597,10 +586,7 @@
out += sections[i]+"<br>"
if (((src in ticker.mode.head_revolutionaries) || \
(src in ticker.mode.traitors) || \
(src in ticker.mode.syndicates)) && \
istype(current,/mob/living/carbon/human) )
if(((src in ticker.mode.head_revolutionaries) || (src in ticker.mode.traitors) || (src in ticker.mode.syndicates)) && ishuman(current))
text = "Uplink: <a href='?src=\ref[src];common=uplink'>give</a>"
var/obj/item/device/uplink/U = find_syndicate_uplink()
@@ -666,7 +652,7 @@
if(!def_value)//If it's a custom objective, it will be an empty string.
def_value = "custom"
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom","follower block (HOG)","build (HOG)","deicide (HOG)", "follower escape (HOG)", "sacrifice prophet (HOG)")
var/new_obj_type = input("Select objective type:", "Objective type", def_value) as null|anything in list("assassinate", "maroon", "debrain", "protect", "destroy", "prevent", "hijack", "escape", "survive", "martyr", "steal", "download", "nuclear", "capture", "absorb", "custom")
if (!new_obj_type)
return
@@ -676,7 +662,7 @@
if ("assassinate","protect","debrain","maroon")
var/list/possible_targets = list("Free objective")
for(var/datum/mind/possible_target in ticker.minds)
if ((possible_target != src) && istype(possible_target.current, /mob/living/carbon/human))
if ((possible_target != src) && ishuman(possible_target.current))
possible_targets += possible_target.current
var/mob/def_target = null
@@ -768,22 +754,6 @@
new_objective.owner = src
new_objective.target_amount = target_number
if("follower block (HOG)")
new_objective = new /datum/objective/follower_block
new_objective.owner = src
if("build (HOG)")
new_objective = new /datum/objective/build
new_objective.owner = src
if("deicide (HOG)")
new_objective = new /datum/objective/deicide
new_objective.owner = src
if("follower escape (HOG)")
new_objective = new /datum/objective/escape_followers
new_objective.owner = src
if("sacrifice prophet (HOG)")
new_objective = new /datum/objective/sacrifice_prophet
new_objective.owner = src
if ("custom")
var/expl = stripped_input(usr, "Custom objective:", "Objective", objective ? objective.explanation_text : "")
if (!expl)
@@ -820,46 +790,6 @@
objective.completed = !objective.completed
log_admin("[key_name(usr)] toggled the win state for [current]'s objective: [objective.explanation_text]")
else if (href_list["handofgod"])
switch(href_list["handofgod"])
if("clear") //wipe handofgod status
if((src in ticker.mode.red_deity_followers) || (src in ticker.mode.blue_deity_followers) || (src in ticker.mode.red_deity_prophets) || (src in ticker.mode.blue_deity_prophets))
remove_hog_follower_prophet()
current << "<span class='danger'><B>You have been brainwashed... again! Your faith is no more!</B></span>"
message_admins("[key_name_admin(usr)] has de-hand of god'ed [current].")
log_admin("[key_name(usr)] has de-hand of god'ed [current].")
if("red follower")
make_Handofgod_follower("red")
message_admins("[key_name_admin(usr)] has red follower'ed [current].")
log_admin("[key_name(usr)] has red follower'ed [current].")
if("red prophet")
make_Handofgod_prophet("red")
message_admins("[key_name_admin(usr)] has red prophet'ed [current].")
log_admin("[key_name(usr)] has red prophet'ed [current].")
if("blue follower")
make_Handofgod_follower("blue")
message_admins("[key_name_admin(usr)] has blue follower'ed [current].")
log_admin("[key_name(usr)] has blue follower'ed [current].")
if("blue prophet")
make_Handofgod_prophet("blue")
message_admins("[key_name_admin(usr)] has blue prophet'ed [current].")
log_admin("[key_name(usr)] has blue prophet'ed [current].")
if("red god")
make_Handofgod_god("red")
message_admins("[key_name_admin(usr)] has red god'ed [current].")
log_admin("[key_name(usr)] has red god'ed [current].")
if("blue god")
make_Handofgod_god("blue")
message_admins("[key_name_admin(usr)] has blue god'ed [current].")
log_admin("[key_name(usr)] has blue god'ed [current].")
else if (href_list["revolution"])
switch(href_list["revolution"])
if("clear")
@@ -1174,30 +1104,38 @@
if("clear")
if(src in ticker.mode.devils)
if(istype(current,/mob/living/carbon/true_devil/))
usr << "<span class='warning'>This cannot be used on true or arch-devils.</span>"
else
ticker.mode.devils -= src
special_role = null
current << "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>"
RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt)
RemoveSpell(/obj/effect/proc_holder/spell/dumbfire/fireball/hellish)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_pitchfork)
message_admins("[key_name_admin(usr)] has de-devil'ed [current].")
devilinfo = null
log_admin("[key_name(usr)] has de-devil'ed [current].")
if(devilinfo)
devilinfo.regress_blood_lizard()
else
usr << "<span class='warning'>Something went wrong with removing the devil, we were unable to find an attached devilinfo.</span>."
ticker.mode.devils -= src
special_role = null
current << "<span class='userdanger'>Your infernal link has been severed! You are no longer a devil!</span>"
RemoveSpell(/obj/effect/proc_holder/spell/targeted/infernal_jaunt)
RemoveSpell(/obj/effect/proc_holder/spell/fireball/hellish)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/summon_contract)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/summon_pitchfork)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/conjure_item/violin)
message_admins("[key_name_admin(usr)] has de-devil'ed [current].")
devilinfo = null
if(issilicon(current))
var/mob/living/silicon/S = current
S.clear_law_sixsixsix(current)
log_admin("[key_name(usr)] has de-devil'ed [current].")
else if(src in ticker.mode.sintouched)
ticker.mode.sintouched -= src
message_admins("[key_name_admin(usr)] has de-sintouch'ed [current].")
log_admin("[key_name(usr)] has de-sintouch'ed [current].")
if("devil")
if(!ishuman(current))
usr << "<span class='warning'>This only works on humans!</span>"
if(!ishuman(current) && !iscyborg(current))
usr << "<span class='warning'>This only works on humans and cyborgs!</span>"
return
ticker.mode.devils += src
special_role = "devil"
ticker.mode.finalize_devil(src)
ticker.mode.add_devil_objectives(src, 2)
announceDevilLaws()
announce_objectives()
if("sintouched")
if(ishuman(current))
ticker.mode.sintouched += src
@@ -1288,7 +1226,7 @@
log_admin("[key_name(usr)] has unemag'ed [R].")
if("unemagcyborgs")
if (istype(current, /mob/living/silicon/ai))
if(isAI(current))
var/mob/living/silicon/ai/ai = current
for (var/mob/living/silicon/robot/R in ai.connected_robots)
R.SetEmagged(0)
@@ -1299,7 +1237,7 @@
switch(href_list["common"])
if("undress")
for(var/obj/item/W in current)
current.unEquip(W, 1) //The 1 forces all items to drop, since this is an admin undress.
current.dropItemToGround(W, TRUE) //The 1 forces all items to drop, since this is an admin undress.
if("takeuplink")
take_uplink()
memory = null//Remove any memory they may have had.
@@ -1319,14 +1257,18 @@
log_admin("[key_name(usr)] attempted to give [current] an uplink.")
else if (href_list["obj_announce"])
var/obj_count = 1
current << "<span class='notice'>Your current objectives:</span>"
for(var/datum/objective/objective in objectives)
current << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
obj_count++
announce_objectives()
edit_memory()
/datum/mind/proc/announce_objectives()
var/obj_count = 1
current << "<span class='notice'>Your current objectives:</span>"
for(var/objective in objectives)
var/datum/objective/O = objective
current << "<B>Objective #[obj_count]</B>: [O.explanation_text]"
obj_count++
/datum/mind/proc/find_syndicate_uplink()
var/list/L = current.get_contents()
for (var/obj/item/I in L)
@@ -1347,32 +1289,42 @@
ticker.mode.finalize_traitor(src)
ticker.mode.greet_traitor(src)
/datum/mind/proc/make_Nuke(turf/spawnloc,nuke_code,leader=0, telecrystals = TRUE)
/datum/mind/proc/make_Nuke(turf/spawnloc, nuke_code, leader=0, telecrystals = TRUE)
if(!(src in ticker.mode.syndicates))
ticker.mode.syndicates += src
ticker.mode.update_synd_icons_added(src)
special_role = "Syndicate"
ticker.mode.forge_syndicate_objectives(src)
ticker.mode.greet_syndicate(src)
current.faction |= "syndicate"
current.loc = spawnloc
if(spawnloc)
current.loc = spawnloc
var/mob/living/carbon/human/H = current
qdel(H.belt)
qdel(H.back)
qdel(H.ears)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_suit)
qdel(H.w_uniform)
if(ishuman(current))
var/mob/living/carbon/human/H = current
qdel(H.belt)
qdel(H.back)
qdel(H.ears)
qdel(H.gloves)
qdel(H.head)
qdel(H.shoes)
qdel(H.wear_id)
qdel(H.wear_suit)
qdel(H.w_uniform)
ticker.mode.equip_syndicate(current, telecrystals)
ticker.mode.equip_syndicate(current, telecrystals)
if (nuke_code)
store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke_code]", 0, 0)
current << "The nuclear authorization code is: <B>[nuke_code]</B>"
else
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in nuke_list
if(nuke)
store_memory("<B>Syndicate Nuclear Bomb Code</B>: [nuke.r_code]", 0, 0)
current << "The nuclear authorization code is: <B>nuke.r_code</B>"
else
current << "You were not provided with a nuclear code. Trying asking your team leader or contacting syndicate command.</B>"
if (leader)
ticker.mode.prepare_syndicate_leader(src,nuke_code)
@@ -1393,7 +1345,6 @@
ticker.mode.wizards += src
special_role = "Wizard"
assigned_role = "Wizard"
//ticker.mode.learn_basic_spells(current)
if(!wizardstart.len)
current.loc = pick(latejoin)
current << "HOT INSERTION, GO GO GO"
@@ -1401,8 +1352,6 @@
current.loc = pick(wizardstart)
ticker.mode.equip_wizard(current)
for(var/obj/item/weapon/spellbook/S in current.contents)
S.op = 0
ticker.mode.name_wizard(current)
ticker.mode.forge_wizard_objectives(src)
ticker.mode.greet_wizard(src)
@@ -1421,9 +1370,7 @@
else
var/explanation = "Summon Nar-Sie via the use of the appropriate rune (Hell join self). It will only work if nine cultists stand on and around it."
current << "<B>Objective #1</B>: [explanation]"
current.memory += "<B>Objective #1</B>: [explanation]<BR>"
current << "The convert rune is join blood self"
current.memory += "The convert rune is join blood self<BR>"
memory += "<B>Objective #1</B>: [explanation]<BR>"
var/mob/living/carbon/human/H = current
if (!ticker.mode.equip_cultist(current))
@@ -1517,119 +1464,6 @@
L = agent_landmarks[team]
H.loc = L.loc
/datum/mind/proc/make_Handofgod_follower(colour)
. = 0
switch(colour)
if("red")
//Remove old allegiances
if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
current << "<span class='danger'><B>You are no longer a member of the Blue cult!<B></span>"
ticker.mode.blue_deity_followers -= src
ticker.mode.blue_deity_prophets -= src
current.faction |= "red god"
current.faction -= "blue god"
if(src in ticker.mode.red_deity_prophets)
current << "<span class='danger'><B>You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!</b></span>"
ticker.mode.red_deity_prophets -= src
ticker.mode.red_deity_followers |= src
current << "<span class='danger'><B>You are now a follower of the red cult's god!</b></span>"
special_role = "Hand of God: Red Follower"
. = 1
if("blue")
//Remove old allegiances
if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
current << "<span class='danger'><B>You are no longer a member of the Red cult!<B></span>"
ticker.mode.red_deity_followers -= src
ticker.mode.red_deity_prophets -= src
current.faction -= "red god"
current.faction |= "blue god"
if(src in ticker.mode.blue_deity_prophets)
current << "<span class='danger'><B>You have lost the connection with your deity, but you still believe in their grand design, You are no longer a prophet!</b></span>"
ticker.mode.blue_deity_prophets -= src
ticker.mode.blue_deity_followers |= src
current << "<span class='danger'><B>You are now a follower of the blue cult's god!</b></span>"
special_role = "Hand of God: Blue Follower"
. = 1
else
return 0
ticker.mode.update_hog_icons_removed(src,"red")
ticker.mode.update_hog_icons_removed(src,"blue")
//ticker.mode.greet_hog_follower(src,colour)
ticker.mode.update_hog_icons_added(src, colour)
/datum/mind/proc/make_Handofgod_prophet(colour)
. = 0
switch(colour)
if("red")
//Remove old allegiances
if(src in ticker.mode.blue_deity_followers || src in ticker.mode.blue_deity_prophets)
current << "<span class='danger'><B>You are no longer a member of the Blue cult!<B></span>"
current.faction -= "blue god"
current.faction |= "red god"
ticker.mode.blue_deity_followers -= src
ticker.mode.blue_deity_prophets -= src
ticker.mode.red_deity_followers -= src
ticker.mode.red_deity_prophets |= src
current << "<span class='danger'><B>You are now a prophet of the red cult's god!</b></span>"
special_role = "Hand of God: Red Prophet"
. = 1
if("blue")
//Remove old allegiances
if(src in ticker.mode.red_deity_followers || src in ticker.mode.red_deity_prophets)
current << "<span class='danger'><B>You are no longer a member of the Red cult!<B></span>"
current.faction -= "red god"
current.faction |= "blue god"
ticker.mode.red_deity_followers -= src
ticker.mode.red_deity_prophets -= src
ticker.mode.blue_deity_followers -= src
ticker.mode.blue_deity_prophets |= src
current << "<span class='danger'><B>You are now a prophet of the blue cult's god!</b></span>"
special_role = "Hand of God: Blue Prophet"
. = 1
else
return 0
ticker.mode.update_hog_icons_removed(src,"red")
ticker.mode.update_hog_icons_removed(src,"blue")
ticker.mode.greet_hog_follower(src,colour)
ticker.mode.update_hog_icons_added(src, colour)
/datum/mind/proc/make_Handofgod_god(colour)
switch(colour)
if("red")
current.become_god("red")
ticker.mode.add_god(src,"red")
if("blue")
current.become_god("blue")
ticker.mode.add_god(src,"blue")
else
return 0
ticker.mode.forge_deity_objectives(src)
ticker.mode.remove_hog_follower(src,0)
ticker.mode.update_hog_icons_added(src, colour)
// ticker.mode.greet_hog_follower(src,colour)
return 1
/datum/mind/proc/AddSpell(obj/effect/proc_holder/spell/S)
spell_list += S
S.action.Grant(current)
@@ -1661,7 +1495,7 @@
if(istype(S, type))
continue
S.charge_counter = delay
addtimer(S, "start_recharge", 0)
INVOKE_ASYNC(S, /obj/effect/proc_holder/spell.proc/start_recharge)
/datum/mind/proc/get_ghost(even_if_they_cant_reenter)
for(var/mob/dead/observer/G in dead_mob_list)
@@ -1698,53 +1532,24 @@
else
spawn(0)
throw EXCEPTION("mind_initialize(): No ticker ready")
if(!mind.name) mind.name = real_name
if(!mind.name)
mind.name = real_name
mind.current = src
/mob/living/carbon/mind_initialize()
..()
last_mind = mind
//HUMAN
/mob/living/carbon/human/mind_initialize()
..()
if(!mind.assigned_role) mind.assigned_role = "Assistant" //defualt
//MONKEY
/mob/living/carbon/monkey/mind_initialize()
..()
//slime
/mob/living/simple_animal/slime/mind_initialize()
..()
mind.special_role = "slime"
mind.assigned_role = "slime"
if(!mind.assigned_role)
mind.assigned_role = "Assistant" //defualt
//XENO
/mob/living/carbon/alien/mind_initialize()
..()
mind.special_role = "Alien"
mind.assigned_role = "Alien"
//XENO HUMANOID
/mob/living/carbon/alien/humanoid/royal/queen/mind_initialize()
..()
mind.special_role = "Queen"
/mob/living/carbon/alien/humanoid/royal/praetorian/mind_initialize()
..()
mind.special_role = "Praetorian"
/mob/living/carbon/alien/humanoid/hunter/mind_initialize()
..()
mind.special_role = "Hunter"
/mob/living/carbon/alien/humanoid/drone/mind_initialize()
..()
mind.special_role = "Drone"
/mob/living/carbon/alien/humanoid/sentinel/mind_initialize()
..()
mind.special_role = "Sentinel"
//XENO LARVA
/mob/living/carbon/alien/larva/mind_initialize()
..()
mind.special_role = "Larva"
//AI
/mob/living/silicon/ai/mind_initialize()
@@ -1761,29 +1566,3 @@
..()
mind.assigned_role = "pAI"
mind.special_role = ""
//BLOB
/mob/camera/blob/mind_initialize()
..()
mind.special_role = "Blob"
//Animals
/mob/living/simple_animal/mind_initialize()
..()
mind.assigned_role = "Animal"
mind.special_role = "Animal"
/mob/living/simple_animal/pet/dog/corgi/mind_initialize()
..()
mind.assigned_role = "Corgi"
mind.special_role = "Corgi"
/mob/living/simple_animal/shade/mind_initialize()
..()
mind.assigned_role = "Shade"
mind.special_role = "Shade"
/mob/living/simple_animal/hostile/construct/mind_initialize()
..()
mind.assigned_role = "[initial(name)]"
mind.special_role = "Cultist"
+23 -15
View File
@@ -1,6 +1,6 @@
/var/global/list/mutations_list = list()
/datum/mutation/
/datum/mutation
var/name
@@ -48,9 +48,9 @@
if(hex2num(getblock(se_string, dna_block)) >= lowest_value)
return 1
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner)
/datum/mutation/human/proc/check_block(mob/living/carbon/human/owner, force_powers=0)
if(check_block_string(owner.dna.struc_enzymes))
if(prob(get_chance))
if(prob(get_chance)||force_powers)
. = on_acquiring(owner)
else
. = on_losing(owner)
@@ -79,7 +79,7 @@
/datum/mutation/human/proc/get_visual_indicator(mob/living/carbon/human/owner)
return
/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target)
/datum/mutation/human/proc/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
return
/datum/mutation/human/proc/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
@@ -130,8 +130,9 @@
owner.status_flags &= ~status
owner.update_body_parts()
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target)
return target.attack_hulk(owner)
/datum/mutation/human/hulk/on_attack_hand(mob/living/carbon/human/owner, atom/target, proximity)
if(proximity) //no telekinetic hulk attack
return target.attack_hulk(owner)
/datum/mutation/human/hulk/on_life(mob/living/carbon/human/owner)
if(owner.health < 0)
@@ -160,7 +161,7 @@
/datum/mutation/human/telekinesis/New()
..()
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="telekinesishead_s", "layer"=-MUTATIONS_LAYER)
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="telekinesishead", "layer"=-MUTATIONS_LAYER)
/datum/mutation/human/telekinesis/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
@@ -179,7 +180,7 @@
/datum/mutation/human/cold_resistance/New()
..()
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="fire_s", "layer"=-MUTATIONS_LAYER)
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="fire", "layer"=-MUTATIONS_LAYER)
/datum/mutation/human/cold_resistance/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
@@ -187,7 +188,7 @@
/datum/mutation/human/cold_resistance/on_life(mob/living/carbon/human/owner)
if(owner.getFireLoss())
if(prob(1))
owner.heal_organ_damage(0,1) //Is this really needed?
owner.heal_bodypart_damage(0,1) //Is this really needed?
/datum/mutation/human/x_ray
@@ -236,7 +237,7 @@
owner.visible_message("<span class='danger'>[owner] starts having a seizure!</span>", "<span class='userdanger'>You have a seizure!</span>")
owner.Paralyse(10)
owner.Jitter(1000)
addtimer(src, "jitter_less", 90, FALSE, owner)
addtimer(CALLBACK(src, .proc/jitter_less, owner), 90)
/datum/mutation/human/epilepsy/proc/jitter_less(mob/living/carbon/human/owner)
if(owner)
@@ -252,11 +253,11 @@
var/mob/new_mob
if(prob(95))
if(prob(50))
new_mob = randmutb(owner)
new_mob = owner.randmutb()
else
new_mob = randmuti(owner)
new_mob = owner.randmuti()
else
new_mob = randmutg(owner)
new_mob = owner.randmutg()
if(new_mob && ismob(new_mob))
owner = new_mob
. = owner
@@ -376,6 +377,9 @@
time_coeff = 2
/datum/mutation/human/race/on_acquiring(mob/living/carbon/human/owner)
if(owner.has_brain_worms())
owner << "<span class='warning'>You feel something strongly clinging to your humanity!</span>"
return
if(..())
return
. = owner.monkeyize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_KEEPSE)
@@ -531,6 +535,10 @@
/datum/mutation/human/swedish/say_mod(message)
if(message)
message = replacetext(message,"w","v")
message = replacetext(message,"j","y")
message = replacetext(message,"a",pick("å","ä","æ","a"))
message = replacetext(message,"bo","bjo")
message = replacetext(message,"o",pick("ö","ø","o"))
if(prob(30))
message += " Bork[pick("",", bork",", bork, bork")]!"
return message
@@ -610,13 +618,13 @@
/datum/mutation/human/laser_eyes/New()
..()
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes_s", "layer"=-FRONT_MUTATIONS_LAYER)
visual_indicators |= image("icon"='icons/effects/genetics.dmi', "icon_state"="lasereyes", "layer"=-FRONT_MUTATIONS_LAYER)
/datum/mutation/human/laser_eyes/get_visual_indicator(mob/living/carbon/human/owner)
return visual_indicators[1]
/datum/mutation/human/laser_eyes/on_ranged_attack(mob/living/carbon/human/owner, atom/target)
if(owner.a_intent == "harm")
if(owner.a_intent == INTENT_HARM)
owner.LaserEyes(target)
+67 -9
View File
@@ -9,6 +9,7 @@
var/shoes = null
var/head = null
var/mask = null
var/neck = null
var/ears = null
var/glasses = null
var/id = null
@@ -17,6 +18,7 @@
var/suit_store = null
var/r_hand = null
var/l_hand = null
var/internals_slot = null //ID of slot containing a gas tank
var/list/backpack_contents = list() // In the list(path=count,otherpath=count) format
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
@@ -47,16 +49,14 @@
H.equip_to_slot_or_del(new head(H),slot_head)
if(mask)
H.equip_to_slot_or_del(new mask(H),slot_wear_mask)
if(neck)
H.equip_to_slot_or_del(new neck(H),slot_neck)
if(ears)
H.equip_to_slot_or_del(new ears(H),slot_ears)
if(glasses)
H.equip_to_slot_or_del(new glasses(H),slot_glasses)
if(id)
H.equip_to_slot_or_del(new id(H),slot_wear_id)
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),slot_s_store)
@@ -65,11 +65,69 @@
if(r_hand)
H.put_in_r_hand(new r_hand(H))
for(var/path in backpack_contents)
var/number = backpack_contents[path]
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H),slot_l_store)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),slot_r_store)
for(var/path in backpack_contents)
var/number = backpack_contents[path]
for(var/i=0,i<number,i++)
H.equip_to_slot_or_del(new path(H),slot_in_backpack)
if(!H.head && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
HS.ToggleHelmet()
post_equip(H, visualsOnly)
return 1
if(!visualsOnly)
apply_fingerprints(H)
if(internals_slot)
H.internal = H.get_item_by_slot(internals_slot)
H.update_action_buttons_icon()
H.update_body()
return 1
/datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H)
if(!istype(H))
return
if(H.back)
H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves
for(var/obj/item/I in H.back.contents)
I.add_fingerprint(H,1)
if(H.wear_id)
H.wear_id.add_fingerprint(H,1)
if(H.w_uniform)
H.w_uniform.add_fingerprint(H,1)
if(H.wear_suit)
H.wear_suit.add_fingerprint(H,1)
if(H.wear_mask)
H.wear_mask.add_fingerprint(H,1)
if(H.wear_neck)
H.wear_neck.add_fingerprint(H,1)
if(H.head)
H.head.add_fingerprint(H,1)
if(H.shoes)
H.shoes.add_fingerprint(H,1)
if(H.gloves)
H.gloves.add_fingerprint(H,1)
if(H.ears)
H.ears.add_fingerprint(H,1)
if(H.glasses)
H.glasses.add_fingerprint(H,1)
if(H.belt)
H.belt.add_fingerprint(H,1)
for(var/obj/item/I in H.belt.contents)
I.add_fingerprint(H,1)
if(H.s_store)
H.s_store.add_fingerprint(H,1)
if(H.l_store)
H.l_store.add_fingerprint(H,1)
if(H.r_store)
H.r_store.add_fingerprint(H,1)
for(var/obj/item/I in H.held_items)
I.add_fingerprint(H,1)
return 1
+28 -2
View File
@@ -1,9 +1,12 @@
#define PROGRESSBAR_HEIGHT 6
/datum/progressbar
var/goal = 1
var/image/bar
var/shown = 0
var/mob/user
var/client/client
var/listindex
/datum/progressbar/New(mob/User, goal_number, atom/target)
. = ..()
@@ -11,13 +14,20 @@
EXCEPTION("Invalid target given")
if (goal_number)
goal = goal_number
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0")
bar = image('icons/effects/progessbar.dmi', target, "prog_bar_0", HUD_LAYER)
bar.plane = HUD_PLANE
bar.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
bar.pixel_y = 32
user = User
if(user)
client = user.client
LAZYINITLIST(user.progressbars)
LAZYINITLIST(user.progressbars[bar.loc])
var/list/bars = user.progressbars[bar.loc]
bars.Add(src)
listindex = bars.len
bar.pixel_y = 32 + (PROGRESSBAR_HEIGHT * (listindex - 1))
/datum/progressbar/proc/update(progress)
//world << "Update [progress] - [goal] - [(progress / goal)] - [((progress / goal) * 100)] - [round(((progress / goal) * 100), 5)]"
if (!user || !user.client)
@@ -35,8 +45,24 @@
user.client.images += bar
shown = 1
/datum/progressbar/proc/shiftDown()
--listindex
bar.pixel_y -= PROGRESSBAR_HEIGHT
/datum/progressbar/Destroy()
for(var/I in user.progressbars[bar.loc])
var/datum/progressbar/P = I
if(P != src && P.listindex > listindex)
P.shiftDown()
var/list/bars = user.progressbars[bar.loc]
bars.Remove(src)
if(!bars.len)
LAZYREMOVE(user.progressbars, bar.loc)
if (client)
client.images -= bar
qdel(bar)
. = ..()
#undef PROGRESSBAR_HEIGHT
+6 -6
View File
@@ -34,7 +34,7 @@
* */
/datum/recipe
var/list/reagents // example: = list("berryjuice" = 5) // do not list same reagent twice
var/list/reagents_list // example: = list("berryjuice" = 5) // do not list same reagent twice
var/list/items // example: =list(/obj/item/weapon/crowbar, /obj/item/weapon/welder) // place /foo/bar before /foo
var/result //example: = /obj/item/weapon/reagent_containers/food/snacks/donut
var/time = 100 // 1/10 part of second
@@ -42,14 +42,14 @@
/datum/recipe/proc/check_reagents(datum/reagents/avail_reagents) //1=precisely, 0=insufficiently, -1=superfluous
. = 1
for (var/r_r in reagents)
for (var/r_r in reagents_list)
var/aval_r_amnt = avail_reagents.get_reagent_amount(r_r)
if (!(abs(aval_r_amnt - reagents[r_r])<0.5)) //if NOT equals
if (aval_r_amnt>reagents[r_r])
if (!(abs(aval_r_amnt - reagents_list[r_r])<0.5)) //if NOT equals
if (aval_r_amnt>reagents_list[r_r])
. = -1
else
return 0
if ((reagents?(reagents.len):(0)) < avail_reagents.reagent_list.len)
if ((reagents_list?(reagents_list.len):(0)) < avail_reagents.reagent_list.len)
return -1
return .
@@ -112,7 +112,7 @@
. = possible_recipes[1]
for (var/datum/recipe/recipe in possible_recipes)
var/N_i = (recipe.items)?(recipe.items.len):0
var/N_r = (recipe.reagents)?(recipe.reagents.len):0
var/N_r = (recipe.reagents_list)?(recipe.reagents_list.len):0
if (N_i > i_count || (N_i== i_count && N_r > r_count ))
r_count = N_r
i_count = N_i
+299
View File
@@ -0,0 +1,299 @@
/datum/riding
var/generic_pixel_x = 0 //All dirs show this pixel_x for the driver
var/generic_pixel_y = 0 //All dirs show this pixel_y for the driver, use these vars if the pixel shift is stable across all dir, override handle_vehicle_offsets otherwise.
var/next_vehicle_move = 0 //used for move delays
var/vehicle_move_delay = 2 //tick delay between movements, lower = faster, higher = slower
var/keytype = null
var/atom/movable/ridden = null
var/slowed = FALSE
var/slowvalue = 1
/datum/riding/proc/handle_vehicle_layer()
if(ridden.dir != NORTH)
ridden.layer = ABOVE_MOB_LAYER
else
ridden.layer = OBJ_LAYER
//Override this to set your vehicle's various pixel offsets
//if they differ between directions, otherwise use the
//generic variables
/datum/riding/proc/handle_vehicle_offsets()
if(ridden.has_buckled_mobs())
for(var/m in ridden.buckled_mobs)
var/mob/living/buckled_mob = m
buckled_mob.setDir(ridden.dir)
buckled_mob.pixel_x = generic_pixel_x
buckled_mob.pixel_y = generic_pixel_y
//KEYS
/datum/riding/proc/keycheck(mob/user)
if(keytype)
if(user.is_holding_item_of_type(keytype))
return TRUE
else
return TRUE
return FALSE
//BUCKLE HOOKS
/datum/riding/proc/restore_position(mob/living/buckled_mob)
if(istype(buckled_mob))
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
buckled_mob.client.view = world.view
//MOVEMENT
/datum/riding/proc/handle_ride(mob/user, direction)
if(user.incapacitated())
ridden.unbuckle_mob(user)
return
if(world.time < next_vehicle_move)
return
next_vehicle_move = world.time + vehicle_move_delay
if(keycheck(user))
if(!Process_Spacemove(direction) || !isturf(ridden.loc))
return
step(ridden, direction)
handle_vehicle_layer()
handle_vehicle_offsets()
else
user << "<span class='notice'>You'll need the keys in one of your hands to drive \the [ridden.name].</span>"
/datum/riding/proc/Process_Spacemove(direction)
if(ridden.has_gravity())
return 1
if(ridden.pulledby)
return 1
return 0
/datum/riding/space/Process_Spacemove(direction)
return 1
//atv
/datum/riding/atv
keytype = /obj/item/key
generic_pixel_x = 0
generic_pixel_y = 4
vehicle_move_delay = 1
/datum/riding/atv/handle_vehicle_layer()
if(ridden.dir == SOUTH)
ridden.layer = ABOVE_MOB_LAYER
else
ridden.layer = OBJ_LAYER
/datum/riding/atv/turret
var/obj/machinery/porta_turret/syndicate/vehicle_turret/turret = null
/datum/riding/atv/turret/handle_vehicle_layer()
if(ridden.dir == SOUTH)
ridden.layer = ABOVE_MOB_LAYER
else
ridden.layer = OBJ_LAYER
if(turret)
if(ridden.dir == NORTH)
turret.layer = ABOVE_MOB_LAYER
else
turret.layer = OBJ_LAYER
/datum/riding/atv/turret/handle_vehicle_offsets()
..()
if(turret)
turret.forceMove(get_turf(ridden))
switch(ridden.dir)
if(NORTH)
turret.pixel_x = 0
turret.pixel_y = 4
if(EAST)
turret.pixel_x = -12
turret.pixel_y = 4
if(SOUTH)
turret.pixel_x = 0
turret.pixel_y = 4
if(WEST)
turret.pixel_x = 12
turret.pixel_y = 4
//pimpin ride
/datum/riding/janicart
keytype = /obj/item/key/janitor
/datum/riding/janicart/handle_vehicle_offsets()
..()
if(ridden.has_buckled_mobs())
for(var/m in ridden.buckled_mobs)
var/mob/living/buckled_mob = m
switch(buckled_mob.dir)
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -12
buckled_mob.pixel_y = 7
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 7
if(WEST)
buckled_mob.pixel_x = 12
buckled_mob.pixel_y = 7
//scooter
/datum/riding/scooter/handle_vehicle_layer()
if(ridden.dir == SOUTH)
ridden.layer = ABOVE_MOB_LAYER
else
ridden.layer = OBJ_LAYER
/datum/riding/scooter/handle_vehicle_offsets()
..()
if(ridden.has_buckled_mobs())
for(var/m in ridden.buckled_mobs)
var/mob/living/buckled_mob = m
switch(buckled_mob.dir)
if(NORTH)
buckled_mob.pixel_x = 0
if(EAST)
buckled_mob.pixel_x = -2
if(SOUTH)
buckled_mob.pixel_x = 0
if(WEST)
buckled_mob.pixel_x = 2
if(buckled_mob.get_num_legs() > 0)
buckled_mob.pixel_y = 5
else
buckled_mob.pixel_y = -4
/datum/riding/proc/account_limbs(mob/living/M)
if(M.get_num_legs() < 2 && !slowed)
vehicle_move_delay = vehicle_move_delay + slowvalue
slowed = TRUE
else if(slowed)
vehicle_move_delay = vehicle_move_delay - slowvalue
slowed = FALSE
/datum/riding/scooter/skateboard
vehicle_move_delay = 0//fast
//secway
/datum/riding/secway
keytype = /obj/item/key/security
generic_pixel_x = 0
generic_pixel_y = 4
//speedbike
/datum/riding/space/speedbike
keytype = null
vehicle_move_delay = 0
/datum/riding/space/speedbike/handle_vehicle_layer()
switch(ridden.dir)
if(NORTH,SOUTH)
ridden.pixel_x = -16
ridden.pixel_y = -16
if(EAST,WEST)
ridden.pixel_x = -18
ridden.pixel_y = 0
/datum/riding/space/speedbike/handle_vehicle_offsets()
if(ridden.has_buckled_mobs())
for(var/m in ridden.buckled_mobs)
var/mob/living/buckled_mob = m
buckled_mob.setDir(ridden.dir)
switch(ridden.dir)
if(NORTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = -8
if(SOUTH)
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 4
if(EAST)
buckled_mob.pixel_x = -10
buckled_mob.pixel_y = 5
if(WEST)
buckled_mob.pixel_x = 10
buckled_mob.pixel_y = 5
//SPEEDUWAGON
/datum/riding/space/speedbike/speedwagon/handle_vehicle_offsets()
if(ridden.has_buckled_mobs())
for(var/m in ridden.buckled_mobs)
var/mob/living/buckled_mob = m
buckled_mob.setDir(ridden.dir)
switch(ridden.dir)
if(NORTH)
buckled_mob.pixel_x = -5
buckled_mob.pixel_y = -5
if(SOUTH)
buckled_mob.pixel_x = 5
buckled_mob.pixel_y = 3
if(EAST)
buckled_mob.pixel_x = -8
buckled_mob.pixel_y = 5
if(WEST)
buckled_mob.pixel_x = 8
buckled_mob.pixel_y = 5
///////////////BOATS////////////
/datum/riding/boat
keytype = /obj/item/weapon/oar
/datum/riding/boat/handle_ride(mob/user, direction)
var/turf/next = get_step(ridden, direction)
var/turf/current = get_turf(ridden)
if(istype(next, /turf/open/floor/plating/lava) || istype(current, /turf/open/floor/plating/lava)) //We can move from land to lava, or lava to land, but not from land to land
..()
else
user << "Boats don't go on land!"
return 0
/datum/riding/boat/dragon
keytype = null
generic_pixel_y = 2
generic_pixel_x = 1
vehicle_move_delay = 1
///////////////ANIMALS////////////
//general animals
/datum/riding/animal
keytype = null
generic_pixel_x = 0
generic_pixel_y = 4
/datum/riding/animal/handle_ride(mob/user, direction)
if(user.incapacitated())
ridden.unbuckle_mob(user)
return
if(world.time < next_vehicle_move)
return
next_vehicle_move = world.time + vehicle_move_delay
if(keycheck(user))
if(!isturf(ridden.loc))
return
step(ridden, direction)
handle_vehicle_layer()
handle_vehicle_offsets()
else
user << "<span class='notice'>You'll need something to guide the [ridden.name].</span>"
+3 -4
View File
@@ -2,10 +2,9 @@
//name = "A Chest of Doubloons"
name = null
var/id = null // For blacklisting purposes, all ruins need an id
var/description = "In the middle of a clearing in the rockface, there's a \
chest filled with gold coins with Spanish engravings. How is there a \
wooden container filled with 18th century coinage in the middle of a \
lavawracked hellscape? It is clearly a mystery."
var/description = "In the middle of a clearing in the rockface, there's a chest filled with gold coins with Spanish engravings. \
How is there a wooden container filled with 18th century coinage in the middle of a lavawracked hellscape? \
It is clearly a mystery."
var/cost = null
var/allow_duplicates = TRUE
+47 -65
View File
@@ -1,3 +1,5 @@
// Hey! Listen! Update \config\lavaruinblacklist.txt with your new ruins!
/datum/map_template/ruin/lavaland
prefix = "_maps/RandomRuins/LavaRuins/"
@@ -8,18 +10,15 @@
/datum/map_template/ruin/lavaland/biodome/beach
name = "Biodome Beach"
id = "biodome-beach"
description = "Seemingly plucked from a tropical destination, this beach \
is calm and cool, with the salty waves roaring softly in the \
background. Comes with a rustic wooden bar and suicidal bartender."
description = "Seemingly plucked from a tropical destination, this beach is calm and cool, with the salty waves roaring softly in the background. \
Comes with a rustic wooden bar and suicidal bartender."
suffix = "lavaland_biodome_beach.dmm"
/datum/map_template/ruin/lavaland/biodome/winter
name = "Biodome Winter"
id = "biodome-winter"
description = "For those getaways where you want to get back to nature, \
but you don't want to leave the fortified military compound where you \
spend your days. Includes a unique(*) laser pistol display case, \
and the recently introduced I.C.E(tm)."
description = "For those getaways where you want to get back to nature, but you don't want to leave the fortified military compound where you spend your days. \
Includes a unique(*) laser pistol display case, and the recently introduced I.C.E(tm)."
suffix = "lavaland_surface_biodome_winter.dmm"
/datum/map_template/ruin/lavaland/biodome/clown
@@ -31,8 +30,7 @@
/datum/map_template/ruin/lavaland/cube
name = "The Wishgranter Cube"
id = "wishgranter-cube"
description = "Nothing good can come from this. Learn from their mistakes \
and turn around."
description = "Nothing good can come from this. Learn from their mistakes and turn around."
suffix = "lavaland_surface_cube.dmm"
cost = 10
allow_duplicates = FALSE
@@ -40,10 +38,8 @@
/datum/map_template/ruin/lavaland/prisoners
name = "Prisoner Crash"
id = "prisoner-crash"
description = "This incredibly high security shuttle clearly didn't have \
'avoiding lavafilled hellscapes' as a design priority. As such, it \
has crashed, waking the prisoners from their cryostasis, and setting \
them loose on the wastes. If they live long enough, that is."
description = "This incredibly high security shuttle clearly didn't have 'avoiding lavafilled hellscapes' as a design priority. \
As such, it has crashed, waking the prisoners from their cryostasis, and setting them loose on the wastes. If they live long enough, that is."
suffix = "lavaland_surface_prisoner_crash.dmm"
cost = 15
allow_duplicates = FALSE
@@ -51,31 +47,33 @@
/datum/map_template/ruin/lavaland/seed_vault
name = "Seed Vault"
id = "seed-vault"
description = "The creators of these vaults were a highly advanced and \
benevolent race, and launched many into the stars, hoping to aid \
fledgling civilizations. However, all the inhabitants seem to do is \
grow drugs and guns."
description = "The creators of these vaults were a highly advanced and benevolent race, and launched many into the stars, hoping to aid fledgling civilizations. \
However, all the inhabitants seem to do is grow drugs and guns."
suffix = "lavaland_surface_seed_vault.dmm"
cost = 10
/datum/map_template/ruin/lavaland/ash_walker
name = "Ash Walker Nest"
id = "ash-walker"
description = "A race of unbreathing lizards live here, that run faster \
than a human can, worship a broken dead city, and are capable of \
reproducing by something involving tentacles? Probably best to \
stay clear."
description = "A race of unbreathing lizards live here, that run faster than a human can, worship a broken dead city, and are capable of reproducing by something involving tentacles? \
Probably best to stay clear."
suffix = "lavaland_surface_ash_walker1.dmm"
cost = 20
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/syndicate_base
name = "Syndicate Lava Base"
id = "lava-base"
description = "A secret base researching illegal bioweapons, it is closely guarded by an elite team of syndicate agents."
suffix = "lavaland_surface_syndicate_base1.dmm"
cost = 20
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/free_golem
name = "Free Golem Ship"
id = "golem-ship"
description = "Lumbering humanoids, made out of precious metals, move \
inside this ship. They frequently leave to mine more minerals, \
which they somehow turn into more of them. Seem very intent on \
research and individual liberty, and also geology based naming?"
description = "Lumbering humanoids, made out of precious metals, move inside this ship. They frequently leave to mine more minerals, which they somehow turn into more of them. \
Seem very intent on research and individual liberty, and also geology based naming?"
cost = 20
suffix = "lavaland_surface_golem_ship.dmm"
allow_duplicates = FALSE
@@ -83,14 +81,14 @@
/datum/map_template/ruin/lavaland/animal_hospital
name = "Animal Hospital"
id = "animal-hospital"
description = "Rats with cancer do not live very long. And the ones that \
wake up from cryostasis seem to commit suicide out of boredom."
description = "Rats with cancer do not live very long. And the ones that wake up from cryostasis seem to commit suicide out of boredom."
cost = 5
suffix = "lavaland_surface_animal_hospital.dmm"
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/sin
cost = 10
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/sin/envy
name = "Ruin of Envy"
@@ -124,70 +122,55 @@
suffix = "lavaland_surface_sloth.dmm"
// Generates nothing but atmos runtimes and salt
cost = 0
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/ato
name = "Automated Trade Outpost"
id = "ato"
description = "A sign at the front says 'Stealing is bad.'"
suffix = "lavaland_surface_automated_trade_outpost.dmm"
cost = 5
/datum/map_template/ruin/lavaland/hierophant
name = "Hierophant's Arena"
id = "hierophant"
description = "A strange, square chunk of metal of massive size. Inside awaits only death and many, many squares."
suffix = "lavaland_surface_hierophant.dmm"
cost = 0
allow_duplicates = FALSE
/datum/map_template/ruin/lavaland/ufo_crash
name = "UFO Crash"
id = "ufo-crash"
description = "Turns out that keeping your abductees unconcious is really \
important. Who knew?"
description = "Turns out that keeping your abductees unconcious is really important. Who knew?"
suffix = "lavaland_surface_ufo_crash.dmm"
cost = 5
/datum/map_template/ruin/lavaland/ww_vault
name = "Wishgranter Vault"
id = "ww-vault"
description = "Scrawled on the large double doors is both a message and a \
warning: 'meat grinder requires sacri...'. You're not so sure about \
this anymore."
description = "Scrawled on the large double doors is both a message and a warning: 'meat grinder requires sacri...'. You're not so sure about this anymore."
suffix = "lavaland_surface_ww_vault.dmm"
cost = 20
/datum/map_template/ruin/lavaland/xeno_nest
name = "Xenomorph Nest"
id = "xeno-nest"
description = "These xenomorphs got bored of horrifically slaughtering \
people on space stations, and have settled down on a nice lava filled \
hellscape to focus on what's really important in life. Quality memes."
description = "These xenomorphs got bored of horrifically slaughtering people on space stations, and have settled down on a nice lava filled hellscape to focus on what's really important in life. \
Quality memes."
suffix = "lavaland_surface_xeno_nest.dmm"
cost = 20
/datum/map_template/ruin/lavaland/fountain
name = "Fountain Hall"
id = "fountain"
description = "The fountain has a warning on the side. DANGER: May have \
undeclared side effects that only become obvious when implemented."
description = "The fountain has a warning on the side. DANGER: May have undeclared side effects that only become obvious when implemented."
suffix = "lavaland_surface_fountain_hall.dmm"
cost = 5
/datum/map_template/ruin/lavaland/survivalcapsule
name = "Survival Capsule Ruins"
id = "survivalcapsule"
description = "What was once sanctuary to the common miner, \
is now their tomb."
description = "What was once sanctuary to the common miner, is now their tomb."
suffix = "lavaland_surface_survivalpod.dmm"
cost = 5
/datum/map_template/ruin/lavaland/tomb
name = "Strange Outpost"
id = "tomb"
description = "A strange tomb, housing the dead of whatever strange civilization \
lived here before. You swear you hear rattling coming from the inside."
suffix = "lavaland_surface_tomb.dmm"
cost = 10
/datum/map_template/ruin/lavaland/pizza
name = "Ruined Pizza Party"
id = "pizza"
description = "Little Timmy's birthday pizza-bash took a turn for the worse \
when a bluespace anomaly passed by."
description = "Little Timmy's birthday pizza-bash took a turn for the worse when a bluespace anomaly passed by."
suffix = "lavaland_surface_pizzaparty.dmm"
allow_duplicates = FALSE
cost = 5
@@ -195,8 +178,7 @@
/datum/map_template/ruin/lavaland/cultaltar
name = "Summoning Ritual"
id = "cultaltar"
description = "A place of vile worship, the scrawling of blood in the middle glowing eerily.\
A demonic laugh echoes throughout the caverns"
description = "A place of vile worship, the scrawling of blood in the middle glowing eerily. A demonic laugh echoes throughout the caverns"
suffix = "lavaland_surface_cultaltar.dmm"
allow_duplicates = FALSE
cost = 10
@@ -209,10 +191,10 @@
allow_duplicates = FALSE
cost = 10
/datum/map_template/ruin/lavaland/cult_shuttle
name = "Crashed Cult Hive"
id = "cultshuttle"
description = "A once-bustling home for zealots of the blood-worshiping type. Turns out practicing \
dark rituals mid-jump isn't the best idea."
suffix = "lavaland_surface_cultcrash.dmm"
cost = 10
/datum/map_template/ruin/lavaland/swarmer_boss
name = "Crashed Shuttle"
id = "swarmerboss"
description = "A Syndicate shuttle had an unfortunate stowaway..."
suffix = "lavaland_surface_swarmer_crash.dmm"
allow_duplicates = FALSE
cost = 20
+97 -95
View File
@@ -1,3 +1,5 @@
// Hey! Listen! Update \config\spaceruinblacklist.txt with your new ruins!
/datum/map_template/ruin/space
prefix = "_maps/RandomRuins/SpaceRuins/"
cost = 1
@@ -7,10 +9,8 @@
id = "zoo"
suffix = "abandonedzoo.dmm"
name = "Biological Storage Facility"
description = "In case society crumbles, we will be able to restore our \
zoos to working order with the breeding stock kept in these 100% \
secure and unbreachable storage facilities. At no point has anything \
escaped. That's our story, and we're sticking to it."
description = "In case society crumbles, we will be able to restore our zoos to working order with the breeding stock kept in these 100% secure and unbreachable storage facilities. \
At no point has anything escaped. That's our story, and we're sticking to it."
/datum/map_template/ruin/space/asteroid1
id = "asteroid1"
@@ -28,18 +28,14 @@
id = "asteroid3"
suffix = "asteroid3.dmm"
name = "Asteroid 3"
description = "This asteroid floating in space has no official \
designation, because the scientist that discovered it deemed it \
'super dull'."
description = "This asteroid floating in space has no official designation, because the scientist that discovered it deemed it 'super dull'."
/datum/map_template/ruin/space/asteroid4
id = "asteroid4"
suffix = "asteroid4.dmm"
name = "Asteroid 4"
description = "Nanotrasen Escape Pods have a 100%* success rate, and a \
99%* customer satisfaction rate. *Please note that these statistics, \
are taken from pods that have successfully docked with a recovery \
vessel."
description = "Nanotrasen Escape Pods have a 100%* success rate, and a 99%* customer satisfaction rate. \
*Please note that these statistics, are taken from pods that have successfully docked with a recovery vessel."
/datum/map_template/ruin/space/asteroid5
id = "asteroid5"
@@ -47,23 +43,19 @@
name = "Asteroid 5"
description = "Oh my god, another giant rock!"
/datum/map_template/ruin/space/deep_storage
id = "deep-storage"
suffix = "deepstorage.dmm"
name = "Survivalist Bunker"
description = "Assume the best, prepare for the worst. Generally, you \
should do so by digging a three man heavily fortified bunker into \
a giant unused asteroid. Then make it self sufficient, mask any \
evidence of construction, hook it covertly into the \
telecommunications network and hope for the best."
/datum/map_template/ruin/space/bigderelict1
id = "bigderelict1"
suffix = "bigderelict1.dmm"
name = "Derelict Tradepost"
description = "A once-bustling tradestation that handled imports and exports from nearby stations now lays eerily dormant. \
The last received message was a distress call from one of the on-board officers, but we had no success in making contact again."
/datum/map_template/ruin/space/derelict1
id = "derelict1"
suffix = "derelict1.dmm"
name = "Derelict 1"
description = "Nothing to see here citizen, move along, certainly no \
xeno outbreaks on this piece of station debris. That purple stuff? \
It's uh... station nectar. It's a top secret research installation."
description = "Nothing to see here citizen, move along, certainly no xeno outbreaks on this piece of station debris. That purple stuff? It's uh... station nectar. \
It's a top secret research installation."
/datum/map_template/ruin/space/derelict2
id = "derelict2"
@@ -77,86 +69,97 @@
id = "derelict3"
suffix = "derelict3.dmm"
name = "Derelict 3"
description = "These hulks were once part of a larger structure, where \
the three great \[REDACTED\] were forged."
description = "These hulks were once part of a larger structure, where the three great \[REDACTED\] were forged."
/datum/map_template/ruin/space/derelict4
id = "derelict4"
suffix = "derelict4.dmm"
name = "Derelict 4"
description = "Centcom ferries have never crashed, will never crash, \
there is no current investigation into a crashed ferry, and we \
will not let Internal Affairs trample over high security information \
in the name of this baseless witchhunt."
description = "Centcom ferries have never crashed, will never crash, there is no current investigation into a crashed ferry, and we will not let Internal Affairs trample over high security \
information in the name of this baseless witchhunt."
/datum/map_template/ruin/space/derelict5
id = "derelict5"
suffix = "derelict5.dmm"
name = "Derelict 5"
description = "The plan is, we put a whole bunch of crates full of \
treasure in this disused warehouse, launch it into space, and then \
ignore it. Forever."
description = "The plan is, we put a whole bunch of crates full of treasure in this disused warehouse, launch it into space, and then ignore it. Forever."
/datum/map_template/ruin/space/derelict6
id = "derelict6"
suffix = "derelict6.dmm"
name = "Derelict 6"
description = "The hush-hush of Nanotrasen when it comes to stations seemingly vanishing off the radar is an interesting topic, \
theories of nuclear destruction float about while Nanotrasen flat-out denies said stations ever existing."
description = "The hush-hush of Nanotrasen when it comes to stations seemingly vanishing off the radar is an interesting topic, theories of nuclear destruction float about while Nanotrasen \
flat-out denies said stations ever existing."
/datum/map_template/ruin/space/empty_shell
id = "empty-shell"
suffix = "emptyshell.dmm"
name = "Empty Shell"
description = "Cosy, rural property availible for young professional \
couple. Only twelve parsecs from the nearest hyperspace lane!"
description = "Cosy, rural property availible for young professional couple. Only twelve parsecs from the nearest hyperspace lane!"
/datum/map_template/ruin/space/gas_the_lizards
id = "gas-the-lizards"
suffix = "gasthelizards.dmm"
name = "Disposal Facility 17"
description = "Gas efficiency at 95.6%, fluid elimination at 96.2%. \
Will require renewed supplies of 'carpet' before the end of the \
quarter."
description = "Gas efficiency at 95.6%, fluid elimination at 96.2%. Will require renewed supplies of 'carpet' before the end of the quarter."
/datum/map_template/ruin/space/intact_empty_ship
id = "intact-empty-ship"
suffix = "intactemptyship.dmm"
name = "Authorship"
description = "Just somewhere quiet, where I can focus on my work with \
no interruptions."
description = "Just somewhere quiet, where I can focus on my work with no interruptions."
/datum/map_template/ruin/space/caravanambush
id = "space/caravanambush"
suffix = "caravanambush.dmm"
name = "Syndicate Ambush"
description = "A caravan route used by passing cargo freights has been ambushed by a salvage team manned by the syndicate. \
The caravan managed to send off a distress message before being surrounded, their video feed cutting off as the sound of gunfire and a parrot was heard."
/datum/map_template/ruin/space/originalcontent
id = "paperwizard"
suffix = "originalcontent.dmm"
name = "A Giant Ball of Paper in Space"
description = "Sightings of a giant wad of paper hurling through the depths of space have been recently reported by multiple outposts near this sector. \
A giant wad of paper, really? Damn prank callers."
/datum/map_template/ruin/space/mech_transport
id = "mech-transport"
suffix = "mechtransport.dmm"
name = "CF Corsair"
description = "Well, when is it getting here? I have bills to pay; very \
well-armed clients who want their shipments as soon as possible! I \
don't care, just find it!"
description = "Well, when is it getting here? I have bills to pay; very well-armed clients who want their shipments as soon as possible! I don't care, just find it!"
/datum/map_template/ruin/space/onehalf
id = "onehalf"
suffix = "onehalf.dmm"
name = "DK Excavator 453"
description = "Based on the trace elements we've detected on the \
gutted asteroids, we suspect that a mining ship using a restricted \
engine is somewhere in the area. We'd like to request a patrol vessel \
to investigate."
description = "Based on the trace elements we've detected on the gutted asteroids, we suspect that a mining ship using a restricted engine is somewhere in the area. \
We'd like to request a patrol vessel to investigate."
/datum/map_template/ruin/space/spacebar
id = "spacebar"
suffix = "spacebar.dmm"
name = "The Rampant Golem and Yellow Hound"
description = "No questions asked. No shoes/foot protection, no service. \
No tabs. No violence in the inside areas. That's it. Welcome to the \
Rampant Golem and Yellow Hound. Can I take your order?"
description = "No questions asked. No shoes/foot protection, no service. No tabs. No violence in the inside areas. That's it. Welcome to the Rampant Golem and Yellow Hound. \
Can I take your order?"
/datum/map_template/ruin/space/spacehotel
id = "spacehotel"
suffix = "spacehotel.dmm"
name = "The Twin-Nexus Hotel"
description = "A interstellar hotel, where the weary spaceman can rest their head and relax, assured that the residental staff will not murder them in their sleep. Probably."
/datum/map_template/ruin/space/turreted_outpost
id = "turreted-outpost"
suffix = "turretedoutpost.dmm"
name = "Unnamed Turreted Outpost"
description = "We'd ask them to stop blaring that ruskiepop music, but \
none of us are brave enough to go near those death turrets they have."
description = "We'd ask them to stop blaring that ruskiepop music, but none of us are brave enough to go near those death turrets they have."
/datum/map_template/ruin/space/oldshuttle
id = "spaceman-origins"
suffix = "shuttlerelic.dmm"
name = "Strange Ship"
description = "A ship seemingly lost, drifting along the stars. This thing looks like it belongs in ancient times."
/datum/map_template/ruin/space/way_home
id = "way-home"
@@ -168,81 +171,80 @@
id = "djstation"
suffix = "djstation.dmm"
name = "DJ Station"
description = "Until very recently this pirate radio station was used \
to harangue local space stations over a variety of perceived \
\"ethics violations\". It seems like someone finally got sick of \
it, but the equipment still works."
description = "Until very recently this pirate radio station was used to harangue local space stations over a variety of perceived \"ethics violations\". \
It seems like someone finally got sick of it, but the equipment still works."
/datum/map_template/ruin/space/thederelict
id = "thederelict"
suffix = "thederelict.dmm"
name = "Kosmicheskaya Stantsiya 13"
description = "The true fate of Kosmicheskaya Stantsiya 13 is an open \
question to this day. Most corporations deny its existence, \
for fear of questioning on what became of its crew."
description = "The true fate of Kosmicheskaya Stantsiya 13 is an open question to this day. Most corporations deny its existence, for fear of questioning on what became of its crew."
/datum/map_template/ruin/space/abandonedteleporter
id = "abandonedteleporter"
suffix = "abandonedteleporter.dmm"
name = "Abandoned Teleporter"
description = "In space construction the teleporter is often the \
first system brought online. This lonely half built teleporter \
is a sign of a proposed structure that for one reason or another \
just never got built."
description = "In space construction the teleporter is often the first system brought online. \
This lonely half built teleporter is a sign of a proposed structure that for one reason or another just never got built."
/datum/map_template/ruin/space/crashedclownship
id = "crashedclownship"
suffix = "crashedclownship.dmm"
name = "Crashed Clown Ship"
description = "For centuries the promise of a new clown homeworld \
has been the siren call for countless clown vessels. Alas the \
clown's lust for shinanagans means that successful voyages \
are almost unheard of, with most vessels falling to hilarious \
consequences almost immediately."
description = "For centuries the promise of a new clown homeworld has been the siren call for countless clown vessels. \
Alas the clown's lust for shinanagans means that successful voyages are almost unheard of, with most vessels falling to hilarious consequences almost immediately."
/datum/map_template/ruin/space/crashedship
id = "crashedship"
suffix = "crashedship.dmm"
name = "Crashed Ship"
description = "Among civilian vessels the most common cause of \
tragedy is lack of food. This ship was outfited with a \
multitude of food generating features, then summarily ran \
into an asteroid shortly after takeoff."
description = "Among civilian vessels the most common cause of tragedy is lack of food. \
This ship was outfited with a multitude of food generating features, then summarily ran into an asteroid shortly after takeoff."
/datum/map_template/ruin/space/listeningstation
id = "listeningstation"
suffix = "listeningstation.dmm"
name = "Syndicate Listening Station"
description = "Listening stations form the backbone of the \
syndicate's information gathering operations. Assignment to \
these stations is dreaded by most agents, as it entails long \
and lonely shifts listening to nearby stations chatter \
incessently about the most meaningless things."
description = "Listening stations form the backbone of the syndicate's information gathering operations. \
Assignment to these stations is dreaded by most agents, as it entails long and lonely shifts listening to nearby stations chatter incessently about the most meaningless things."
/datum/map_template/ruin/space/oldAIsat
id = "oldAIsat"
suffix = "oldAIsat.dmm"
name = "Abandoned Telecommunications Satellite"
description = "When the inspector told the employees that they \
were all fired, and that their jobs \"could be done by \
trained lizards anyway\", they reacted badly. This event and \
others is the reason why Central always sends an ERT squad with \
their competent inspectors. Incompetent inspectors are told \
they can \"do it alone\" because they're \"that pro\". \
Incompetent inspectors believe this."
description = "When the inspector told the employees that they were all fired, and that their jobs \"could be done by trained lizards anyway\", they reacted badly. \
This event and others is the reason why Central always sends an ERT squad with their competent inspectors. Incompetent inspectors are told they can \"do it alone\" because they're \"that pro\". \
Incompetent inspectors believe this."
/datum/map_template/ruin/space/oldteleporter
id = "oldteleporter"
suffix = "oldteleporter.dmm"
name = "Detached Teleporter"
description = "The structure of this surprisingly intact \
teleporter suggests that it was once part of a larger structure, \
but what remains of said structure, if anything, can \
only be guessed at."
description = "The structure of this surprisingly intact teleporter suggests that it was once part of a larger structure, but what remains of said structure, if anything, can only be guessed at."
/datum/map_template/ruin/space/puzzle1
id = "puzzle1"
suffix = "puzzle1.dmm"
name = "Strange Structure"
description = "A strange, free-floating structure that has been aimlessly drifting through the void \
of space for who knows how long. Seems like whatever built it was really bored."
/datum/map_template/ruin/space/vaporwave
id = "vaporwave"
suffix = "vaporwave.dmm"
name = "Aesthetic Outpost"
description = "Pause and remember-- You are unique.You are special. Every mistake, trial, and hardship has helped to sculpt your real beauty. \
Stop hating yourself and start appreciating and loving yourself!"
/datum/map_template/ruin/space/bus
id = "bus"
suffix = "bus.dmm"
name = "Waylaid Buses"
description = "There seems to be a pair of buses that pulled over for repairs. What were they doing..? Their shipment sure seems to be filled with a strange mix. \
Anyway, it looks like some people tried to fix it up for a long time but didn't really get anywhere..."
/datum/map_template/ruin/space/miracle
id = "miracle"
suffix = "miracle.dmm"
name = "Ordinary Space Tile"
description = "Absolutely nothing strange going on here please move along, plenty more space to see right this way!"
/datum/map_template/ruin/space/dragoon
id = "dragoon"
suffix = "dragoontomb.dmm"
name = "Sky Bulge Tomb"
description = "A tomb of a dice-loving dragoon in space. Turns out he got too good and jumped too high. Contains the Sky Bulge, which when thrown, warps the thrower."
+110 -91
View File
@@ -6,8 +6,16 @@
var/shuttle_id
var/description
var/prerequisites
var/admin_notes
var/credit_cost = INFINITY
var/can_be_bought = TRUE
/datum/map_template/shuttle/proc/prerequisites_met()
return TRUE
/datum/map_template/shuttle/New()
shuttle_id = "[port_id]_[suffix]"
mappath = "[prefix][shuttle_id].dmm"
@@ -32,128 +40,137 @@
/datum/map_template/shuttle/emergency/airless
suffix = "airless"
name = "(Shuttle Under Construction)"
description = "The documentation hasn't been finished yet for this \
shuttle.\n\
In case of emergency: Break glass."
name = "Build your own shuttle kit"
description = "Save money by building your own shuttle! The chassis will dock upon purchase, but launch will have to be authorized as usual via shuttle call. Interior and atmosphere not included."
admin_notes = "No brig, no medical facilities, no air."
credit_cost = -7500
/datum/map_template/shuttle/emergency/asteroid
suffix = "asteroid"
name = "Asteroid emergency shuttle"
name = "Asteroid Station Emergency Shuttle"
description = "A respectable mid-sized shuttle that first saw service shuttling Nanotrasen crew to and from their asteroid belt embedded facilities."
credit_cost = 3000
/datum/map_template/shuttle/emergency/bar
suffix = "bar"
name = "The Emergency Escape Bar"
description = "Features include sentient bar staff (a Bardrone and a \
Barmaid), bathroom, a quality lounge for the heads, and a \
large gathering table."
admin_notes = "Bardrone and Barmaid are GODMODE, will be automatically \
sentienced by the fun balloon at 60 seconds before arrival. Has \
medical facilities."
description = "Features include sentient bar staff (a Bardrone and a Barmaid), bathroom, a quality lounge for the heads, and a large gathering table."
admin_notes = "Bardrone and Barmaid are GODMODE, will be automatically sentienced by the fun balloon at 60 seconds before arrival. \
Has medical facilities."
credit_cost = 5000
/datum/map_template/shuttle/emergency/meteor
suffix = "meteor"
name = "An Asteroid With Engines Strapped To It"
description = "A hollowed out asteroid with engines strapped to it. Due to its size and difficulty in steering it, this shuttle may damage the docking area."
admin_notes = "This shuttle will likely crush escape, killing anyone there."
credit_cost = -5000
/datum/map_template/shuttle/emergency/luxury
suffix = "luxury"
name = "Luxury Shuttle"
description = "A luxurious golden shuttle complete with an indoor swimming pool. Each crewmember wishing to board must bring 500 credits, payable in cash and mineral coin."
admin_notes = "Due to the limited space for non paying crew, this shuttle may cause a riot."
credit_cost = 10000
/datum/map_template/shuttle/emergency/birdboat
suffix = "birdboat"
name = "Birdboat emergency shuttle"
name = "Birdboat Station Emergency Shuttle"
description = "Though a little on the small side, this shuttle is feature complete, which is more than can be said for the pattern of station it was commissioned for."
credit_cost = 1000
/datum/map_template/shuttle/emergency/box
suffix = "box"
name = "Box emergency shuttle"
name = "Box Station Emergency Shuttle"
credit_cost = 2000
description = "The gold standard in emergency exfiltration, this tried and true design is equipped with everything the crew needs for a safe flight home."
/datum/map_template/shuttle/emergency/clown
suffix = "clown"
name = "Snappop(tm)!"
description = "Hey kids and grownups! Are you bored of DULL and TEDIOUS \
shuttle journeys after you're evacuating for probably BORING reasons. \
Well then order the Snappop(tm) today! We've got fun activities for \
everyone, an all access cockpit, and no boring security brig! Boo! \
Play dress up with your friends! Collect all the bedsheets before \
your neighbour does! Check if the AI is watching you with our patent \
pending \"Peeping Tom AI Multitool Detector\" or PEEEEEETUR for \
short. Have a fun ride!"
admin_notes = "Brig is replaced by anchored greentext book surrounded by \
lavaland chasms, stationside door has been removed to prevent \
accidental dropping. No brig."
description = "Hey kids and grownups! \
Are you bored of DULL and TEDIOUS shuttle journeys after you're evacuating for probably BORING reasons. Well then order the Snappop(tm) today! \
We've got fun activities for everyone, an all access cockpit, and no boring security brig! Boo! Play dress up with your friends! \
Collect all the bedsheets before your neighbour does! Check if the AI is watching you with our patent pending \"Peeping Tom AI Multitool Detector\" or PEEEEEETUR for short. \
Have a fun ride!"
admin_notes = "Brig is replaced by anchored greentext book surrounded by lavaland chasms, stationside door has been removed to prevent accidental dropping. No brig."
credit_cost = 8000
/datum/map_template/shuttle/emergency/cramped
suffix = "cramped"
name = "Secure Transport Vessel 5 (STV5)"
description = "Well, looks like Centcomm only had this ship in the area, \
they probably weren't expecting you to need evac for a while. \
Probably best if you don't rifle around in whatever equipment they \
were transporting. I hope you're friendly with your coworkers, \
because there is very little space in this thing.\n\
\n\
Contains contraband armory guns, maintenance loot, and abandoned \
crates!"
admin_notes = "Due to origin as a solo piloted secure vessel, has an \
active GPS onboard labeled STV5."
description = "Well, looks like Centcomm only had this ship in the area, they probably weren't expecting you to need evac for a while. \
Probably best if you don't rifle around in whatever equipment they were transporting. I hope you're friendly with your coworkers, because there is very little space in this thing.\n\
\n\
Contains contraband armory guns, maintenance loot, and abandoned crates!"
admin_notes = "Due to origin as a solo piloted secure vessel, has an active GPS onboard labeled STV5."
credit_cost = -7500
/datum/map_template/shuttle/emergency/meta
suffix = "meta"
name = "Meta emergency shuttle"
name = "Meta Station Emergency Shuttle"
credit_cost = 4000
description = "A fairly standard shuttle, though larger and slightly better equipped than the Box Station variant."
/datum/map_template/shuttle/emergency/mini
suffix = "mini"
name = "Mini emergency shuttle"
name = "Ministation emergency shuttle"
credit_cost = 1000
description = "Despite it's namesake, this shuttle is actually only slightly smaller than standard, and still complete with a brig and medbay."
/datum/map_template/shuttle/emergency/scrapheap
suffix = "scrapheap"
name = "Standby Evacuation Vessel \"Scrapheap Challenge\""
credit_cost = -1000
description = "Due to a lack of functional emergency shuttles, we bought this second hand from a scrapyard and pressed it into service. Please do not lean to heavily on the exterior windows, they are fragile."
admin_notes = "An abomination with no functional medbay, sections missing, and some very fragile windows. Surprisingly airtight."
/datum/map_template/shuttle/emergency/narnar
suffix = "narnar"
name = "Shuttle 667"
description = "Looks like this shuttle may have wandered into the \
darkness between the stars on route to the station. Let's not think \
too hard about where all the bodies came from."
admin_notes = "Contains real cult ruins, mob eyeballs, and inactive \
constructs. Cult mobs will automatically be sentienced by fun \
balloon. Cloning pods in 'medbay' area are showcases and \
nonfunctional."
description = "Looks like this shuttle may have wandered into the darkness between the stars on route to the station. Let's not think too hard about where all the bodies came from."
admin_notes = "Contains real cult ruins, mob eyeballs, and inactive constructs. Cult mobs will automatically be sentienced by fun balloon. \
Cloning pods in 'medbay' area are showcases and nonfunctional."
/datum/map_template/shuttle/emergency/pubby
suffix = "pubby"
name = "Pubby Station Emergency Shuttle"
description = "A small, but feature complete shuttle. It boasts a card table to keep crew members occupied on the long flight home."
credit_cost = 1000
/datum/map_template/shuttle/emergency/supermatter
suffix = "supermatter"
name = "Hyperfractal Gigashuttle"
description = "\"I dunno, this seems kinda needlessly complicated.\"\n\
\"This shuttle has very a very high safety record, according to \
Centcom Officer Cadet Yins.\"\n\
\"Are you sure?\"\n\
\"Yes, it has a safety record of N-A-N, which is apparently \
larger than 100%.\""
admin_notes = "Supermatter that spawns on shuttle is special anchored \
'hugbox' supermatter that cannot take damage and does not take in \
or emit gas. Outside of admin intervention, it cannot explode. \
It does, however, still dust anything on contact, emits high levels \
of radiation, and induce hallucinations in anyone looking at it \
without protective goggles. Emitters spawn powered on, expect \
admin notices, they are harmless."
\"This shuttle has very a very high safety record, according to Centcom Officer Cadet Yins.\"\n\
\"Are you sure?\"\n\
\"Yes, it has a safety record of N-A-N, which is apparently larger than 100%.\""
admin_notes = "Supermatter that spawns on shuttle is special anchored 'hugbox' supermatter that cannot take damage and does not take in or emit gas. \
Outside of admin intervention, it cannot explode. \
It does, however, still dust anything on contact, emits high levels of radiation, and induce hallucinations in anyone looking at it without protective goggles. \
Emitters spawn powered on, expect admin notices, they are harmless."
/datum/map_template/shuttle/emergency/imfedupwiththisworld
suffix = "imfedupwiththisworld"
name = "Oh, Hi Daniel"
description = "How was space work today? \
Oh, pretty good. We got a new space station and the company will make a lot of money. \
What space station? \
I cannot tell you; it's space confidential. \
Aw, come space on. Why not? \
No, I can't. Anyway, how is your space roleplay life?"
description = "How was space work today? Oh, pretty good. We got a new space station and the company will make a lot of money. What space station? I cannot tell you; it's space confidential. \
Aw, come space on. Why not? No, I can't. Anyway, how is your space roleplay life?"
credit_cost = -5000
/datum/map_template/shuttle/emergency/goon
suffix = "goon"
name = "NES Port"
description = "The Nanotrasen Emergency Shuttle Port(NES Port for short) \
is a shuttle used at other less known nanotrasen facilities \
and has a more open inside for larger crowds."
description = "The Nanotrasen Emergency Shuttle Port(NES Port for short) is a shuttle used at other less known nanotrasen facilities and has a more open inside for larger crowds."
credit_cost = 3000
/datum/map_template/shuttle/emergency/wabbajack
suffix = "wabbajack"
name = "NT Lepton Violet"
description = "The research team based on this vessel went missing one \
day, and no amount of investigation could discover what happened to \
them. The only occupants were a number of dead rodents, who appeared to \
have clawed each other to death. Needless to say, no engineering team \
wanted to go near the thing, and it's only being used as an Emergency \
Escape Shuttle because there is literally nothing else available."
admin_notes = "If the crew can solve the puzzle, they will wake the \
wabbajack statue. It will likely not end well. There's a reason it's \
boarded up. Maybe they should have just left it alone."
description = "The research team based on this vessel went missing one day, and no amount of investigation could discover what happened to them. \
The only occupants were a number of dead rodents, who appeared to have clawed each other to death. \
Needless to say, no engineering team wanted to go near the thing, and it's only being used as an Emergency Escape Shuttle because there is literally nothing else available."
admin_notes = "If the crew can solve the puzzle, they will wake the wabbajack statue. It will likely not end well. There's a reason it's boarded up. Maybe they should have just left it alone."
credit_cost = 15000
/datum/map_template/shuttle/ferry/base
suffix = "base"
@@ -163,28 +180,19 @@
/datum/map_template/shuttle/ferry/meat
suffix = "meat"
name = "\"meat\" ferry"
description = "Ahoy! We got all kinds o' meat aft here. Meat from plant \
people, people who be dark, not in a racist way, just they're dark \
black. Oh and lizard meat too,mighty popular that is. Definitely \
100% fresh, just ask this guy here. *person on meatspike moans* See? \
Definitely high quality meat, nothin' wrong with it, nothin' added, \
definitely no zombifyin' reagents!"
admin_notes = "Meat currently contains no zombifying reagents, lizard on \
meatspike must be spawned in."
description = "Ahoy! We got all kinds o' meat aft here. Meat from plant people, people who be dark, not in a racist way, just they're dark black. \
Oh and lizard meat too,mighty popular that is. Definitely 100% fresh, just ask this guy here. *person on meatspike moans* See? \
Definitely high quality meat, nothin' wrong with it, nothin' added, definitely no zombifyin' reagents!"
admin_notes = "Meat currently contains no zombifying reagents, lizard on meatspike must be spawned in."
/datum/map_template/shuttle/ferry/lighthouse
suffix = "lighthouse"
name = "The Lighthouse(?)"
description = "*static*... part of a much larger vessel, possibly \
military in origin. The weapon markings aren't anything we've seen \
... static ... by almost never the same person twice, possible use \
of unknown storage ... static ... seeing ERT officers onboard, but \
no missions are on file for ... static ... static ... annoying \
jingle ... only at The LIGHTHOUSE! Fulfilling needs you didn't even \
know you had. We've got EVERYTHING, and something else!"
admin_notes = "Currently larger than ferry docking port on Box, will not \
hit anything, but must be force docked. Trader and ERT bodyguards are \
not included."
description = "*static*... part of a much larger vessel, possibly military in origin. \
The weapon markings aren't anything we've seen ...static... by almost never the same person twice, possible use of unknown storage ...static... \
seeing ERT officers onboard, but no missions are on file for ...static...static...annoying jingle... only at The LIGHTHOUSE! \
Fulfilling needs you didn't even know you had. We've got EVERYTHING, and something else!"
admin_notes = "Currently larger than ferry docking port on Box, will not hit anything, but must be force docked. Trader and ERT bodyguards are not included."
/datum/map_template/shuttle/whiteship/box
suffix = "box"
@@ -194,6 +202,10 @@
suffix = "meta"
name = "NT Recovery White-ship"
/datum/map_template/shuttle/whiteship/pubby
suffix = "pubby"
name = "NT White UFO"
/datum/map_template/shuttle/cargo/box
suffix = "box"
name = "supply shuttle (Box)"
@@ -201,3 +213,10 @@
/datum/map_template/shuttle/cargo/birdboat
suffix = "birdboat"
name = "supply shuttle (Birdboat)"
/datum/map_template/shuttle/emergency/delta
suffix = "delta"
name = "Delta Station Emergency Shuttle"
description = "A large shuttle for a large station, this shuttle can comfortably fit all your overpopulation and crowding needs. Complete with all facilities plus additional equipment."
admin_notes = "Go big or go home."
credit_cost = 7500
+139
View File
@@ -0,0 +1,139 @@
//Largely beneficial effects go here, even if they have drawbacks. An example is provided in Shadow Mend.
/datum/status_effect/shadow_mend
id = "shadow_mend"
duration = 3
alert_type = /obj/screen/alert/status_effect/shadow_mend
/obj/screen/alert/status_effect/shadow_mend
name = "Shadow Mend"
desc = "Shadowy energies wrap around your wounds, sealing them at a price. After healing, you will slowly lose health every three seconds for thirty seconds."
icon_state = "shadow_mend"
/datum/status_effect/shadow_mend/on_apply()
owner.visible_message("<span class='notice'>Violet light wraps around [owner]'s body!</span>", "<span class='notice'>Violet light wraps around your body!</span>")
playsound(owner, 'sound/magic/Teleport_app.ogg', 50, 1)
/datum/status_effect/shadow_mend/tick()
owner.adjustBruteLoss(-15)
owner.adjustFireLoss(-15)
/datum/status_effect/shadow_mend/on_remove()
owner.visible_message("<span class='warning'>The violet light around [owner] glows black!</span>", "<span class='warning'>The tendrils around you cinch tightly and reap their toll...</span>")
playsound(owner, 'sound/magic/Teleport_diss.ogg', 50, 1)
owner.apply_status_effect(STATUS_EFFECT_VOID_PRICE)
/datum/status_effect/void_price
id = "void_price"
duration = 30
tick_interval = 3
alert_type = /obj/screen/alert/status_effect/void_price
/obj/screen/alert/status_effect/void_price
name = "Void Price"
desc = "Black tendrils cinch tightly against you, digging wicked barbs into your flesh."
icon_state = "shadow_mend"
/datum/status_effect/void_price/tick()
owner << sound('sound/magic/Summon_Karp.ogg', volume = 25)
owner.adjustBruteLoss(3)
/datum/status_effect/vanguard_shield
id = "vanguard"
duration = 20
alert_type = /obj/screen/alert/status_effect/vanguard
/obj/screen/alert/status_effect/vanguard
name = "Vanguard"
desc = "You're absorbing stuns! 25% of all stuns taken will affect you after this effect ends."
icon_state = "vanguard"
alerttooltipstyle = "clockcult"
/obj/screen/alert/status_effect/vanguard/MouseEntered(location,control,params)
var/mob/living/L = usr
if(istype(L)) //this is probably more safety than actually needed
var/vanguard = L.stun_absorption["vanguard"]
desc = initial(desc)
desc += "<br><b>[vanguard["stuns_absorbed"] * 2]</b> seconds of stuns held back.<br><b>[round(min(vanguard["stuns_absorbed"] * 0.25, 20)) * 2]</b> seconds of stun will affect you."
..()
/datum/status_effect/vanguard_shield/on_apply()
add_logs(owner, null, "gained Vanguard stun immunity")
owner.add_stun_absorption("vanguard", 200, 1, "'s yellow aura momentarily intensifies!", "Your ward absorbs the stun!", " radiating with a soft yellow light!")
owner.visible_message("<span class='warning'>[owner] begins to faintly glow!</span>", "<span class='brass'>You will absorb all stuns for the next twenty seconds.</span>")
/datum/status_effect/vanguard_shield/on_remove()
var/vanguard = owner.stun_absorption["vanguard"]
var/stuns_blocked = 0
if(vanguard)
stuns_blocked = round(min(vanguard["stuns_absorbed"] * 0.25, 20))
if(owner.stat != DEAD)
var/message_to_owner = "<span class='warning'>You feel your Vanguard quietly fade...</span>"
var/otheractiveabsorptions = FALSE
for(var/i in owner.stun_absorption)
if(owner.stun_absorption[i]["end_time"] > world.time && owner.stun_absorption[i]["priority"] > vanguard["priority"])
otheractiveabsorptions = TRUE
if(!ratvar_awakens && stuns_blocked && !otheractiveabsorptions)
vanguard["end_time"] = 0 //so it doesn't absorb the stuns we're about to apply
owner.Stun(stuns_blocked)
owner.Weaken(stuns_blocked)
message_to_owner = "<span class='boldwarning'>The weight of the Vanguard's protection crashes down upon you!</span>"
if(stuns_blocked >= 15)
message_to_owner += "\n<span class='userdanger'>You faint from the exertion!</span>"
stuns_blocked *= 2
owner.Paralyse(stuns_blocked)
owner.visible_message("<span class='warning'>[owner]'s glowing aura fades!</span>", message_to_owner)
add_logs(owner, null, "lost Vanguard stun immunity[stuns_blocked ? "and been stunned for [stuns_blocked]":""]")
/datum/status_effect/inathneqs_endowment
id = "inathneqs_endowment"
duration = 15
alert_type = /obj/screen/alert/status_effect/inathneqs_endowment
/obj/screen/alert/status_effect/inathneqs_endowment
name = "Inath-neq's Endowment"
desc = "Adrenaline courses through you as the Resonant Cogwheel's energy shields you from all harm!"
icon_state = "inathneqs_endowment"
alerttooltipstyle = "clockcult"
/datum/status_effect/inathneqs_endowment/on_apply()
add_logs(owner, null, "gained Inath-neq's invulnerability")
owner.visible_message("<span class='warning'>[owner] shines with azure light!</span>", "<span class='notice'>You feel Inath-neq's power flow through you! You're invincible!</span>")
var/oldcolor = owner.color
owner.color = "#1E8CE1"
owner.fully_heal()
owner.add_stun_absorption("inathneq", 150, 2, "'s flickering blue aura momentarily intensifies!", "Inath-neq's power absorbs the stun!", " glowing with a flickering blue light!")
owner.status_flags |= GODMODE
animate(owner, color = oldcolor, time = 150, easing = EASE_IN)
addtimer(CALLBACK(owner, /atom/proc/update_atom_colour), 150)
playsound(owner, 'sound/magic/Ethereal_Enter.ogg', 50, 1)
/datum/status_effect/inathneqs_endowment/on_remove()
add_logs(owner, null, "lost Inath-neq's invulnerability")
owner.visible_message("<span class='warning'>The light around [owner] flickers and dissipates!</span>", "<span class='boldwarning'>You feel Inath-neq's power fade from your body!</span>")
owner.status_flags &= ~GODMODE
playsound(owner, 'sound/magic/Ethereal_Exit.ogg', 50, 1)
/datum/status_effect/cyborg_power_regen
id = "power_regen"
duration = 10
alert_type = /obj/screen/alert/status_effect/power_regen
var/power_to_give = 0 //how much power is gained each tick
/obj/screen/alert/status_effect/power_regen
name = "Power Regeneration"
desc = "You are quickly regenerating power!"
icon_state = "power_regen"
/datum/status_effect/cyborg_power_regen/tick()
var/mob/living/silicon/robot/cyborg = owner
if(!istype(cyborg) || !cyborg.cell)
qdel(src)
return
playsound(cyborg, 'sound/effects/light_flicker.ogg', 50, 1)
cyborg.cell.give(power_to_give)
+11
View File
@@ -0,0 +1,11 @@
//Largely negative status effects go here, even if they have small benificial effects
/datum/status_effect/sigil_mark //allows the affected target to always trigger sigils while mindless
id = "sigil_mark"
duration = -1
alert_type = null
var/stat_allowed = DEAD //if owner's stat is below this, will remove itself
/datum/status_effect/sigil_mark/tick()
if(owner.stat < stat_allowed)
qdel(src)
+30
View File
@@ -0,0 +1,30 @@
/datum/status_effect/freon
id = "frozen"
duration = 10
unique = TRUE
alert_type = /obj/screen/alert/status_effect/freon
var/icon/cube
/obj/screen/alert/status_effect/freon
name = "Frozen Solid"
desc = "You're frozen inside of an ice cube, and cannot move! You can still do stuff, like shooting. Resist out of the cube!"
icon_state = "frozen"
/datum/status_effect/freon/on_apply()
if(!owner.stat)
owner << "You become frozen in a cube!"
cube = icon('icons/effects/freeze.dmi', "ice_cube")
owner.overlays += cube
owner.update_canmove()
/datum/status_effect/freon/tick()
owner.update_canmove()
if(owner && owner.bodytemperature >= 310.055)
qdel(src)
/datum/status_effect/freon/on_remove()
if(!owner.stat)
owner << "The cube melts!"
owner.overlays -= cube
owner.bodytemperature += 100
owner.update_canmove()
+100
View File
@@ -0,0 +1,100 @@
//Status effects are used to apply temporary or permanent effects to mobs. Mobs are aware of their status effects at all times.
//This file contains their code, plus code for applying and removing them.
//When making a new status effect, add a define to status_effects.dm in __DEFINES for ease of use!
var/global/list/all_status_effects = list() //a list of all status effects, if for some reason you need to remove all of them
/datum/status_effect
var/id = "effect" //Used for screen alerts.
var/duration = -1 //How long the status effect lasts in SECONDS. Enter -1 for an effect that never ends unless removed through some means.
var/tick_interval = 1 //How many seconds between ticks. Leave at 1 for every second.
var/mob/living/owner //The mob affected by the status effect.
var/cosmetic = FALSE //If the status effect only exists for flavor.
var/unique = TRUE //If there can be multiple status effects of this type on one mob.
var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description
/datum/status_effect/New(mob/living/new_owner)
if(new_owner)
owner = new_owner
if(owner)
LAZYADD(owner.status_effects, src)
all_status_effects += src
addtimer(CALLBACK(src, .proc/start_ticking), 1) //Give us time to set any variables
/datum/status_effect/Destroy()
STOP_PROCESSING(SSprocessing, src)
if(owner)
owner.clear_alert(id)
on_remove()
LAZYREMOVE(owner.status_effects, src)
all_status_effects -= src
return ..()
/datum/status_effect/proc/start_ticking()
if(!src)
return
if(!owner)
qdel(src)
return
on_apply()
if(alert_type)
var/obj/screen/alert/status_effect/A = owner.throw_alert(id, alert_type)
A.attached_effect = src //so the alert can reference us, if it needs to
START_PROCESSING(SSprocessing, src)
/datum/status_effect/process()
if(!owner)
qdel(src)
return
if(duration != -1)
duration--
tick_interval--
if(!tick_interval)
tick()
tick_interval = initial(tick_interval)
if(!duration)
qdel(src)
/datum/status_effect/proc/on_apply() //Called whenever the buff is applied.
/datum/status_effect/proc/tick() //Called every tick.
/datum/status_effect/proc/on_remove() //Called whenever the buff expires or is removed.
////////////////
// ALERT HOOK //
////////////////
/obj/screen/alert/status_effect
name = "Curse of Mundanity"
desc = "You don't feel any different..."
var/datum/status_effect/attached_effect
//////////////////
// HELPER PROCS //
//////////////////
/mob/living/proc/apply_status_effect(effect) //applies a given status effect to this mob, returning the effect if it was successful
. = FALSE
var/datum/status_effect/S1 = effect
LAZYINITLIST(status_effects)
for(var/datum/status_effect/S in status_effects)
if(S.id == initial(S1.id) && initial(S1.unique))
return
S1 = new effect(src)
. = S1
/mob/living/proc/remove_status_effect(effect) //removes all of a given status effect from this mob, returning TRUE if at least one was removed
. = FALSE
if(status_effects)
var/datum/status_effect/S1 = effect
for(var/datum/status_effect/S in status_effects)
if(initial(S1.id) == S.id)
qdel(S)
. = TRUE
/mob/living/proc/has_status_effect(effect) //returns the effect if the mob calling the proc owns the given status effect
. = FALSE
if(status_effects)
var/datum/status_effect/S1 = effect
for(var/datum/status_effect/S in status_effects)
if(initial(S1.id) == S.id)
return S
+5 -4
View File
@@ -70,7 +70,7 @@
M << telegraph_message
if(telegraph_sound)
M << sound(telegraph_sound)
addtimer(src, "start", telegraph_duration)
addtimer(CALLBACK(src, .proc/start), telegraph_duration)
/datum/weather/proc/start()
if(stage >= MAIN_STAGE)
@@ -85,7 +85,7 @@
if(weather_sound)
M << sound(weather_sound)
START_PROCESSING(SSweather, src)
addtimer(src, "wind_down", weather_duration)
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
/datum/weather/proc/wind_down()
if(stage >= WIND_DOWN_STAGE)
@@ -100,7 +100,7 @@
if(end_sound)
M << sound(end_sound)
STOP_PROCESSING(SSweather, src)
addtimer(src, "end", end_duration)
addtimer(CALLBACK(src, .proc/end), end_duration)
/datum/weather/proc/end()
if(stage == END_STAGE)
@@ -109,7 +109,8 @@
update_areas()
/datum/weather/proc/can_impact(mob/living/L) //Can this weather impact a mob?
if(L.z != target_z)
var/turf/mob_turf = get_turf(L)
if(mob_turf && (mob_turf.z != target_z))
return
if(immunity_type in L.weather_immunities)
return
+38 -61
View File
@@ -16,6 +16,7 @@
end_duration = 0
area_type = /area
protected_areas = list(/area/space)
target_z = ZLEVEL_STATION
overlay_layer = ABOVE_OPEN_TURF_LAYER //Covers floors only
@@ -78,7 +79,7 @@
weather_sound = 'sound/lavaland/ash_storm_start.ogg'
weather_overlay = "ash_storm"
end_message = "<span class='boldannounce'>The shrieking wind whips away the last of the ash falls to its usual murmur. It should be safe to go outside now.</span>"
end_message = "<span class='boldannounce'>The shrieking wind whips away the last of the ash and falls to its usual murmur. It should be safe to go outside now.</span>"
end_duration = 300
end_sound = 'sound/lavaland/ash_storm_end.ogg'
end_overlay = "light_ash"
@@ -118,11 +119,11 @@
name = "radiation storm"
desc = "A cloud of intense radiation passes through the area dealing rad damage to those who are unprotected."
telegraph_duration = 600
telegraph_duration = 400
telegraph_message = "<span class='danger'>The air begins to grow warm.</span>"
weather_message = "<span class='userdanger'><i>You feel waves of heat wash over you! Find shelter!</i></span>"
weather_overlay = "radiation"
weather_overlay = "ash_storm"
weather_duration_lower = 600
weather_duration_upper = 1500
weather_color = "green"
@@ -132,78 +133,54 @@
end_message = "<span class='notice'>The air seems to be cooling off again.</span>"
area_type = /area
protected_areas = list(/area/maintenance, /area/turret_protected/ai_upload, /area/turret_protected/ai_upload_foyer, /area/turret_protected/ai)
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
/area/ai_monitored/turret_protected/ai, /area/storage/emergency, /area/storage/emergency2, /area/shuttle)
target_z = ZLEVEL_STATION
immunity_type = "rad"
/datum/weather/rad_storm/telegraph()
..()
status_alarm("alert")
/datum/weather/rad_storm/impact(mob/living/L)
if(prob(20))
var/resist = L.getarmor(null, "rad")
if(prob(40))
if(ishuman(L))
var/mob/living/carbon/human/H = L
if(H.dna && H.dna.species)
if(!(RADIMMUNE in H.dna.species.specflags))
if(prob(50))
randmuti(H)
if(prob(90))
randmutb(H)
else
randmutg(H)
H.domutcheck()
if(!(RADIMMUNE in H.dna.species.species_traits))
if(prob(max(0,100-resist)))
H.randmuti()
if(prob(50))
if(prob(90))
H.randmutb()
else
H.randmutg()
H.domutcheck()
L.rad_act(20,1)
L.adjustToxLoss(4)
/datum/weather/rad_storm/end()
if(..())
return
priority_announce("The radiation threat has passed. Please return to your workplaces.", "Anomaly Alert")
spawn(300) revoke_maint_all_access()
status_alarm()
/datum/weather/solar_flare
name = "solar flare"
desc = "A solar flare from the local star knocks out power on the station."
telegraph_duration = 300
telegraph_message = "<span class='danger'>You feel a slight tingling in the air.</span>"
/datum/weather/rad_storm/proc/status_alarm(command) //Makes the status displays show the radiation warning for those who missed the announcement.
var/datum/radio_frequency/frequency = SSradio.return_frequency(1435)
weather_message = "<span class='userdanger'><i>Everything shuts off all at once, and the station becomes dark and lifeless.</i></span>"
weather_duration_lower = 450
weather_duration_upper = 900
weather_sound = 'sound/effects/powerdown.ogg'
end_duration = 100
end_message = "<span class='notice'>The buzz of electronics returns once more as the power turns back on.</span>"
end_sound = 'sound/effects/powerup.ogg'
area_type = /area
protected_areas = list(/area/maintenance, /area/turret_protected/ai_upload, /area/turret_protected/ai_upload_foyer, /area/turret_protected/ai, /area/engine/engineering)
target_z = ZLEVEL_STATION
immunity_type = null
/datum/weather/solar_flare/update_areas()
for(var/V in impacted_areas)
var/area/A = V
if(stage == MAIN_STAGE)
A.power_light = 0
A.power_equip = 0
A.power_environ = 0
A.power_change()
for(var/obj/machinery/power/apc/apc in machines)
apc.shorted_old = apc.shorted
var/area/C = get_area(apc)
if(C in impacted_areas)
apc.shorted = TRUE
else
A.power_light = 1
A.power_equip = 1
A.power_environ = 1
A.power_change()
for(var/obj/machinery/power/apc/apc in machines)
apc.shorted = apc.shorted_old
/datum/weather/solar_flare/end()
if(..())
if(!frequency)
return
addtimer(GLOBAL_PROC, "priority_announce", 60, FALSE, "The solar flare has ended. Please return to work.", "Anomaly Alert")
var/datum/signal/status_signal = new
var/atom/movable/virtualspeaker/virt = new /atom/movable/virtualspeaker(null)
status_signal.source = virt
status_signal.transmission_method = 1
status_signal.data["command"] = "shuttle"
if(command == "alert")
status_signal.data["command"] = "alert"
status_signal.data["picture_state"] = "radiation"
frequency.post_signal(src, status_signal)
+3 -2
View File
@@ -1,5 +1,6 @@
/datum/wires/airalarm
holder_type = /obj/machinery/airalarm
proper_name = "Air Alarm"
/datum/wires/airalarm/New(atom/holder)
wires = list(
@@ -30,13 +31,13 @@
if(!A.shorted)
A.shorted = TRUE
A.update_icon()
addtimer(A, "reset", 1200, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/airalarm.proc/reset, wire), 1200)
if(WIRE_IDSCAN) // Toggle lock.
A.locked = !A.locked
if(WIRE_AI) // Disable AI control for a while.
if(!A.aidisabled)
A.aidisabled = TRUE
addtimer(A, "reset", 100, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/airalarm.proc/reset, wire), 100)
if(WIRE_PANIC) // Toggle panic siphon.
if(!A.shorted)
if(A.mode == 1) // AALARM_MODE_SCRUB
+14 -7
View File
@@ -1,5 +1,6 @@
/datum/wires/airlock
holder_type = /obj/machinery/door/airlock
proper_name = "Airlock"
/datum/wires/airlock/secure
randomize = TRUE
@@ -17,7 +18,7 @@
/datum/wires/airlock/interactable(mob/user)
var/obj/machinery/door/airlock/A = holder
if(!istype(user, /mob/living/silicon) && A.isElectrified() && A.shock(user, 100))
if(!issilicon(user) && A.isElectrified() && A.shock(user, 100))
return FALSE
if(A.panel_open)
return TRUE
@@ -78,7 +79,8 @@
if(WIRE_SHOCK) // Pulse to shock the door for 10 ticks.
if(!A.secondsElectrified)
A.secondsElectrified = 30
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
spawn(10)
if(A)
@@ -103,17 +105,21 @@
if(WIRE_POWER1, WIRE_POWER2) // Cut to loose power, repair all to gain power.
if(mend && !is_cut(WIRE_POWER1) && !is_cut(WIRE_POWER2))
A.regainMainPower()
A.shock(usr, 50)
if(usr)
A.shock(usr, 50)
else
A.loseMainPower()
A.shock(usr, 50)
if(usr)
A.shock(usr, 50)
if(WIRE_BACKUP1, WIRE_BACKUP2) // Cut to loose backup power, repair all to gain backup power.
if(mend && !is_cut(WIRE_BACKUP1) && !is_cut(WIRE_BACKUP2))
A.regainBackupPower()
A.shock(usr, 50)
if(usr)
A.shock(usr, 50)
else
A.loseBackupPower()
A.shock(usr, 50)
if(usr)
A.shock(usr, 50)
if(WIRE_BOLTS) // Cut to drop bolts, mend does nothing.
if(!mend)
A.bolt()
@@ -135,7 +141,8 @@
else
if(A.secondsElectrified != -1)
A.secondsElectrified = -1
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
if(usr)
A.shockedby += text("\[[time_stamp()]\][usr](ckey:[usr.ckey])")
add_logs(usr, A, "electrified")
if(WIRE_SAFETY) // Cut to disable safeties, mend to re-enable.
A.safe = mend
+4 -3
View File
@@ -1,5 +1,6 @@
/datum/wires/apc
holder_type = /obj/machinery/power/apc
proper_name = "APC"
/datum/wires/apc/New(atom/holder)
wires = list(
@@ -28,14 +29,14 @@
if(WIRE_POWER1, WIRE_POWER2) // Short for a long while.
if(!A.shorted)
A.shorted = TRUE
addtimer(A, "reset", 1200, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/power/apc.proc/reset, wire), 1200)
if(WIRE_IDSCAN) // Unlock for a little while.
A.locked = FALSE
addtimer(A, "reset", 300, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/power/apc.proc/reset, wire), 300)
if(WIRE_AI) // Disable AI control for a very short time.
if(!A.aidisabled)
A.aidisabled = TRUE
addtimer(A, "reset", 10, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/power/apc.proc/reset, wire), 10)
/datum/wires/apc/on_cut(index, mend)
var/obj/machinery/power/apc/A = holder
+4 -3
View File
@@ -1,5 +1,6 @@
/datum/wires/autolathe
holder_type = /obj/machinery/autolathe
proper_name = "Autolathe"
/datum/wires/autolathe/New(atom/holder)
wires = list(
@@ -26,13 +27,13 @@
switch(wire)
if(WIRE_HACK)
A.adjust_hacked(!A.hacked)
addtimer(A, "reset", 60, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/autolathe.proc/reset, wire), 60)
if(WIRE_SHOCK)
A.shocked = !A.shocked
addtimer(A, "reset", 60, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/autolathe.proc/reset, wire), 60)
if(WIRE_DISABLE)
A.disabled = !A.disabled
addtimer(A, "reset", 60, FALSE, wire)
addtimer(CALLBACK(A, /obj/machinery/autolathe.proc/reset, wire), 60)
/datum/wires/autolathe/on_cut(wire, mend)
var/obj/machinery/autolathe/A = holder
+13
View File
@@ -0,0 +1,13 @@
/datum/wires/emitter
randomize = 1 //Only one wire don't need blueprints
holder_type = /obj/machinery/power/emitter
/datum/wires/emitter/New(atom/holder)
wires = list(WIRE_ZAP)
..()
/datum/wires/emitter/on_pulse(wire)
var/obj/machinery/power/emitter/E = holder
E.fire_beam()
..()
+1
View File
@@ -14,6 +14,7 @@
/datum/wires/explosive/c4
holder_type = /obj/item/weapon/c4
randomize = TRUE //Same behaviour since no wire actually disarms it
/datum/wires/explosive/c4/interactable(mob/user)
var/obj/item/weapon/c4/P = holder
@@ -1,5 +1,6 @@
/datum/wires/particle_accelerator/control_box
holder_type = /obj/machinery/particle_accelerator/control_box
proper_name = "Particle Accelerator"
/datum/wires/particle_accelerator/control_box/New(atom/holder)
wires = list(
+1
View File
@@ -1,5 +1,6 @@
/datum/wires/radio
holder_type = /obj/item/device/radio
proper_name = "Radio"
/datum/wires/radio/New(atom/holder)
wires = list(
+6 -1
View File
@@ -5,7 +5,8 @@
/datum/wires/robot/New(atom/holder)
wires = list(
WIRE_AI, WIRE_CAMERA,
WIRE_LAWSYNC, WIRE_LOCKDOWN
WIRE_LAWSYNC, WIRE_LOCKDOWN,
WIRE_RESET_MODULE
)
add_duds(2)
..()
@@ -22,6 +23,7 @@
status += "The intelligence link display shows [R.connected_ai ? R.connected_ai.name : "NULL"]."
status += "The camera light is [!isnull(R.camera) && R.camera.status ? "on" : "off"]."
status += "The lockdown indicator is [R.lockcharge ? "on" : "off"]."
status += "The reset module hardware light is [R.has_module() ? "on" : "off"]."
return status
/datum/wires/robot/on_pulse(wire)
@@ -44,6 +46,9 @@
R.show_laws()
if(WIRE_LOCKDOWN)
R.SetLockdown(!R.lockcharge) // Toggle
if(WIRE_RESET_MODULE)
if(R.has_module())
R.ResetModule()
/datum/wires/robot/on_cut(wire, mend)
var/mob/living/silicon/robot/R = holder
+1
View File
@@ -1,5 +1,6 @@
/datum/wires/suit_storage_unit
holder_type = /obj/machinery/suit_storage_unit
proper_name = "Suit Storage Unit"
/datum/wires/suit_storage_unit/New(atom/holder)
wires = list(
+17 -16
View File
@@ -20,7 +20,7 @@
if(WIRE_BOOM)
if(B.active)
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
B.timer = 0
B.explode_now = TRUE
tell_admins(B)
if(WIRE_UNBOLT)
holder.visible_message("<span class='notice'>\icon[B] The bolts spin in place for a moment.</span>")
@@ -30,28 +30,28 @@
else
holder.visible_message("<span class='notice'>\icon[B] The bomb chirps.</span>")
playsound(B, 'sound/machines/chime.ogg', 30, 1)
B.timer += 30
B.detonation_timer += 300
B.delayedbig = TRUE
if(WIRE_PROCEED)
holder.visible_message("<span class='danger'>\icon[B] The bomb buzzes ominously!</span>")
playsound(B, 'sound/machines/buzz-sigh.ogg', 30, 1)
if(B.timer >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
B.timer = 60
else if(B.timer >= 21)
B.timer -= 10
else if(B.timer >= 11) // Both to prevent negative timers and to have a little mercy.
B.timer = 10
var/seconds = B.seconds_remaining()
if(seconds >= 61) // Long fuse bombs can suddenly become more dangerous if you tinker with them.
B.detonation_timer = world.time + 600
else if(seconds >= 21)
B.detonation_timer -= 100
else if(seconds >= 11) // Both to prevent negative timers and to have a little mercy.
B.detonation_timer = world.time + 100
if(WIRE_ACTIVATE)
if(!B.active && !B.defused)
holder.visible_message("<span class='danger'>\icon[B] You hear the bomb start ticking!</span>")
playsound(B, 'sound/machines/click.ogg', 30, 1)
B.active = TRUE
B.activate()
B.update_icon()
else if(B.delayedlittle)
holder.visible_message("<span class='notice'>\icon[B] Nothing happens.</span>")
else
holder.visible_message("<span class='notice'>\icon[B] The bomb seems to hesitate for a moment.</span>")
B.timer += 10
B.detonation_timer += 100
B.delayedlittle = TRUE
/datum/wires/syndicatebomb/on_cut(wire, mend)
@@ -63,7 +63,7 @@
else
if(B.active)
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
B.timer = 0
B.explode_now = TRUE
tell_admins(B)
else
B.defused = TRUE
@@ -71,11 +71,11 @@
if(!mend && B.anchored)
holder.visible_message("<span class='notice'>\icon[B] The bolts lift out of the ground!</span>")
playsound(B, 'sound/effects/stealthoff.ogg', 30, 1)
B.anchored = 0
B.anchored = FALSE
if(WIRE_PROCEED)
if(!mend && B.active)
holder.visible_message("<span class='danger'>\icon[B] An alarm sounds! It's go-</span>")
B.timer = 0
B.explode_now = TRUE
tell_admins(B)
if(WIRE_ACTIVATE)
if(!mend && B.active)
@@ -87,5 +87,6 @@
/datum/wires/syndicatebomb/proc/tell_admins(obj/machinery/syndicatebomb/B)
if(istype(B, /obj/machinery/syndicatebomb/training))
return
log_game("A [B.name] was detonated via boom wire at X=[B.x], Y=[B.y], Z=[B.z].")
message_admins("A [B.name] was detonated via boom wire at <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[B.x];Y=[B.y];Z=[B.z]'> (JMP)</a>.")
var/turf/T = get_turf(B)
log_game("\A [B] was detonated via boom wire at [COORD(T)].")
message_admins("A [B.name] was detonated via boom wire at [ADMIN_COORDJMP(T)].")
+13
View File
@@ -0,0 +1,13 @@
/datum/wires/tesla_coil
randomize = 1 //Only one wire don't need blueprints
holder_type = /obj/machinery/power/tesla_coil
/datum/wires/tesla_coil/New(atom/holder)
wires = list(WIRE_ZAP)
..()
/datum/wires/tesla_coil/on_pulse(wire)
var/obj/machinery/power/tesla_coil/C = holder
C.zap()
..()
+5 -4
View File
@@ -1,9 +1,10 @@
/datum/wires/vending
holder_type = /obj/machinery/vending
proper_name = "Vending Unit"
/datum/wires/vending/New(atom/holder)
wires = list(
WIRE_THROW, WIRE_ELECTRIFY, WIRE_SPEAKER,
WIRE_THROW, WIRE_SHOCK, WIRE_SPEAKER,
WIRE_CONTRABAND, WIRE_IDSCAN
)
add_duds(1)
@@ -11,7 +12,7 @@
/datum/wires/vending/interactable(mob/user)
var/obj/machinery/vending/V = holder
if(!istype(user, /mob/living/silicon) && V.seconds_electrified && V.shock(user, 100))
if(!issilicon(user) && V.seconds_electrified && V.shock(user, 100))
return FALSE
if(V.panel_open)
return TRUE
@@ -33,7 +34,7 @@
V.shoot_inventory = !V.shoot_inventory
if(WIRE_CONTRABAND)
V.extended_inventory = !V.extended_inventory
if(WIRE_ELECTRIFY)
if(WIRE_SHOCK)
V.seconds_electrified = 30
if(WIRE_IDSCAN)
V.scan_id = !V.scan_id
@@ -47,7 +48,7 @@
V.shoot_inventory = !mend
if(WIRE_CONTRABAND)
V.extended_inventory = FALSE
if(WIRE_ELECTRIFY)
if(WIRE_SHOCK)
if(mend)
V.seconds_electrified = FALSE
else
+25 -107
View File
@@ -1,123 +1,25 @@
var/list/wire_colors = list( // http://www.crockford.com/wrrrld/color.html
"aliceblue",
"antiquewhite",
"aqua",
"aquamarine",
"beige",
"blanchedalmond",
#define MAXIMUM_EMP_WIRES 3
var/list/wire_colors = list(
"blue",
"blueviolet",
"brown",
"burlywood",
"cadetblue",
"chartreuse",
"chocolate",
"coral",
"cornflowerblue",
"cornsilk",
"crimson",
"cyan",
"deeppink",
"deepskyblue",
"dimgray",
"dodgerblue",
"firebrick",
"floralwhite",
"forestgreen",
"fuchsia",
"gainsboro",
"ghostwhite",
"gold",
"goldenrod",
"gray",
"grey",
"green",
"greenyellow",
"honeydew",
"hotpink",
"indianred",
"ivory",
"khaki",
"lavender",
"lavenderblush",
"lawngreen",
"lemonchiffon",
"lightblue",
"lightcoral",
"lightcyan",
"lightgoldenrodyellow",
"lightgray",
"lightgreen",
"lightpink",
"lightsalmon",
"lightseagreen",
"lightskyblue",
"lightslategray",
"lightsteelblue",
"lightyellow",
"lime",
"limegreen",
"linen",
"magenta",
"maroon",
"mediumaquamarine",
"mediumblue",
"mediumorchid",
"mediumpurple",
"mediumseagreen",
"mediumslateblue",
"mediumspringgreen",
"mediumturquoise",
"mediumvioletred",
"mintcream",
"mistyrose",
"moccasin",
"navajowhite",
"oldlace",
"olive",
"olivedrab",
"orange",
"orangered",
"orchid",
"palegoldenrod",
"palegreen",
"paleturquoise",
"palevioletred",
"papayawhip",
"peachpuff",
"peru",
"pink",
"plum",
"powderblue",
"purple",
"red",
"rosybrown",
"royalblue",
"saddlebrown",
"salmon",
"sandybrown",
"seagreen",
"seashell",
"sienna",
"silver",
"skyblue",
"slateblue",
"slategray",
"snow",
"springgreen",
"steelblue",
"tan",
"teal",
"thistle",
"tomato",
"turquoise",
"violet",
"wheat",
"white",
"whitesmoke",
"yellow",
"yellowgreen",
)
var/list/wire_color_directory = list()
var/list/wire_name_directory = list()
/proc/is_wire_tool(obj/item/I)
if(istype(I, /obj/item/device/multitool))
@@ -136,12 +38,14 @@ var/list/wire_color_directory = list()
/datum/wires
var/atom/holder = null // The holder (atom that contains these wires).
var/holder_type = null // The holder's typepath (used to make wire colors common to all holders).
var/proper_name = "Unknown" // The display name for the wire set shown in station blueprints. Not used if randomize is true or it's an item NT wouldn't know about (Explosives/Nuke)
var/list/wires = list() // List of wires.
var/list/cut_wires = list() // List of wires that have been cut.
var/list/colors = list() // Dictionary of colors to wire.
var/list/assemblies = list() // List of attached assemblies.
var/randomize = 0 // If every instance of these wires should be random.
// Prevents wires from showing up in station blueprints
/datum/wires/New(atom/holder)
..()
@@ -156,6 +60,7 @@ var/list/wire_color_directory = list()
if(!wire_color_directory[holder_type])
randomize()
wire_color_directory[holder_type] = colors
wire_name_directory[holder_type] = proper_name
else
colors = wire_color_directory[holder_type]
@@ -166,7 +71,7 @@ var/list/wire_color_directory = list()
/datum/wires/proc/add_duds(duds)
while(duds)
var/dud = "dud[--duds]"
var/dud = WIRE_DUD_PREFIX + "[--duds]"
if(dud in wires)
continue
wires += dud
@@ -253,6 +158,17 @@ var/list/wire_color_directory = list()
S.loc = holder.loc
return S
/datum/wires/proc/emp_pulse()
var/list/possible_wires = shuffle(wires)
var/remaining_pulses = MAXIMUM_EMP_WIRES
for(var/wire in possible_wires)
if(prob(33))
pulse(wire)
remaining_pulses--
if(remaining_pulses >= 0)
break
// Overridable Procs
/datum/wires/proc/interactable(mob/user)
return TRUE
@@ -297,7 +213,7 @@ var/list/wire_color_directory = list()
for(var/color in colors)
payload.Add(list(list(
"color" = color,
"wire" = (IsAdminGhost(user) ? get_wire(color) : null),
"wire" = (IsAdminGhost(user) || (user.is_holding_item_of_type(/obj/item/device/multitool/abductor)) ? get_wire(color) : null),
"cut" = is_color_cut(color),
"attached" = is_attached(color)
)))
@@ -310,11 +226,11 @@ var/list/wire_color_directory = list()
return
var/target_wire = params["wire"]
var/mob/living/L = usr
var/obj/item/I = L.get_active_hand()
var/obj/item/I = L.get_active_held_item()
switch(action)
if("cut")
if(istype(I, /obj/item/weapon/wirecutters) || IsAdminGhost(usr))
playsound(holder, 'sound/items/Wirecutter.ogg', 20, 1)
playsound(holder, I.usesound, 20, 1)
cut_color(target_wire)
. = TRUE
else
@@ -342,3 +258,5 @@ var/list/wire_color_directory = list()
. = TRUE
else
L << "<span class='warning'>You need an attachable assembly!</span>"
#undef MAXIMUM_EMP_WIRES