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 05:56:14 -06:00
committed by Poojawa
parent 7735dec0ec
commit f7c09077d2
2489 changed files with 830965 additions and 416701 deletions
+12 -4
View File
@@ -8,10 +8,11 @@
/proc/notice(msg)
world.log << "## NOTICE: [msg]"
//print a testing-mode debug message to world.log
/proc/testing(msg)
//print a testing-mode debug message to world.log and world
#ifdef TESTING
world.log << "## TESTING: [msg]"
#define testing(msg) world.log << "## TESTING: [msg]"; world << "## TESTING: [msg]"
#else
#define testing(msg)
#endif
/proc/log_admin(text)
@@ -19,10 +20,14 @@
if (config.log_admin)
diary << "\[[time_stamp()]]ADMIN: [text]"
/proc/log_mentor(text)
mentor_log.Add(text)
diary << "\[[time_stamp()]]MENTOR: [text]"
/proc/log_adminsay(text)
if (config.log_adminchat)
log_admin("ASAY: [text]")
/proc/log_dsay(text)
if (config.log_adminchat)
log_admin("DSAY: [text]")
@@ -76,3 +81,6 @@
//reusing the PDA option because I really don't think news comments are worth a config option
diary << "\[[time_stamp()]]COMMENT: [text]"
/proc/log_chat(text)
if (config.log_pda)
diary << "\[[time_stamp()]]CHAT: [text]"
+2
View File
@@ -10,6 +10,8 @@
if(query.NextRow())
var/diff = text2num(query.item[1])
if(config.use_account_age_for_jobs)
player_age = max(0,diff) //So job code soesn't freak out if they are time traveling.
if(diff < YOUNG)
var/msg = "(IP: [address], ID: [computer_id]) is a new BYOND account made on [y]-[m]-[d]."
if(diff < 0)
+8 -1
View File
@@ -40,5 +40,12 @@ var/cmp_field = "name"
/proc/cmp_subsystem_priority(datum/subsystem/a, datum/subsystem/b)
return a.priority - b.priority
/proc/cmp_timer(datum/timedevent/a, datum/timedevent/b)
return a.timeToRun - b.timeToRun
/proc/cmp_clientcolour_priority(datum/client_colour/A, datum/client_colour/B)
return B.priority - A.priority
return B.priority - A.priority
/proc/cmp_clockscripture_priority(datum/clockwork_scripture/A, datum/clockwork_scripture/B)
return initial(A.sort_priority) - initial(B.sort_priority)
+73 -31
View File
@@ -13,13 +13,17 @@
for(A, A && !isarea(A), A=A.loc); //semicolon is for the empty statement
return A
/proc/get_area_name(atom/X)
var/area/Y = get_area(X)
return Y.name
/proc/get_area_master(O)
var/area/A = get_area(O)
if(A && A.master)
A = A.master
return A
/proc/get_area_name(N) //get area by its name
/proc/get_area_by_name(N) //get area by its name
for(var/area/A in world)
if(A.name == N)
return A
@@ -315,24 +319,22 @@
O.screen_loc = screen_loc
return O
/proc/Show2Group4Delay(obj/O, list/group, delay=0)
if(!isobj(O))
return
if(!group)
group = clients
for(var/client/C in group)
C.screen += O
if(delay)
spawn(delay)
for(var/client/C in group)
C.screen -= O
/proc/remove_images_from_clients(image/I, list/show_to)
for(var/client/C in show_to)
C.images -= I
/proc/flick_overlay(image/I, list/show_to, duration)
for(var/client/C in show_to)
C.images += I
spawn(duration)
for(var/client/C in show_to)
C.images -= I
addtimer(CALLBACK(GLOBAL_PROC, /.proc/remove_images_from_clients, I, show_to), duration)
/proc/flick_overlay_view(image/I, atom/target, duration) //wrapper for the above, flicks to everyone who can see the target atom
var/list/viewing = list()
for(var/m in viewers(target))
var/mob/M = m
if(M.client)
viewing += M.client
flick_overlay(I, viewing, duration)
/proc/get_active_player_count(var/alive_check = 0, var/afk_check = 0, var/human_check = 0)
// Get active players who are playing in the round
@@ -344,9 +346,9 @@
continue
else if(afk_check && M.client.is_afk())
continue
else if(human_check && !istype(M, /mob/living/carbon/human))
else if(human_check && !ishuman(M))
continue
else if(istype(M, /mob/new_player)) // exclude people in the lobby
else if(isnewplayer(M)) // exclude people in the lobby
continue
else if(isobserver(M)) // Ghosts are fine if they were playing once (didn't start as observers)
var/mob/dead/observer/O = M
@@ -393,14 +395,35 @@
return new /datum/projectile_data(src_x, src_y, time, distance, power_x, power_y, dest_x, dest_y)
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300)
/proc/showCandidatePollWindow(mob/dead/observer/G, poll_time, Question, list/candidates, ignore_category, time_passed)
set waitfor = 0
G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
switch(ignore_category ? askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No","Never for this round", StealFocus=0, Timeout=poll_time) : askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
if(1)
G << "<span class='notice'>Choice registered: Yes.</span>"
if((world.time-time_passed)>poll_time)
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
G << 'sound/machines/buzz-sigh.ogg'
else
candidates += G
if(2)
G << "<span class='danger'>Choice registered: No.</span>"
if(3)
var/list/L = poll_ignore[ignore_category]
if(!L)
poll_ignore[ignore_category] = list()
poll_ignore[ignore_category] += G.ckey
G << "<span class='danger'>Choice registered: Never for this round.</span>"
/proc/pollCandidates(var/Question, var/jobbanType, var/datum/game_mode/gametypeCheck, var/be_special_flag = 0, var/poll_time = 300, var/ignore_category = null)
var/list/mob/dead/observer/candidates = list()
var/time_passed = world.time
if (!Question)
Question = "Would you like to be a special role?"
for(var/mob/dead/observer/G in player_list)
if(!G.key || !G.client)
if(!G.key || !G.client || (ignore_category && poll_ignore[ignore_category] && G.ckey in poll_ignore[ignore_category]))
continue
if(be_special_flag)
if(!(G.client.prefs) || !(be_special_flag in G.client.prefs.be_special))
@@ -411,18 +434,8 @@
if (jobbanType)
if(jobban_isbanned(G, jobbanType) || jobban_isbanned(G, "Syndicate"))
continue
spawn(0)
G << 'sound/misc/notice2.ogg' //Alerting them to their consideration
switch(askuser(G,Question,"Please answer in [poll_time/10] seconds!","Yes","No", StealFocus=0, Timeout=poll_time))
if(1)
G << "<span class='notice'>Choice registered: Yes.</span>"
if((world.time-time_passed)>poll_time)
G << "<span class='danger'>Sorry, you were too late for the consideration!</span>"
G << 'sound/machines/buzz-sigh.ogg'
else
candidates += G
if(2)
G << "<span class='danger'>Choice registered: No.</span>"
showCandidatePollWindow(G, poll_time, Question, candidates, ignore_category, time_passed)
sleep(poll_time)
//Check all our candidates, to make sure they didn't log off during the wait period.
@@ -430,8 +443,27 @@
if(!G.key || !G.client)
candidates.Remove(G)
listclearnulls(candidates)
return candidates
/proc/pollCandidatesForMob(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, mob/M, ignore_category = null)
var/list/L = pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category)
if(!M || qdeleted(M) || !M.loc)
return list()
return L
/proc/pollCandidatesForMobs(Question, jobbanType, datum/game_mode/gametypeCheck, be_special_flag = 0, poll_time = 300, list/mobs, ignore_category = null)
var/list/L = pollCandidates(Question, jobbanType, gametypeCheck, be_special_flag, poll_time, ignore_category)
var/i=1
for(var/v in mobs)
var/atom/A = v
if(!A || qdeleted(A) || !A.loc)
mobs.Cut(i,i+1)
else
++i
return L
/proc/makeBody(mob/dead/observer/G_found) // Uses stripped down and bastardized code from respawn character
if(!G_found || !G_found.key)
return
@@ -444,3 +476,13 @@
new_character.key = G_found.key
return new_character
/proc/send_to_playing_players(thing) //sends a whatever to all playing players; use instead of world << where needed
for(var/M in player_list)
if(M && !isnewplayer(M))
M << thing
/proc/window_flash(var/client_or_usr)
if (!client_or_usr)
return
winset(client_or_usr, "mainwindow", "flash=5")
+12
View File
@@ -23,12 +23,19 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, body_markings_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/lizard, tails_list_lizard)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/lizard, animated_tails_list_lizard)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, tails_list_human)
init_sprite_accessory_subtypes(/datum/sprite_accessory/tails_animated/human, animated_tails_list_human)
init_sprite_accessory_subtypes(/datum/sprite_accessory/snouts, snouts_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/horns, horns_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/ears, ears_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, wings_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings_open, wings_open_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, frills_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, spines_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/spines_animated, animated_spines_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, legs_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, r_wings_list,roundstart = TRUE)
//mammal bodyparts (fucking furries)
init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_body_markings, mam_body_markings_list)
init_sprite_accessory_subtypes(/datum/sprite_accessory/mam_tails, mam_tails_list)
@@ -65,6 +72,11 @@
var/datum/tech/D = new path()
tech_list[D.id] = D
//Emotes
for(var/path in subtypesof(/datum/emote))
var/datum/emote/E = new path()
emote_list[E.key] = E
init_subtypes(/datum/crafting_recipe, crafting_recipes)
/* // Uncomment to debug chemical reaction list.
+50 -48
View File
@@ -108,39 +108,39 @@
return adjacencies
//do not use, use queue_smooth(atom)
/proc/smooth_icon(atom/A)
if(!A || !A.smooth || !A.z)
return
if(qdeleted(A))
return
if(!A || !A.smooth)
return
spawn(0)
if((A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
var/adjacencies = calculate_adjacencies(A)
if((A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
var/adjacencies = calculate_adjacencies(A)
if(A.smooth & SMOOTH_DIAGONAL)
A.diagonal_smooth(adjacencies)
else
cardinal_smooth(A, adjacencies)
if(A.smooth & SMOOTH_DIAGONAL)
A.diagonal_smooth(adjacencies)
else
cardinal_smooth(A, adjacencies)
/atom/proc/diagonal_smooth(adjacencies)
switch(adjacencies)
if(N_NORTH|N_WEST)
replace_smooth_overlays("d1-se-0","d2-se","d3-se","d4-se")
replace_smooth_overlays("d-se","d-se-0")
if(N_NORTH|N_EAST)
replace_smooth_overlays("d1-sw","d2-sw-0","d3-sw","d4-sw")
replace_smooth_overlays("d-sw","d-sw-0")
if(N_SOUTH|N_WEST)
replace_smooth_overlays("d1-ne","d2-ne","d3-ne-0","d4-ne")
replace_smooth_overlays("d-ne","d-ne-0")
if(N_SOUTH|N_EAST)
replace_smooth_overlays("d1-nw","d2-nw","d3-nw","d4-nw-0")
replace_smooth_overlays("d-nw","d-nw-0")
if(N_NORTH|N_WEST|N_NORTHWEST)
replace_smooth_overlays("d1-se-1","d2-se","d3-se","d4-se")
replace_smooth_overlays("d-se","d-se-1")
if(N_NORTH|N_EAST|N_NORTHEAST)
replace_smooth_overlays("d1-sw","d2-sw-1","d3-sw","d4-sw")
replace_smooth_overlays("d-sw","d-sw-1")
if(N_SOUTH|N_WEST|N_SOUTHWEST)
replace_smooth_overlays("d1-ne","d2-ne","d3-ne-1","d4-ne")
replace_smooth_overlays("d-ne","d-ne-1")
if(N_SOUTH|N_EAST|N_SOUTHEAST)
replace_smooth_overlays("d1-nw","d2-nw","d3-nw","d4-nw-1")
replace_smooth_overlays("d-nw","d-nw-1")
else
cardinal_smooth(src, adjacencies)
@@ -153,25 +153,33 @@
/turf/closed/wall/diagonal_smooth(adjacencies)
adjacencies = reverse_ndir(..())
if(adjacencies)
underlays.Cut()
var/list/U = list()
if(fixed_underlay)
if(fixed_underlay["space"])
underlays += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=src.layer)
var/image/I = image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
I.plane = PLANE_SPACE
U += I
else
underlays += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=src.layer)
U += image(fixed_underlay["icon"], fixed_underlay["icon_state"], layer=TURF_LAYER)
else
var/turf/T = get_step(src, turn(adjacencies, 180))
if(T && T.density)
if(T && (T.density || T.smooth))
T = get_step(src, turn(adjacencies, 135))
if(T && T.density)
if(T && (T.density || T.smooth))
T = get_step(src, turn(adjacencies, 225))
if(istype(T, /turf/open/space))
underlays += image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=src.layer)
if(isspaceturf(T) && !istype(T, /turf/open/space/transit))
var/image/I = image('icons/turf/space.dmi', SPACE_ICON_STATE, layer=TURF_LAYER)
I.plane = PLANE_SPACE
U += I
else if(T && !T.density && !T.smooth)
underlays += T
U += T
else if(baseturf && !initial(baseturf.density) && !initial(baseturf.smooth))
U += image(initial(baseturf.icon), initial(baseturf.icon_state), layer=TURF_LAYER)
else
underlays += DEFAULT_UNDERLAY_IMAGE
U += DEFAULT_UNDERLAY_IMAGE
underlays = U
/proc/cardinal_smooth(atom/A, adjacencies)
//NW CORNER
@@ -226,25 +234,31 @@
else if(adjacencies & N_EAST)
se = "4-e"
var/list/New = list()
if(A.top_left_corner != nw)
A.overlays -= A.top_left_corner
A.top_left_corner = nw
A.add_overlay(nw)
New += nw
if(A.top_right_corner != ne)
A.overlays -= A.top_right_corner
A.top_right_corner = ne
A.add_overlay(ne)
New += ne
if(A.bottom_right_corner != sw)
A.overlays -= A.bottom_right_corner
A.bottom_right_corner = sw
A.add_overlay(sw)
New += sw
if(A.bottom_left_corner != se)
A.overlays -= A.bottom_left_corner
A.bottom_left_corner = se
A.add_overlay(se)
New += se
if(New.len)
A.add_overlay(New)
/proc/find_type_in_direction(atom/source, direction)
var/turf/target_turf = get_step(source, direction)
@@ -305,14 +319,16 @@
/atom/proc/replace_smooth_overlays(nw, ne, sw, se)
clear_smooth_overlays()
var/list/O = list()
top_left_corner = nw
add_overlay(nw)
O += nw
top_right_corner = ne
add_overlay(ne)
O += ne
bottom_left_corner = sw
add_overlay(sw)
O += sw
bottom_right_corner = se
add_overlay(se)
O += se
add_overlay(O)
/proc/reverse_ndir(ndir)
switch(ndir)
@@ -351,19 +367,6 @@
else
return 0
//SSicon_smooth
/proc/ss_smooth_icon(atom/A)
if(qdeleted(A))
return
if(!istype(A) || (A && !A.smooth))
return
if((A.smooth & SMOOTH_TRUE) || (A.smooth & SMOOTH_MORE))
var/adjacencies = calculate_adjacencies(A)
if(A.smooth & SMOOTH_DIAGONAL)
A.diagonal_smooth(adjacencies)
else
cardinal_smooth(A, adjacencies)
//SSicon_smooth
/proc/queue_smooth_neighbors(atom/A)
for(var/V in orange(1,A))
@@ -384,6 +387,5 @@
name = "smooth wall"
icon = 'icons/turf/smooth_wall.dmi'
icon_state = "smooth"
walltype = "shuttle"
smooth = SMOOTH_TRUE|SMOOTH_DIAGONAL|SMOOTH_BORDER
canSmoothWith = null
+31 -3
View File
@@ -199,7 +199,7 @@ mob
getFlatIcon(src)
Browse_Icon()
obj/effect/overlayTest
/obj/effect/overlayTest
icon = 'old_or_unused.dmi'
icon_state = "blue"
pixel_x = -24
@@ -948,9 +948,8 @@ var/global/list/friendly_animal_types = list()
overlays += priority_overlays
/atom/proc/add_overlay(image, priority = 0)
if(image in overlays)
return
var/list/new_overlays = overlays.Copy()
new_overlays -= image
if(priority)
if(!priority_overlays)
priority_overlays = list()
@@ -1007,3 +1006,32 @@ var/global/list/humanoid_icon_cache = list()
//Lame.
/image/proc/setDir(newdir)
dir = newdir
// Used to make the frozen item visuals for Freon.
var/list/freeze_item_icons = list()
/atom/proc/freeze_icon_index()
return "\ref[initial(icon)]-[initial(icon_state)]"
/obj/proc/make_frozen_visual()
if(!is_frozen && (initial(icon) && initial(icon_state)))
var/index = freeze_icon_index()
var/icon/IC
var/icon/P = freeze_item_icons[index]
if(!P)
P = new /icon
for(var/iconstate in icon_states(icon))
var/icon/O = new('icons/effects/freeze.dmi', "ice_cube")
IC = new(icon, iconstate)
O.Blend(IC, ICON_ADD)
P.Insert(O, iconstate)
freeze_item_icons[index] = P
icon = P
name = "frozen [name]"
is_frozen = TRUE
//Assumes already frozed
obj/proc/make_unfrozen()
icon = initial(icon)
name = replacetext(name, "frozen ", "")
is_frozen = FALSE
+64 -11
View File
@@ -76,9 +76,13 @@
. += A
//Like typesof() or subtypesof(), but returns a typecache instead of a list
/proc/typecacheof(path, ignore_root_path)
/proc/typecacheof(path, ignore_root_path, only_root_path = FALSE)
if(ispath(path))
var/list/types = ignore_root_path ? subtypesof(path) : typesof(path)
var/list/types = list()
if(only_root_path)
types = list(path)
else
types = ignore_root_path ? subtypesof(path) : typesof(path)
var/list/L = list()
for(var/T in types)
L[T] = TRUE
@@ -92,8 +96,11 @@
L[T] = TRUE
else
for(var/P in pathlist)
for(var/T in typesof(P))
L[T] = TRUE
if(only_root_path)
L[P] = TRUE
else
for(var/T in typesof(P))
L[T] = TRUE
return L
//Empties the list by setting the length to 0. Hopefully the elements get garbage collected
@@ -104,13 +111,8 @@
//Removes any null entries from the list
/proc/listclearnulls(list/L)
if(istype(L))
var/i=1
for(var/thing in L)
if(thing != null)
++i
continue
L.Cut(i,i+1)
var/list/N = new(L.len)
L -= N
/*
* Returns list containing all the entries from first list that are not present in second.
@@ -228,12 +230,30 @@
return L
//same, but returns nothing and acts on list in place
/proc/shuffle_inplace(list/L)
if(!L)
return
for(var/i=1, i<L.len, ++i)
L.Swap(i,rand(i,L.len))
//Return a list with no duplicate entries
/proc/uniqueList(list/L)
. = list()
for(var/i in L)
. |= i
//same, but returns nothing and acts on list in place (also handles associated values properly)
/proc/uniqueList_inplace(list/L)
var/temp = L.Copy()
L.len = 0
for(var/key in temp)
if (isnum(key))
L |= key
else
L[key] = temp[key]
//for sorting clients or mobs by ckey
/proc/sortKey(list/L, order=1)
return sortTim(L, order >= 0 ? /proc/cmp_ckey_asc : /proc/cmp_ckey_dsc)
@@ -392,5 +412,38 @@
if(islist(.[i]))
.[i] = .(.[i])
//takes an input_key, as text, and the list of keys already used, outputting a replacement key in the format of "[input_key] ([number_of_duplicates])" if it finds a duplicate
//use this for lists of things that might have the same name, like mobs or objects, that you plan on giving to a player as input
/proc/avoid_assoc_duplicate_keys(input_key, list/used_key_list)
if(!input_key || !istype(used_key_list))
return
if(used_key_list[input_key])
used_key_list[input_key]++
input_key = "[input_key] ([used_key_list[input_key]])"
else
used_key_list[input_key] = 1
return input_key
#if DM_VERSION > 512
#error Remie said that lummox was adding a way to get a lists
#error contents via list.values, if that is true remove this
#error otherwise, update the version and bug lummox
#elseif
//Flattens a keyed list into a list of it's contents
/proc/flatten_list(list/key_list)
if(!islist(key_list))
return null
. = list()
for(var/key in key_list)
. |= key_list[key]
//Picks from the list, with some safeties, and returns the "default" arg if it fails
#define DEFAULTPICK(L, default) ((istype(L, /list) && L:len) ? pick(L) : default)
#define LAZYINITLIST(L) if (!L) L = list()
#define UNSETEMPTY(L) if (L && !L.len) L = null
#define LAZYREMOVE(L, I) if(L) { L -= I; if(!L.len) { L = null; } }
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= L.len ? L[I] : null) : L[I]) : null)
#define LAZYLEN(L) length(L)
+3 -1
View File
@@ -20,8 +20,10 @@ var/list/sqrtTable = list(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
/proc/Ceiling(x, y=1)
return -round(-x / y) * y
/proc/Floor(x, y=1)
return round(x / y) * y
#define Clamp(CLVALUE,CLMIN,CLMAX) ( max( (CLMIN), min((CLVALUE), (CLMAX)) ) )
#define CLAMP01(x) (Clamp(x,0,1))
// cotangent
/proc/Cot(x)
+82 -77
View File
@@ -63,91 +63,96 @@
// Color matrices:
//Luma coefficients suggested for HDTVs. If you change these, make sure they add up to 1.
#define LUMR 0.2126
#define LUMG 0.7152
#define LUMB 0.0722
/* Documenting a couple of potentially useful color matrices here to inspire ideas
// Greyscale - indentical to saturation @ 0
list(LUMA_R,LUMA_R,LUMA_R,0, LUMA_G,LUMA_G,LUMA_G,0, LUMA_B,LUMA_B,LUMA_B,0, 0,0,0,1, 0,0,0,0)
//Still need color matrix addition, negation, and multiplication.
// Color inversion
list(-1,0,0,0, 0,-1,0,0, 0,0,-1,0, 0,0,0,1, 1,1,1,0)
//Returns an identity color matrix which does nothing
/proc/color_identity()
return list(1,0,0, 0,1,0, 0,0,1)
// Sepiatone
list(0.393,0.349,0.272,0, 0.769,0.686,0.534,0, 0.189,0.168,0.131,0, 0,0,0,1, 0,0,0,0)
*/
//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting whites
//TODO: Need a version that only affects one color (ie shift red to blue but leave greens and blues alone)
/proc/color_rotation(angle)
if(angle == 0)
return color_identity()
angle = Clamp(angle, -180, 180)
var/cos = cos(angle)
//Does nothing
/proc/color_matrix_identity()
return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0)
//Adds/subtracts overall lightness
//0 is identity, 1 makes everything white, -1 makes everything black
/proc/color_matrix_lightness(power)
return list(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1, power,power,power,0)
//Changes distance hues have from grey while maintaining the overall lightness. Greys are unaffected.
//1 is identity, 0 is greyscale, >1 oversaturates colors
/proc/color_matrix_saturation(value)
var/inv = 1 - value
var/R = round(LUMA_R * inv, 0.001)
var/G = round(LUMA_G * inv, 0.001)
var/B = round(LUMA_B * inv, 0.001)
return list(R + value,R,R,0, G,G + value,G,0, B,B,B + value,0, 0,0,0,1, 0,0,0,0)
//Changes distance colors have from rgb(127,127,127) grey
//1 is identity. 0 makes everything grey >1 blows out colors and greys
/proc/color_matrix_contrast(value)
var/add = (1 - value) / 2
return list(value,0,0,0, 0,value,0,0, 0,0,value,0, 0,0,0,1, add,add,add,0)
//Moves all colors angle degrees around the color wheel while maintaining intensity of the color and not affecting greys
//0 is identity, 120 moves reds to greens, 240 moves reds to blues
/proc/color_matrix_rotate_hue(angle)
var/sin = sin(angle)
var/constA = 0.143
var/constB = 0.140
var/constC = -0.283
var/cos = cos(angle)
var/cos_inv_third = 0.333*(1-cos)
var/sqrt3_sin = sqrt(3)*sin
return list(
LUMR + cos * (1-LUMR) + sin * -LUMR, LUMR + cos * -LUMR + sin * constA, LUMR + cos * -LUMR + sin * -(1-LUMR),
LUMG + cos * -LUMG + sin * -LUMG, LUMG + cos * (1-LUMG) + sin * constB, LUMG + cos * -LUMG + sin * LUMG,
LUMB + cos * -LUMB + sin * (1-LUMB), LUMB + cos * -LUMB + sin * constC, LUMB + cos * (1-LUMB) + sin * LUMB
)
round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), 0,
round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), round(cos_inv_third+sqrt3_sin, 0.001), 0,
round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), round(cos+cos_inv_third, 0.001), 0,
0,0,0,1,
0,0,0,0)
//Makes everything brighter or darker without regard to existing color or brightness
/proc/color_brightness(power)
power = Clamp(power, -255, 255)
power = power/255
//These next three rotate values about one axis only
//x is the red axis, y is the green axis, z is the blue axis.
/proc/color_matrix_rotate_x(angle)
var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001)
return list(1,0,0,0, 0,cosval,sinval,0, 0,-sinval,cosval,0, 0,0,0,1, 0,0,0,0)
return list(1,0,0, 0,1,0, 0,0,1, power,power,power)
/proc/color_matrix_rotate_y(angle)
var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001)
return list(cosval,0,-sinval,0, 0,1,0,0, sinval,0,cosval,0, 0,0,0,1, 0,0,0,0)
/var/list/delta_index = list(
0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11,
0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68,
0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25,
2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8,
4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0,
7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8,
10.0)
/proc/color_matrix_rotate_z(angle)
var/sinval = round(sin(angle), 0.001); var/cosval = round(cos(angle), 0.001)
return list(cosval,sinval,0,0, -sinval,cosval,0,0, 0,0,1,0, 0,0,0,1, 0,0,0,0)
//Exxagerates or removes brightness
/proc/color_contrast(value)
value = Clamp(value, -100, 100)
if(value == 0)
return color_identity()
var/x = 0
if (value < 0)
x = 127 + value / 100 * 127;
else
x = value % 1
if(x == 0)
x = delta_index[value]
else
x = delta_index[value] * (1-x) + delta_index[value+1] * x//use linear interpolation for more granularity.
x = x * 127 + 127
//Returns a matrix addition of A with B
/proc/color_matrix_add(list/A, list/B)
if(!istype(A) || !istype(B))
return color_matrix_identity()
if(A.len != 20 || B.len != 20)
return color_matrix_identity()
var/list/output = list()
output.len = 20
for(var/value in 1 to 20)
output[value] = A[value] + B[value]
return output
var/mult = x / 127
var/add = 0.5 * (127-x) / 255
return list(mult,0,0, 0,mult,0, 0,0,mult, add,add,add)
//Exxagerates or removes colors
/proc/color_saturation(value as num)
if(value == 0)
return color_identity()
value = Clamp(value, -100, 100)
if(value > 0)
value *= 3
var/x = 1 + value / 100
var/inv = 1 - x
var/R = LUMR * inv
var/G = LUMG * inv
var/B = LUMB * inv
return list(R + x,R,R, G,G + x,G, B,B,B + x)
#undef LUMR
#undef LUMG
#undef LUMB
//Returns a matrix multiplication of A with B
/proc/color_matrix_multiply(list/A, list/B)
if(!istype(A) || !istype(B))
return color_matrix_identity()
if(A.len != 20 || B.len != 20)
return color_matrix_identity()
var/list/output = list()
output.len = 20
var/x = 1
var/y = 1
var/offset = 0
for(y in 1 to 5)
offset = (y-1)*4
for(x in 1 to 4)
output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y==5?B[x+16]:0), 0.001)
return output
+70 -27
View File
@@ -62,13 +62,15 @@
init_sprite_accessory_subtypes(/datum/sprite_accessory/frills, frills_list)
if(!spines_list.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/spines, spines_list)
if(!legs_list.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/legs, legs_list)
if(!body_markings_list.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/body_markings, body_markings_list)
if(!wings_list.len)
init_sprite_accessory_subtypes(/datum/sprite_accessory/wings, wings_list)
//For now we will always return none for tail_human and ears.
return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "tail_lizard" = pick(tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(snouts_list), "horns" = pick(horns_list), "ears" = "None", "frills" = pick(frills_list), "spines" = pick(spines_list), "body_markings" = pick(body_markings_list)))
return(list("mcolor" = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F"), "tail_lizard" = pick(tails_list_lizard), "tail_human" = "None", "wings" = "None", "snout" = pick(snouts_list), "horns" = pick(horns_list), "ears" = "None", "frills" = pick(frills_list), "spines" = pick(spines_list), "body_markings" = pick(body_markings_list), "legs" = "Normal Legs"))
/proc/random_hair_style(gender)
switch(gender)
@@ -105,6 +107,13 @@
if(i != attempts_to_find_unique_name && !findname(.))
break
/proc/random_unique_plasmaman_name(attempts_to_find_unique_name=10)
for(var/i=1, i<=attempts_to_find_unique_name, i++)
. = capitalize(plasmaman_name())
if(i != attempts_to_find_unique_name && !findname(.))
break
/proc/random_skin_tone()
return pick(skin_tones)
@@ -161,24 +170,30 @@ Proc for attack log creation, because really why not
*/
/proc/add_logs(mob/user, mob/target, what_done, object=null, addition=null)
var/newhealthtxt = ""
var/coordinates = ""
var/turf/attack_location = get_turf(target)
if(attack_location)
coordinates = "([attack_location.x],[attack_location.y],[attack_location.z])"
if(target && isliving(target))
var/mob/living/L = target
newhealthtxt = " (NEWHP: [L.health])"
if(user && ismob(user))
user.attack_log += text("\[[time_stamp()]\] <font color='red'>Has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]</font>")
if(user.mind)
user.mind.attack_log += text("\[[time_stamp()]\] <font color='red'>[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has [what_done] [target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]</font>")
if(target && ismob(target))
target.attack_log += text("\[[time_stamp()]\] <font color='orange'>Has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]</font>")
if(target.mind)
target.mind.attack_log += text("\[[time_stamp()]\] <font color='orange'>[target ? "[target.name][(ismob(target) && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has been [what_done] by [user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]</font>")
log_attack("[user ? "[user.name][(ismob(user) && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(ismob(target) && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][newhealthtxt][coordinates]")
var/is_mob_user = user && typecache_mob[user.type]
var/is_mob_target = target && typecache_mob[target.type]
var/mob/living/living_target
if(target && isliving(target))
living_target = target
if(is_mob_user)
var/message = "\[[time_stamp()]\] <font color='red'>[user ? "[user.name][(user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has [what_done] [target ? "[target.name][(is_mob_target && target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
user.attack_log += message
if(user.mind)
user.mind.attack_log += message
if(is_mob_target)
var/message = "\[[time_stamp()]\] <font color='orange'>[target ? "[target.name][(target.ckey) ? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] has been [what_done] by [user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]</font>"
target.attack_log += message
if(target.mind)
target.mind.attack_log += message
log_attack("[user ? "[user.name][(is_mob_user && user.ckey) ? "([user.ckey])" : ""]" : "NON-EXISTANT SUBJECT"] [what_done] [target ? "[target.name][(is_mob_target && target.ckey)? "([target.ckey])" : ""]" : "NON-EXISTANT SUBJECT"][object ? " with [object]" : " "][addition][(living_target) ? " (NEWHP: [living_target.health])" : ""][(attack_location) ? "([attack_location.x],[attack_location.y],[attack_location.z])" : ""]")
/proc/do_mob(mob/user , mob/target, time = 30, uninterruptible = 0, progress = 1)
@@ -192,7 +207,7 @@ Proc for attack log creation, because really why not
var/target_loc = target.loc
var/holding = user.get_active_hand()
var/holding = user.get_active_held_item()
var/datum/progressbar/progbar
if (progress)
progbar = new(user, time, target)
@@ -214,7 +229,7 @@ Proc for attack log creation, because really why not
drifting = 0
user_loc = user.loc
if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_hand() != holding || user.incapacitated() || user.lying )
if((!drifting && user.loc != user_loc) || target.loc != target_loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying )
. = 0
break
if (progress)
@@ -234,7 +249,7 @@ Proc for attack log creation, because really why not
if(!user.Process_Spacemove(0) && user.inertia_dir)
drifting = 1
var/holding = user.get_active_hand()
var/holding = user.get_active_held_item()
var/holdingnull = 1 //User's hand started out empty, check for an empty hand
if(holding)
@@ -261,8 +276,9 @@ Proc for attack log creation, because really why not
break
if(Tloc && (!target || Tloc != target.loc))
. = 0
break
if((Uloc != Tloc || Tloc != user) && !drifting)
. = 0
break
if(needhand)
//This might seem like an odd check, but you can still need a hand even when it's empty
@@ -271,7 +287,7 @@ Proc for attack log creation, because really why not
if(!holding)
. = 0
break
if(user.get_active_hand() != holding)
if(user.get_active_held_item() != holding)
. = 0
break
if (progress)
@@ -292,7 +308,7 @@ Proc for attack log creation, because really why not
for(var/atom/target in targets)
originalloc[target] = target.loc
var/holding = user.get_active_hand()
var/holding = user.get_active_held_item()
var/datum/progressbar/progbar
if(progress)
progbar = new(user, time, targets[1])
@@ -316,7 +332,7 @@ Proc for attack log creation, because really why not
user_loc = user.loc
for(var/atom/target in targets)
if((!drifting && user_loc != user.loc) || originalloc[target] != target.loc || user.get_active_hand() != holding || user.incapacitated() || user.lying )
if((!drifting && user_loc != user.loc) || originalloc[target] != target.loc || user.get_active_held_item() != holding || user.incapacitated() || user.lying )
. = 0
break mainloop
if(progbar)
@@ -329,6 +345,33 @@ Proc for attack log creation, because really why not
if(H.dna && istype(H.dna.species, species_datum))
. = TRUE
/proc/spawn_atom_to_turf(spawn_type, target, amount, admin_spawn=FALSE)
var/turf/T = get_turf(target)
if(!T)
CRASH("attempt to spawn atom type: [spawn_type] in nullspace")
for(var/j in 1 to amount)
var/atom/X = new spawn_type(T)
X.admin_spawned = admin_spawn
/proc/spawn_and_random_walk(spawn_type, target, amount, walk_chance=100, max_walk=3, always_max_walk=FALSE, admin_spawn=FALSE)
var/turf/T = get_turf(target)
var/step_count = 0
if(!T)
CRASH("attempt to spawn atom type: [spawn_type] in nullspace")
for(var/j in 1 to amount)
var/atom/movable/X = new spawn_type(T)
X.admin_spawned = admin_spawn
if(always_max_walk || prob(walk_chance))
if(always_max_walk)
step_count = max_walk
else
step_count = rand(1, max_walk)
for(var/i in 1 to step_count)
step(X, pick(NORTH, SOUTH, EAST, WEST))
/proc/deadchat_broadcast(message, mob/follow_target=null, speaker_key=null, message_type=DEADCHAT_REGULAR)
for(var/mob/M in player_list)
@@ -341,7 +384,7 @@ Proc for attack log creation, because really why not
var/adminoverride = 0
if(M.client && M.client.holder && (prefs.chat_toggles & CHAT_DEAD))
adminoverride = 1
if(istype(M, /mob/new_player) && !adminoverride)
if(isnewplayer(M) && !adminoverride)
continue
if(M.stat != DEAD && !adminoverride)
continue
@@ -356,7 +399,7 @@ Proc for attack log creation, because really why not
if(prefs.toggles & DISABLE_ARRIVALRATTLE)
continue
if(istype(M, /mob/dead/observer) && follow_target)
if(isobserver(M) && follow_target)
var/link = FOLLOW_LINK(M, follow_target)
M << "[link] [message]"
else
+4 -2
View File
@@ -4,6 +4,8 @@
else
return "[pick(lizard_names_female)]-[pick(lizard_names_female)]"
/proc/plasmaman_name()
return "[pick(plasmaman_names)] \Roman[rand(1,99)]"
var/church_name = null
/proc/church_name()
@@ -100,7 +102,7 @@ var/religion_name = null
if(2)
new_station_name += pick(greek_letters)
if(3)
new_station_name += pick(roman_numerals)
new_station_name += "\Roman[rand(1,99)]"
if(4)
new_station_name += pick(phonetic_alphabet)
if(5)
@@ -170,7 +172,7 @@ var/syndicate_code_response//Code response for traitors.
var/safety[] = list(1,2,3)//Tells the proc which options to remove later on.
var/nouns[] = list("love","hate","anger","peace","pride","sympathy","bravery","loyalty","honesty","integrity","compassion","charity","success","courage","deceit","skill","beauty","brilliance","pain","misery","beliefs","dreams","justice","truth","faith","liberty","knowledge","thought","information","culture","trust","dedication","progress","education","hospitality","leisure","trouble","friendships", "relaxation")
var/drinks[] = list("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequila sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
var/drinks[] = list("vodka and tonic","gin fizz","bahama mama","manhattan","black Russian","whiskey soda","long island iced tea","margarita","Irish coffee"," manly dwarf","Irish cream","doctor's delight","Beepksy Smash","tequila sunrise","brave bull","gargle blaster","bloody mary","whiskey cola","white Russian","vodka martini","martini","Cuba libre","kahlua","vodka","wine","moonshine")
var/locations[] = teleportlocs.len ? teleportlocs : drinks//if null, defaults to drinks instead.
var/names[] = list()
+242
View File
@@ -0,0 +1,242 @@
//pronoun procs, for getting pronouns without using the text macros that only work in certain positions
//datums don't have gender, but most of their subtypes do!
/datum/proc/p_they(capitalized, temp_gender)
. = "it"
if(capitalized)
. = capitalize(.)
/datum/proc/p_their(capitalized, temp_gender)
. = "its"
if(capitalized)
. = capitalize(.)
/datum/proc/p_them(capitalized, temp_gender)
. = "it"
if(capitalized)
. = capitalize(.)
/datum/proc/p_have(temp_gender)
. = "has"
/datum/proc/p_are(temp_gender)
. = "is"
/datum/proc/p_were(temp_gender)
. = "was"
/datum/proc/p_do(temp_gender)
. = "does"
/datum/proc/p_theyve(capitalized, temp_gender)
. = p_they(capitalized, temp_gender) + "'" + copytext(p_have(temp_gender), 3)
/datum/proc/p_theyre(capitalized, temp_gender)
. = p_they(capitalized, temp_gender) + "'" + copytext(p_are(temp_gender), 2)
/datum/proc/p_s(temp_gender) //is this a descriptive proc name, or what?
. = "s"
//like clients, which do have gender.
/client/p_they(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "they"
switch(temp_gender)
if(FEMALE)
. = "she"
if(MALE)
. = "he"
if(capitalized)
. = capitalize(.)
/client/p_their(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "their"
switch(temp_gender)
if(FEMALE)
. = "her"
if(MALE)
. = "his"
if(capitalized)
. = capitalize(.)
/client/p_them(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "them"
switch(temp_gender)
if(FEMALE)
. = "her"
if(MALE)
. = "him"
if(capitalized)
. = capitalize(.)
/client/p_have(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "has"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "have"
/client/p_are(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "is"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "are"
/client/p_were(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "was"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "were"
/client/p_do(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "does"
if(temp_gender == PLURAL || temp_gender == NEUTER)
. = "do"
/client/p_s(temp_gender)
if(!temp_gender)
temp_gender = gender
if(temp_gender != PLURAL && temp_gender != NEUTER)
. = "s"
//mobs(and atoms but atoms don't really matter write your own proc overrides) also have gender!
/mob/p_they(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "it"
switch(temp_gender)
if(FEMALE)
. = "she"
if(MALE)
. = "he"
if(PLURAL)
. = "they"
if(capitalized)
. = capitalize(.)
/mob/p_their(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "its"
switch(temp_gender)
if(FEMALE)
. = "her"
if(MALE)
. = "his"
if(PLURAL)
. = "their"
if(capitalized)
. = capitalize(.)
/mob/p_them(capitalized, temp_gender)
if(!temp_gender)
temp_gender = gender
. = "it"
switch(temp_gender)
if(FEMALE)
. = "her"
if(MALE)
. = "him"
if(PLURAL)
. = "them"
if(capitalized)
. = capitalize(.)
/mob/p_have(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "has"
if(temp_gender == PLURAL)
. = "have"
/mob/p_are(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "is"
if(temp_gender == PLURAL)
. = "are"
/mob/p_were(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "was"
if(temp_gender == PLURAL)
. = "were"
/mob/p_do(temp_gender)
if(!temp_gender)
temp_gender = gender
. = "does"
if(temp_gender == PLURAL)
. = "do"
/mob/p_s(temp_gender)
if(!temp_gender)
temp_gender = gender
if(temp_gender != PLURAL)
. = "s"
//humans need special handling, because they can have their gender hidden
/mob/living/carbon/human/p_they(capitalized, temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_their(capitalized, temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_them(capitalized, temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_have(temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_are(temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_were(temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_do(temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
/mob/living/carbon/human/p_s(temp_gender)
var/list/obscured = check_obscured_slots()
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if((slot_w_uniform in obscured) && skipface)
temp_gender = PLURAL
return ..()
+118 -55
View File
@@ -206,6 +206,20 @@
if(start)
return findtextEx(text, suffix, start, null)
//Checks if any of a given list of needles is in the haystack
/proc/text_in_list(haystack, list/needle_list, start=1, end=0)
for(var/needle in needle_list)
if(findtext(haystack, needle, start, end))
return 1
return 0
//Like above, but case sensitive
/proc/text_in_list_case(haystack, list/needle_list, start=1, end=0)
for(var/needle in needle_list)
if(findtextEx(haystack, needle, start, end))
return 1
return 0
//Adds 'u' number of zeros ahead of the text 't'
/proc/add_zero(t, u)
while (length(t) < u)
@@ -421,66 +435,115 @@ var/list/binary = list("0","1")
return t
/proc/char_split(t)
. = list()
for(var/x in 1 to length(t))
. += copytext(t,x,x+1)
#define string2charlist(string) (splittext(string, regex("(.)")) - splittext(string, ""))
var/list/rot13_lookup = list()
/proc/rot13(text = "")
var/list/textlist = string2charlist(text)
var/list/result = list()
for(var/c in textlist)
var/ca = text2ascii(c)
if(ca >= text2ascii("a") && ca <= text2ascii("m"))
ca += 13
else if(ca >= text2ascii("n") && ca <= text2ascii("z"))
ca -= 13
else if(ca >= text2ascii("A") && ca <= text2ascii("M"))
ca += 13
else if(ca >= text2ascii("N") && ca <= text2ascii("Z"))
ca -= 13
result += ascii2text(ca)
return jointext(result, "")
/proc/generate_rot13_lookup()
var/letters = alphabet.Copy()
for(var/c in alphabet)
letters += uppertext(c)
//Takes a list of values, sanitizes it down for readability and character count,
//then exports it as a json file at data/npc_saves/[filename].json.
//As far as SS13 is concerned this is write only data. You can't change something
//in the json file and have it be reflected in the in game item/mob it came from.
//(That's what things like savefiles are for) Note that this list is not shuffled.
/proc/twitterize(list/proposed, filename, cullshort = 1, storemax = 1000)
if(!islist(proposed) || !filename || !config.log_twitter)
return
for(var/char in letters)
var/ascii_char = text2ascii(char, 1)
//Regular expressions are, as usual, absolute magic
var/regex/is_website = new("http|www.|\[a-z0-9_-]+.(com|org|net|mil|edu)+", "i")
var/regex/is_email = new("\[a-z0-9_-]+@\[a-z0-9_-]+.\[a-z0-9_-]+", "i")
var/regex/alphanumeric = new("\[a-z0-9]+", "i")
var/regex/punctuation = new("\[.!?]+", "i")
var/regex/all_invalid_symbols = new("\[^ -~]+")
var/index
var/list/accepted = list()
for(var/string in proposed)
if(findtext(string,is_website) || findtext(string,is_email) || findtext(string,all_invalid_symbols) || !findtext(string,alphanumeric))
continue
var/buffer = ""
var/early_culling = TRUE
for(var/pos = 1, pos <= lentext(string), pos++)
var/let = copytext(string, pos, (pos + 1) % lentext(string))
if(early_culling && !findtext(let,alphanumeric))
continue
early_culling = FALSE
buffer += let
if(!findtext(buffer,alphanumeric))
continue
var/punctbuffer = ""
var/cutoff = lentext(buffer)
for(var/pos = lentext(buffer), pos >= 0, pos--)
var/let = copytext(buffer, pos, (pos + 1) % lentext(buffer))
if(findtext(let,alphanumeric))
break
if(findtext(let,punctuation))
punctbuffer = let + punctbuffer //Note this isn't the same thing as using +=
cutoff = pos
if(punctbuffer) //We clip down excessive punctuation to get the letter count lower and reduce repeats. It's not perfect but it helps.
var/exclaim = FALSE
var/question = FALSE
var/periods = 0
for(var/pos = lentext(punctbuffer), pos >= 0, pos--)
var/punct = copytext(punctbuffer, pos, (pos + 1) % lentext(punctbuffer))
if(!exclaim && findtext(punct,"!"))
exclaim = TRUE
if(!question && findtext(punct,"?"))
question = TRUE
if(!exclaim && !question && findtext(punct,"."))
periods += 1
if(exclaim)
if(question)
punctbuffer = "?!"
else
punctbuffer = "!"
else if(question)
punctbuffer = "?"
else if(periods)
if(periods > 1)
punctbuffer = "..."
else
punctbuffer = "" //Grammer nazis be damned
buffer = copytext(buffer, 1, cutoff) + punctbuffer
if(!findtext(buffer,alphanumeric))
continue
if(!buffer || lentext(buffer) > 140 || lentext(buffer) <= cullshort || buffer in accepted)
continue
switch(ascii_char)
// A - Z
if(65 to 90)
index = 65
// a - z
if(97 to 122)
index = 97
accepted += buffer
var/d = ascii_char - index
d += 13
if(d >= 26)
d -= 26
ascii_char = index + d
var/translated_char = ascii2text(ascii_char)
var/log = file("data/npc_saves/[filename].json") //If this line ever shows up as changed in a PR be very careful you aren't being memed on
var/list/oldjson = list()
var/list/oldentries = list()
if(fexists(log))
oldjson = json_decode(file2text(log))
oldentries = oldjson["data"]
if(!isemptylist(oldentries))
for(var/string in accepted)
for(var/old in oldentries)
if(string == old)
oldentries.Remove(old) //Line's position in line is "refreshed" until it falls off the in game radar
break
rot13_lookup[char] = translated_char
var/list/finalized = list()
finalized = accepted.Copy() + oldentries.Copy() //we keep old and unreferenced phrases near the bottom for culling
listclearnulls(finalized)
if(!isemptylist(finalized) && length(finalized) > storemax)
finalized.Cut(storemax + 1)
fdel(log)
/proc/rot13(t_in)
if(!rot13_lookup.len)
generate_rot13_lookup()
var/t_out = ""
for(var/i in 1 to length(t_in))
var/char = copytext(t_in, i, i + 1)
if(char in rot13_lookup)
t_out += rot13_lookup[char]
else
t_out += char
return t_out
//Used in preferences' SetFlavorText and human's set_flavor verb
//Previews a string of len or less length
/proc/copytext_preserve_html(var/text, var/first, var/last)
return html_encode(copytext(html_decode(text), first, last))
proc/TextPreview(var/string,var/len=40)
if(lentext(string) <= len)
if(!lentext(string))
return "\[...\]"
else
return string
else
return "[copytext(string, 1, 37)]..."
var/list/tosend = list()
tosend["data"] = finalized
log << json_encode(tosend)
+9
View File
@@ -7,3 +7,12 @@
t = copytext(t, 1, index) + repl_chars[char] + copytext(t, index+5)
index = findtext(t, char)
return t
proc/TextPreview(var/string,var/len=40)
if(lentext(string) <= len)
if(!lentext(string))
return "\[...\]"
else
return string
else
return "[copytext(string, 1, 37)]..."
+11 -2
View File
@@ -6,7 +6,7 @@
return time2text(world.timeofday, format)
/proc/gameTimestamp(format = "hh:mm:ss") // Get the game time in text
return time2text(world.time - timezoneOffset + 432000, format)
return time2text(world.time - timezoneOffset + 432000 - round_start_time, format)
/* Returns 1 if it is the selected month and day */
/proc/isDay(month, day)
@@ -22,4 +22,13 @@
//returns timestamp in a sql and ISO 8601 friendly format
/proc/SQLtime()
return time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
return time2text(world.realtime, "YYYY-MM-DD hh:mm:ss")
/var/midnight_rollovers = 0
/var/rollovercheck_last_timeofday = 0
/proc/update_midnight_rollover()
if (world.timeofday < rollovercheck_last_timeofday) //TIME IS GOING BACKWARDS!
return midnight_rollovers++
return midnight_rollovers
+21 -71
View File
@@ -225,6 +225,8 @@
return 'icons/mob/screen_slimecore.dmi'
if("Operative")
return 'icons/mob/screen_operative.dmi'
if("Clockwork")
return 'icons/mob/screen_clockwork.dmi'
else
return 'icons/mob/screen_midnight.dmi'
@@ -347,55 +349,6 @@ for(var/t in test_times)
/proc/isLeap(y)
return ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
// A copy of text2dir, extended to accept one and two letter
// directions, and to clearly return 0 otherwise.
/proc/text2dir_extended(direction)
switch(uppertext(direction))
if("NORTH", "N")
return 1
if("SOUTH", "S")
return 2
if("EAST", "E")
return 4
if("WEST", "W")
return 8
if("NORTHEAST", "NE")
return 5
if("NORTHWEST", "NW")
return 9
if("SOUTHEAST", "SE")
return 6
if("SOUTHWEST", "SW")
return 10
else
return 0
// A copy of dir2text, which returns the short one or two letter
// directions used in tube icon states.
/proc/dir2text_short(direction)
switch(direction)
if(1)
return "N"
if(2)
return "S"
if(4)
return "E"
if(8)
return "W"
if(5)
return "NE"
if(6)
return "SE"
if(9)
return "NW"
if(10)
return "SW"
else
return
//Turns a Body_parts_covered bitfield into a list of organ/limb names.
@@ -574,26 +527,23 @@ for(var/t in test_times)
var/B = hex2num(copytext(A,6,0))
return R+G+B
//get just one color
/proc/GetRedPart(A)
return hex2num(copytext(A,2,4))
//word of warning: using a matrix like this as a color value will simplify it back to a string after being set
/proc/color_hex2color_matrix(string)
var/length = length(string)
if(length != 7 && length != 9)
return color_matrix_identity()
var/r = hex2num(copytext(string, 2, 4))/255
var/g = hex2num(copytext(string, 4, 6))/255
var/b = hex2num(copytext(string, 6, 8))/255
var/a = 1
if(length == 9)
a = hex2num(copytext(string, 8, 10))/255
if(!isnum(r) || !isnum(g) || !isnum(b) || !isnum(a))
return color_matrix_identity()
return list(r,0,0,0, 0,g,0,0, 0,0,b,0, 0,0,0,a, 0,0,0,0)
/proc/GetGreenPart(A)
return hex2num(copytext(A,4,6))
/proc/GetBluePart(A)
return hex2num(copytext(A,6,0))
//Converts a positive interger to its roman numeral equivilent. Ignores any decimals.
//Numbers over 3999 will display with extra "M"s (don't tell the Romans) and can get comically long, so be careful.
/proc/num2roman(A)
var/list/values = list("M" = 1000, "CM" = 900, "D" = 500, "CD" = 400, "C" = 100, "XC" = 90, "L" = 50, "XL" = 40, "X" = 10, "IX" = 9, "V" = 5, "IV" = 4, "I" = 1)
if(!A || !isnum(A))
return 0
while(A >= 1)
for(var/i in values)
if(A >= values[i])
. += i
A -= values[i]
break
//will drop all values not on the diagonal
/proc/color_matrix2color_hex(list/the_matrix)
if(!istype(the_matrix) || the_matrix.len != 20)
return "#ffffffff"
return rgb(the_matrix[1]*255, the_matrix[6]*255, the_matrix[11]*255, the_matrix[16]*255)
+170 -280
View File
@@ -1,4 +1,4 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/*
* A large number of misc global procs.
@@ -283,27 +283,20 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Returns a list of all items of interest with their name
/proc/getpois(mobs_only=0,skip_mindless=0)
var/list/mobs = sortmobs()
var/list/names = list()
var/list/pois = list()
var/list/namecounts = list()
var/list/pois = list()
for(var/mob/M in mobs)
if(skip_mindless && (!M.mind && !M.ckey))
if(!isbot(M) && !istype(M, /mob/camera/))
continue
if(M.client && M.client.holder && M.client.holder.fakekey) //stealthmins
continue
var/name = M.name
if (name in names)
namecounts[name]++
name = "[name] ([namecounts[name]])"
else
names.Add(name)
namecounts[name] = 1
if (M.real_name && M.real_name != M.name)
var/name = avoid_assoc_duplicate_keys(M.name, namecounts)
if(M.real_name && M.real_name != M.name)
name += " \[[M.real_name]\]"
if (M.stat == 2)
if(istype(M, /mob/dead/observer/))
if(M.stat == DEAD)
if(isobserver(M))
name += " \[ghost\]"
else
name += " \[dead\]"
@@ -313,14 +306,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
for(var/atom/A in poi_list)
if(!A || !A.loc)
continue
var/name = A.name
if (names.Find(name))
namecounts[name]++
name = "[name] ([namecounts[name]])"
else
names.Add(name)
namecounts[name] = 1
pois[name] = A
pois[avoid_assoc_duplicate_keys(A.name, namecounts)] = A
return pois
//Orders mobs by type then by name
@@ -337,7 +323,7 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
for(var/mob/living/carbon/human/M in sortmob)
moblist.Add(M)
for(var/mob/living/carbon/brain/M in sortmob)
for(var/mob/living/brain/M in sortmob)
moblist.Add(M)
for(var/mob/living/carbon/alien/M in sortmob)
moblist.Add(M)
@@ -359,41 +345,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
moblist.Add(M)
return moblist
/var/mob/dview/dview_mob = new
//Version of view() which ignores darkness, because BYOND doesn't have it (I actually suggested it but it was tagged redundant, BUT HEARERS IS A T- /rant).
/proc/dview(var/range = world.view, var/center, var/invis_flags = 0)
if(!center)
return
dview_mob.forceMove(center)
dview_mob.see_invisible = invis_flags
. = view(range, dview_mob)
dview_mob.forceMove(null)
/mob/dview
invisibility = 101
density = 0
see_in_dark = 1e6
anchored = 1
// Finds ALL mobs on turfs in line of sight. Similar to "in dview", but catches mobs that are not on a turf (e.g. inside a locker or such).
/proc/get_all_mobs_in_dview(var/turf/T, var/range = world.view, var/list/ignore_types = list())
. = list()
var/list/can_see = dview(range, T)
for(var/mob/M in can_see)
if(is_type_in_list(M, ignore_types))
continue
. += M
for(var/mob/M in mob_list) //Got the ones in vision, now let's go for the ones not on a turf.
if(M.z == 0) //Mobs not on a turf will have XYZ = 0,0,0. They also won't show up in dview() so we're not checking anything twice.
if(is_type_in_list(M, ignore_types))
continue
if(get_turf(M) in can_see) //Checking the mob's turf now, since those are it's "true" coordinates (plus dview() did pick up on turfs, so we can check using that).
. += M
//E = MC^2
/proc/convert2energy(M)
var/E = M*(SPEED_OF_LIGHT_SQ)
@@ -472,12 +423,15 @@ Turf and target are seperate in case you want to teleport some distance from a t
if(M.ckey == key)
return M
// Returns the atom sitting on the turf.
// For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
/proc/get_atom_on_turf(atom/movable/M)
//Returns the atom sitting on the turf.
//For example, using this on a disk, which is in a bag, on a mob, will return the mob because it's on the turf.
//Optional arg 'type' to stop once it reaches a specific type instead of a turf.
/proc/get_atom_on_turf(atom/movable/M, stop_type)
var/atom/loc = M
while(loc && loc.loc && !istype(loc.loc, /turf/))
while(loc && loc.loc && !isturf(loc.loc))
loc = loc.loc
if(stop_type && istype(loc, stop_type))
break
return loc
// returns the turf located at the map edge in the specified direction relative to A
@@ -531,25 +485,6 @@ Turf and target are seperate in case you want to teleport some distance from a t
var/y=arcsin(x/sqrt(1+x*x))
return y
/proc/anim(turf/location,target as mob|obj,a_icon,a_icon_state as text,flick_anim as text,sleeptime = 0,direction as num)
//This proc throws up either an icon or an animation for a specified amount of time.
//The variables should be apparent enough.
var/atom/movable/overlay/animation = new(location)
if(direction)
animation.setDir(direction)
animation.icon = a_icon
animation.layer = target:layer+1
if(a_icon_state)
animation.icon_state = a_icon_state
else
animation.icon_state = "blank"
animation.master = target
flick(flick_anim, animation)
sleep(max(sleeptime, 15))
qdel(animation)
/atom/proc/GetAllContents()
var/list/processing_list = list(src)
var/list/assembled = list()
@@ -587,12 +522,12 @@ Turf and target are seperate in case you want to teleport some distance from a t
return 1
/proc/is_blocked_turf(turf/T)
/proc/is_blocked_turf(turf/T, exclude_mobs)
if(T.density)
return 1
for(var/i in T)
var/atom/A = i
if(A.density)
if(A.density && (!exclude_mobs || !ismob(A)))
return 1
return 0
@@ -659,58 +594,60 @@ Turf and target are seperate in case you want to teleport some distance from a t
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all areas of that type in the world.
/proc/get_areas(areatype)
if(!areatype)
return null
/proc/get_areas(areatype, subtypes=TRUE)
if(istext(areatype))
areatype = text2path(areatype)
if(isarea(areatype))
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/areas = new/list()
for(var/area/N in world)
if(istype(N, areatype))
areas += N
var/list/areas = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in sortedAreas)
var/area/A = V
if(cache[A.type])
areas += V
else
for(var/V in sortedAreas)
var/area/A = V
if(A.type == areatype)
areas += V
return areas
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all turfs in areas of that type of that type in the world.
/proc/get_area_turfs(areatype, target_z = 0)
if(!areatype)
return null
/proc/get_area_turfs(areatype, target_z = 0, subtypes=FALSE)
if(istext(areatype))
areatype = text2path(areatype)
if(isarea(areatype))
else if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
else if(!ispath(areatype))
return null
var/list/turfs = new/list()
for(var/area/N in world)
if(istype(N, areatype))
for(var/turf/T in N)
var/list/turfs = list()
if(subtypes)
var/list/cache = typecacheof(areatype)
for(var/V in sortedAreas)
var/area/A = V
if(!cache[A.type])
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
else
for(var/V in sortedAreas)
var/area/A = V
if(A.type != areatype)
continue
for(var/turf/T in A)
if(target_z == 0 || target_z == T.z)
turfs += T
return turfs
//Takes: Area type as text string or as typepath OR an instance of the area.
//Returns: A list of all atoms (objs, turfs, mobs) in areas of that type of that type in the world.
/proc/get_area_all_atoms(areatype)
if(!areatype)
return null
if(istext(areatype))
areatype = text2path(areatype)
if(isarea(areatype))
var/area/areatemp = areatype
areatype = areatemp.type
var/list/atoms = new/list()
for(var/area/N in world)
if(istype(N, areatype))
for(var/atom/A in N)
atoms += A
return atoms
/proc/get_cardinal_dir(atom/A, atom/B)
var/dx = abs(B.x - A.x)
var/dy = abs(B.y - A.y)
@@ -757,15 +694,18 @@ Turf and target are seperate in case you want to teleport some distance from a t
return zone
/*
Gets the turf this atom's *ICON* appears to inhabit
It takes into account:
* Pixel_x/y
* Matrix x/y
NOTE: if your atom has non-standard bounds then this proc
will handle it, but:
* if the bounds are even, then there are an even amount of "middle" turfs, the one to the EAST, NORTH, or BOTH is picked
(this may seem bad, but you're atleast as close to the center of the atom as possible, better than byond's default loc being all the way off)
* if the bounds are odd, the true middle turf of the atom is returned
*/
/proc/get_turf_pixel(atom/movable/AM)
@@ -815,53 +755,27 @@ Turf and target are seperate in case you want to teleport some distance from a t
loc = loc.loc
return null
//Quick type checks for some tools
var/global/list/common_tools = list(
/obj/item/stack/cable_coil,
/obj/item/weapon/wrench,
/obj/item/weapon/weldingtool,
/obj/item/weapon/screwdriver,
/obj/item/weapon/wirecutters,
/obj/item/device/multitool,
/obj/item/weapon/crowbar)
/proc/istool(O)
if(O && is_type_in_list(O, common_tools))
return 1
return 0
/proc/is_pointed(obj/item/W)
if(istype(W, /obj/item/weapon/pen))
return 1
if(istype(W, /obj/item/weapon/screwdriver))
return 1
if(istype(W, /obj/item/weapon/reagent_containers/syringe))
return 1
if(istype(W, /obj/item/weapon/kitchen/fork))
return 1
else
return 0
//For objects that should embed, but make no sense being is_sharp or is_pointed()
//e.g: rods
var/list/can_embed_types = typecacheof(list(
/obj/item/stack/rods,
/obj/item/pipe))
/proc/can_embed(obj/item/W)
if(W.is_sharp())
return 1
if(is_pointed(W))
return 1
var/list/embed_items = list(\
/obj/item/stack/rods,\
)
if(is_type_in_list(W, embed_items))
if(is_type_in_typecache(W, can_embed_types))
return 1
/*
Checks if that loc and dir has a item on the wall
*/
var/list/WALLITEMS = list(
var/list/WALLITEMS = typecacheof(list(
/obj/machinery/power/apc, /obj/machinery/airalarm, /obj/item/device/radio/intercom,
/obj/structure/extinguisher_cabinet, /obj/structure/reagent_dispensers/peppertank,
/obj/machinery/status_display, /obj/machinery/requests_console, /obj/machinery/light_switch, /obj/structure/sign,
@@ -869,22 +783,22 @@ var/list/WALLITEMS = list(
/obj/machinery/computer/security/telescreen, /obj/machinery/embedded_controller/radio/simple_vent_controller,
/obj/item/weapon/storage/secure/safe, /obj/machinery/door_timer, /obj/machinery/flasher, /obj/machinery/keycard_auth,
/obj/structure/mirror, /obj/structure/fireaxecabinet, /obj/machinery/computer/security/telescreen/entertainment
)
))
var/list/WALLITEMS_EXTERNAL = list(
/obj/machinery/camera, /obj/machinery/camera_assembly,
/obj/machinery/light_construct, /obj/machinery/light)
var/list/WALLITEMS_EXTERNAL = typecacheof(list(
/obj/machinery/camera, /obj/structure/camera_assembly,
/obj/structure/light_construct, /obj/machinery/light))
var/list/WALLITEMS_INVERSE = list(
/obj/machinery/light_construct, /obj/machinery/light)
var/list/WALLITEMS_INVERSE = typecacheof(list(
/obj/structure/light_construct, /obj/machinery/light))
/proc/gotwallitem(loc, dir, var/check_external = 0)
var/locdir = get_step(loc, dir)
for(var/obj/O in loc)
if(is_type_in_list(O, WALLITEMS) && check_external != 2)
if(is_type_in_typecache(O, WALLITEMS) && check_external != 2)
//Direction works sometimes
if(is_type_in_list(O, WALLITEMS_INVERSE))
if(is_type_in_typecache(O, WALLITEMS_INVERSE))
if(O.dir == turn(dir, 180))
return 1
else if(O.dir == dir)
@@ -895,8 +809,8 @@ var/list/WALLITEMS_INVERSE = list(
if(get_turf_pixel(O) == locdir)
return 1
if(is_type_in_list(O, WALLITEMS_EXTERNAL) && check_external)
if(is_type_in_list(O, WALLITEMS_INVERSE))
if(is_type_in_typecache(O, WALLITEMS_EXTERNAL) && check_external)
if(is_type_in_typecache(O, WALLITEMS_INVERSE))
if(O.dir == turn(dir, 180))
return 1
else if(O.dir == dir)
@@ -904,7 +818,7 @@ var/list/WALLITEMS_INVERSE = list(
//Some stuff is placed directly on the wallturf (signs)
for(var/obj/O in locdir)
if(is_type_in_list(O, WALLITEMS) && check_external != 2)
if(is_type_in_typecache(O, WALLITEMS) && check_external != 2)
if(O.pixel_x == 0 && O.pixel_y == 0)
return 1
return 0
@@ -975,33 +889,34 @@ var/list/WALLITEMS_INVERSE = list(
return "white"
/proc/params2turf(scr_loc, turf/origin)
if(!scr_loc)
return null
var/tX = splittext(scr_loc, ",")
var/tY = splittext(tX[2], ":")
var/tZ = origin.z
tY = tY[1]
tX = splittext(tX[1], ":")
tX = tX[1]
tX = max(1, min(world.maxx, origin.x + (text2num(tX) - (world.view + 1))))
tY = max(1, min(world.maxy, origin.y + (text2num(tY) - (world.view + 1))))
tX = Clamp(origin.x + text2num(tX) - world.view - 1, 1, world.maxx)
tY = Clamp(origin.y + text2num(tY) - world.view - 1, 1, world.maxy)
return locate(tX, tY, tZ)
/proc/screen_loc2turf(text, turf/origin)
if(!text)
return null
var/tZ = splittext(text, ",")
var/tX = splittext(tZ[1], "-")
var/tY = text2num(tX[2])
tX = splittext(tZ[2], "-")
tX = text2num(tX[2])
tZ = origin.z
tX = max(1, min(origin.x + 7 - tX, world.maxx))
tY = max(1, min(origin.y + 7 - tY, world.maxy))
tX = Clamp(origin.x + 7 - tX, 1, world.maxx)
tY = Clamp(origin.y + 7 - tY, 1, world.maxy)
return locate(tX, tY, tZ)
/proc/IsValidSrc(A)
if(istype(A, /datum))
var/datum/B = A
return !qdeleted(B)
if(istype(A, /client))
return 1
/proc/IsValidSrc(datum/D)
if(istype(D))
return !qdeleted(D)
return 0
@@ -1023,7 +938,7 @@ var/list/WALLITEMS_INVERSE = list(
/proc/is_A_facing_B(atom/A,atom/B)
if(!istype(A) || !istype(B))
return 0
if(istype(A, /mob/living))
if(isliving(A))
var/mob/living/LA = A
if(LA.lying)
return 0
@@ -1038,6 +953,7 @@ var/list/WALLITEMS_INVERSE = list(
/*
rough example of the "cone" made by the 3 dirs checked
B
\
\
@@ -1053,68 +969,10 @@ B --><-- A
/
/
B
*/
//This is just so you can stop an orbit.
//orbit() can run without it (swap orbiting for A)
//but then you can never stop it and that's just silly.
/atom/movable/var/atom/orbiting = null
//A: atom to orbit
//radius: range to orbit at, radius of the circle formed by orbiting
//clockwise: whether you orbit clockwise or anti clockwise
//rotation_speed: how fast to rotate
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts)
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE)
if(!istype(A))
return
if(orbiting)
stop_orbit()
orbiting = A
var/matrix/initial_transform = matrix(transform)
var/lastloc = loc
//Head first!
if(pre_rotation)
var/matrix/M = matrix(transform)
var/pre_rot = 90
if(!clockwise)
pre_rot = -90
M.Turn(pre_rot)
transform = M
var/matrix/shift = matrix(transform)
shift.Translate(0,radius)
transform = shift
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
transform = initial_transform
while(orbiting && orbiting == A && A.loc)
var/targetloc = get_turf(A)
if(!lockinorbit && loc != lastloc && loc != targetloc)
break
loc = targetloc
lastloc = loc
stoplag()
if (orbiting == A) //make sure we haven't started orbiting something else.
orbiting = null
SpinAnimation(0,0)
/atom/movable/proc/stop_orbit()
orbiting = null
//Center's an image.
//Requires:
//The Image
@@ -1289,17 +1147,22 @@ B --><-- A
/proc/add_to_proximity_list(atom/A, range)
var/turf/T = get_turf(A)
if(!T || !A.loc)
throw EXCEPTION("Someone adding a prox sensor in nullspace")
var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z))
for(var/B in L)
var/turf/C = B
C.proximity_checkers |= A
LAZYINITLIST(C.proximity_checkers)
C.proximity_checkers[A] = TRUE
return L
/proc/remove_from_proximity_list(atom/A, range)
var/turf/T = get_turf(A)
/proc/remove_from_proximity_list(atom/A, range, oldloc = null)
var/turf/T = get_turf(oldloc ? oldloc : A)
var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z))
for(var/B in L)
var/turf/C = B
if (!C.proximity_checkers)
continue
C.proximity_checkers.Remove(A)
/proc/shift_proximity(atom/checker, atom/A, range, atom/B, newrange)
@@ -1313,10 +1176,13 @@ B --><-- A
var/list/O = M - L
for(var/C in N)
var/turf/D = C
if (!D.proximity_checkers)
continue
D.proximity_checkers.Remove(checker)
for(var/E in O)
var/turf/F = E
F.proximity_checkers |= checker
LAZYINITLIST(F.proximity_checkers)
F.proximity_checkers[checker] = TRUE
return 1
/proc/flick_overlay_static(image/I, atom/A, duration)
@@ -1329,13 +1195,13 @@ B --><-- A
/proc/get_areas_in_z(zlevel)
. = list()
var/validarea = 0
var/validarea = FALSE
for(var/V in sortedAreas)
var/area/A = V
validarea = 1
validarea = TRUE
for(var/turf/T in A)
if(T.z != zlevel)
validarea = 0
validarea = FALSE
break
if(validarea)
. += A
@@ -1347,7 +1213,7 @@ B --><-- A
if(!istype(A, type))
continue
var/distance = get_dist(source, A)
if(!closest_distance)
if(!closest_atom)
closest_distance = distance
closest_atom = A
else
@@ -1356,9 +1222,14 @@ B --><-- A
closest_atom = A
return closest_atom
proc/pick_closest_path(value)
var/list/matches = get_fancy_list_of_types()
if (!isnull(value) && value!="")
proc/pick_closest_path(value, list/matches = get_fancy_list_of_atom_types())
if (value == FALSE) //nothing should be calling us with a number, so this is safe
value = input("Enter type to find (blank for all, cancel to cancel)", "Search for type") as null|text
if (isnull(value))
return
value = trim(value)
if(!isnull(value) && value != "")
matches = filter_fancy_list(matches, value)
if(matches.len==0)
@@ -1368,7 +1239,7 @@ proc/pick_closest_path(value)
if(matches.len==1)
chosen = matches[1]
else
chosen = input("Select an atom type", "Spawn Atom", matches[1]) as null|anything in matches
chosen = input("Select a type", "Pick Type", matches[1]) as null|anything in matches
if(!chosen)
return
chosen = matches[chosen]
@@ -1379,17 +1250,21 @@ proc/pick_closest_path(value)
CRASH(msg)
//Key thing that stops lag. Cornerstone of performance in ss13, Just sitting here, in unsorted.dm.
//Increases delay as the server gets more overloaded,
//as sleeps aren't cheap and sleeping only to wake up and sleep again is wasteful
#define DELTA_CALC max(((max(world.tick_usage, world.cpu) / 100) * max(Master.sleep_delta,1)), 1)
/proc/stoplag()
. = 1
sleep(world.tick_lag)
if (world.tick_usage > TICK_LIMIT_TO_RUN) //woke up, still not enough tick, sleep for more.
. += 2
sleep(world.tick_lag*2)
if (world.tick_usage > TICK_LIMIT_TO_RUN) //woke up, STILL not enough tick, sleep for more.
. += 4
sleep(world.tick_lag*4)
//you might be thinking of adding more steps to this, or making it use a loop and a counter var
// not worth it.
. = 0
var/i = 1
do
. += round(i*DELTA_CALC)
sleep(i*world.tick_lag*DELTA_CALC)
i *= 2
while (world.tick_usage > min(TICK_LIMIT_TO_RUN, CURRENT_TICKLIMIT))
#undef DELTA_CALC
/proc/flash_color(mob_or_client, flash_color="#960000", flash_time=20)
var/client/C
@@ -1406,31 +1281,11 @@ proc/pick_closest_path(value)
return
C.color = flash_color
spawn(0)
animate(C, color = initial(C.color), time = flash_time)
animate(C, color = initial(C.color), time = flash_time)
#define RANDOM_COLOUR (rgb(rand(0,255),rand(0,255),rand(0,255)))
#define QDEL_IN(item, time) addtimer(GLOBAL_PROC, "qdel", time, FALSE, item)
/proc/check_for_cleanbot_bug()
var/static/admins_warned //bet you didn't know you could do this!
var/icon/Icon_test = icon('icons/BadAss.dmi')
if(!istype(Icon_test))
var/msg = "Cleanbot bug detected in icons! Icons are mapping to [Icon_test]"
if (!admins_warned)
admins_warned = 1
spawn(25)
message_admins(msg)
stack_trace(msg)
var/sound/Sound_test = sound('sound/misc/null.ogg')
if(!istype(Sound_test))
var/msg = "Cleanbot bug detected in sounds! Sounds are mapping to [Sound_test]"
if (!admins_warned)
admins_warned = 1
spawn(25)
message_admins(msg)
stack_trace(msg)
#define QDEL_IN(item, time) addtimer(CALLBACK(GLOBAL_PROC, .proc/qdel, item), time, TIMER_STOPPABLE)
/proc/random_nukecode()
var/val = rand(0, 99999)
@@ -1439,10 +1294,45 @@ proc/pick_closest_path(value)
str = "0" + str
. = str
/proc/trange(var/Dist = 0, var/turf/Center = null)
if (isnull(Center))
return
/atom/proc/Shake(pixelshiftx = 15, pixelshifty = 15, duration = 250)
var/initialpixelx = pixel_x
var/initialpixely = pixel_y
var/shiftx = rand(-pixelshiftx,pixelshiftx)
var/shifty = rand(-pixelshifty,pixelshifty)
animate(src, pixel_x = pixel_x + shiftx, pixel_y = pixel_y + shifty, time = 0.2, loop = duration)
pixel_x = initialpixelx
pixel_y = initialpixely
var/turf/x1y1 = locate(((Center.x - Dist) < 1 ? 1 : Center.x - Dist), ((Center.y - Dist) < 1 ? 1 : Center.y - Dist), Center.z)
var/turf/x2y2 = locate(((Center.x + Dist) > world.maxx ? world.maxx : Center.x + Dist), ((Center.y + Dist) > world.maxy ? world.maxy : Center.y + Dist), Center.z)
return block(x1y1, x2y2)
/proc/weightclass2text(var/w_class)
switch(w_class)
if(WEIGHT_CLASS_TINY)
. = "tiny"
if(WEIGHT_CLASS_SMALL)
. = "small"
if(WEIGHT_CLASS_NORMAL)
. = "normal-sized"
if(WEIGHT_CLASS_BULKY)
. = "bulky"
if(WEIGHT_CLASS_HUGE)
. = "huge"
if(WEIGHT_CLASS_GIGANTIC)
. = "gigantic"
else
. = ""
//can a window be here, or is there a window blocking it?
/proc/valid_window_location(turf/T, dir_to_check)
if(!T)
return FALSE
for(var/obj/O in T)
if(istype(O, /obj/machinery/door/window) && (O.dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR))
return FALSE
if(istype(O, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = O
if(W.ini_dir == dir_to_check || dir_to_check == FULLTILE_WINDOW_DIR)
return FALSE
if(istype(O, /obj/structure/window))
var/obj/structure/window/W = O
if(W.ini_dir == dir_to_check || W.ini_dir == FULLTILE_WINDOW_DIR || dir_to_check == FULLTILE_WINDOW_DIR)
return FALSE
return TRUE