Tg patch branch to master (#192)

* code nitpicking

* Midnight oil

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

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Tg modern (#149)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

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

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

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

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

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

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* Vore code sync (#157)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

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

* code nitpicking

* Midnight oil

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

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

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

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

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

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

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

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* edgy code of the modernization (#164)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

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

* code nitpicking

* Midnight oil

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

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

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

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

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

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

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

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

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

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* Merge test onto bleeding edgy (#165)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

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

* code nitpicking

* Midnight oil

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

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

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

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

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

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

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

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

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

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* travis map updates

* updates

* pool's closed due to lag

* datum pools are closed too

* Initializing new pool's closed

* Pool's closed and initializing shit is done

* sprite updates

* chattering is okay to do now.

* bleeblin edgy 1/23 (#166)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Escape and Devourable

For the normies who play here yet complain about it.

* Things that should be committed

* unneeded files

* Sizeray works now

* tweaks and bed time going

* IT WORKS mostly

Need to get multiple guts and saving working tho

* save tweaks

* item hotfix

* gut examine message

* damifino

* save system works

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

* code nitpicking

* Midnight oil

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

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* missed commit

* Noms

* specific release doesn't work

* Tg modernization patch (#115)

* sync (#3)

* shuttle auto call

* Merge /vore into /master (#39)

* progress

* Compile errors fixed

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

* Update admins.txt

* efforts continue

Fuck grab code, seriously

* grab code is cancer

* Execute the Narkism

Do not hesitate.

Show no mercy.

* holy shit grab code is awful

* have I bitched about grab code

My bitching, let me show you it

* código de agarre es una mierda

No really it is

* yeah I don't even know anymore.

* Lolnope. Fuck grab code

* I'm not even sure what to fix anymore

* Self eating is not an acceptable fate

* Taste the void, son.

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

Maybe it's a sign of things to come.

* uncommented and notes

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

* shuttle auto call

* it works and I don't know why

* Subsystem 12/21

Most Recent TG subsystem folder

* globalvars 12/21

Tossed out the flavor_misc and parallax files

* Onclick 12/21

as well as .dme updates

* _defines 12/21

ommited old _MC.dm

* _HELPERS 12/21

Preserved snowflake placement of furry sprites

* _defeines/genetics

reapplied narkism holdover for snowflake races.

* Oops forgot mutant colors

* modules porting 12/21 + Sounds/icons

Admin, Client and most of mob life files ommitted

* enviroment file

* Admin optimizations

ahelp log system kept

* Mob ports 12/21

Flavor text preserved

* datums ported 12/21

* Game ported 12/21

* batch of duplicate fixes/dogborg work

Dogborgs need to be modernized to refractored borg standards.

* moar fixes

* Maps and futher compile fixes

* port from cactus did

* fix format error

* Update preferences.dm

unfuck

* Revert "port from cactus did"

* unfuck

* more sprite work

* vore

* disabled roundstart xenos for now

* admin QOL

needs callback porting, TBD

* Mentor system initial port

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

* test merge

* Jesus tits did this finally fix compile issues?

* Initial test compiles. hooray.

* Admin ticket fixes

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

* who list wip

also ahelps are broken again. fuck if I know why

* discord bot basics

* maybe tickets work now & bot framework done

* ahelp callback readd

* vore tweaks

* progress

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

* dirtier fix than a korean hooker in the 60s

* The release your hooker will always fake

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

* Save system is literal black magic

* great googly moogly it's all gone to shit

* We May 2015 save code now

* fiddling with digestion code now

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

* OWN UP YOUR OWN DIGESTION

* UNREGULATED GUTS ARE NON COMPLIANT

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

* BELLIES MUST COMPLY WITH USER OWNERSHIP

* Removed debug messages

* Unneeded verb additions

* file change tweaks

* WATCH YOUR SPACING, DRIVER

* Changelog and devourment for some mobs.

Because I knew people were gunna ask.

NO YOU CANNOT EAT THE FUCKING LEGION

* title screen change from Crow's PR.

* More of Crow's title screen stuff

* mode tweaks.... again

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

* LOOC

* index sync problem (#158)

* digifix

* things

* furry races.dm

* actually deletes species_types

* maps

* tgui and stuff

* Sounds

* icon updates

* Defines and helpers

* global vars and on click

* controllers

* datums

* game folder

* fixes invisible flan mobs

* some modules

* dropbomb verb enhanced

* moar

* moar

* moar

* even more again

* and finally these for modules

* Some compile tweaks

* silly dme get updated you scrub

* compiles cleanly now

* various open PR fixes from TG

as of 0800 Texas Standard Time

* also fancy cryopods before I forget again

* headslug gold core fix

* some species and DNA tweaks

* Digest already damn you

* suddenly sound and resist works. wtf

* Minor tweaks, cryopod noise change

* Vore tested working, species working

* travis map updates

* updates

* pool's closed due to lag

* datum pools are closed too

* Initializing new pool's closed

* Pool's closed and initializing shit is done

* sprite updates

* chattering is okay to do now.

* Update .travis.yml

* Update .travis.yml

* Update .travis.yml

* Revert "Modern modern"

* Revert "Revert "Modern modern""

* fix it fix it fix it fix it

* fixes title screen - thanks crow

* Riding code reverted

* possible tgui fix?

* who the fuck even knows if this is the problem

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

* "fixes" missing items in some machinery.

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

* Update .travis.yml

* fixes shuttle purchase from comms

* fixes and QoL

* Polymorphing all is dangerous too

* re-fixes ahelp ticket system again

* metagaming check proving to be spamlicious

* Fixes not being able to see devoured mob poses

* fix for vehicle buckling

* ahelp timer runtime fix (#178)

* controller and game updates 1/29

* Defines, helpers, datums 1/29

* world.dm updates

* modules/admin tweaks

* everything in modules not a mob

* modules/mob fixes and such

No more PAIs ventcrawling

* icons, maps, tools, etc.

* compiler fixes

* round type vote fixed

* hardsuit cargo pack

* reduce ion and electric storm chance

* perms access for travis

* fix helmet to the suit
removes CE from crate

* changelog

* fuck

* perms for travis... again

* Update tgstation.dme

* Update tgstation.dme

* Donation race

* redpanda

* red panda

* size play work

* Size chemical basics

Needs testing/refining

* some fixing ports before I just fucking ported it anyway

* It's been a fucking week.

* commiting moar changes because github

* admins.txt lol

* icons

* defines and such

* globalvars and onclick

* Controllers

* datums

* game folder

* oh look, HoG is back

* modules pt 1

* client things

* more modules

* everything not mob code

* some mob stuff

* more mob things

* silicon mobs

* ayylims and monkeys

* human updates

* huh

* housekeeping is fired.

* last minute fixes

* more last minute things

* human parts double check'd

* more paper

* Icons are fixed

* double check of thermal protection code. (#191)
This commit is contained in:
TalkingCactus
2017-02-03 06:56:14 -05:00
committed by Poojawa
parent 7735dec0ec
commit f7c09077d2
2489 changed files with 830965 additions and 416701 deletions
+44 -2
View File
@@ -176,9 +176,45 @@ You can set verify to TRUE if you want send() to sleep until the client has the
/datum/asset/simple/tgui
assets = list(
"tgui.css" = 'tgui/assets/tgui.css',
"tgui.js" = 'tgui/assets/tgui.js'
"tgui.js" = 'tgui/assets/tgui.js',
"font-awesome.min.css" = 'tgui/assets/font-awesome.min.css',
"fontawesome-webfont.eot" = 'tgui/assets/fonts/fontawesome-webfont.eot',
"fontawesome-webfont.woff2" = 'tgui/assets/fonts/fontawesome-webfont.woff2',
"fontawesome-webfont.woff" = 'tgui/assets/fonts/fontawesome-webfont.woff',
"fontawesome-webfont.ttf" = 'tgui/assets/fonts/fontawesome-webfont.ttf',
"fontawesome-webfont.svg" = 'tgui/assets/fonts/fontawesome-webfont.svg'
)
/datum/asset/simple/headers
assets = list(
"alarm_green.gif" = 'icons/program_icons/alarm_green.gif',
"alarm_red.gif" = 'icons/program_icons/alarm_red.gif',
"batt_5.gif" = 'icons/program_icons/batt_5.gif',
"batt_20.gif" = 'icons/program_icons/batt_20.gif',
"batt_40.gif" = 'icons/program_icons/batt_40.gif',
"batt_60.gif" = 'icons/program_icons/batt_60.gif',
"batt_80.gif" = 'icons/program_icons/batt_80.gif',
"batt_100.gif" = 'icons/program_icons/batt_100.gif',
"charging.gif" = 'icons/program_icons/charging.gif',
"downloader_finished.gif" = 'icons/program_icons/downloader_finished.gif',
"downloader_running.gif" = 'icons/program_icons/downloader_running.gif',
"ntnrc_idle.gif" = 'icons/program_icons/ntnrc_idle.gif',
"ntnrc_new.gif" = 'icons/program_icons/ntnrc_new.gif',
"power_norm.gif" = 'icons/program_icons/power_norm.gif',
"power_warn.gif" = 'icons/program_icons/power_warn.gif',
"sig_high.gif" = 'icons/program_icons/sig_high.gif',
"sig_low.gif" = 'icons/program_icons/sig_low.gif',
"sig_lan.gif" = 'icons/program_icons/sig_lan.gif',
"sig_none.gif" = 'icons/program_icons/sig_none.gif',
)
/datum/asset/simple/pda
assets = list(
"pda_atmos.png" = 'icons/pda_icons/pda_atmos.png',
@@ -206,7 +242,8 @@ You can set verify to TRUE if you want send() to sleep until the client has the
"pda_refresh.png" = 'icons/pda_icons/pda_refresh.png',
"pda_scanner.png" = 'icons/pda_icons/pda_scanner.png',
"pda_signaler.png" = 'icons/pda_icons/pda_signaler.png',
"pda_status.png" = 'icons/pda_icons/pda_status.png'
"pda_status.png" = 'icons/pda_icons/pda_status.png',
"pda_dronephone.png" = 'icons/pda_icons/pda_dronephone.png'
)
/datum/asset/simple/paper
@@ -224,6 +261,11 @@ You can set verify to TRUE if you want send() to sleep until the client has the
"large_stamp-law.png" = 'icons/stamp_icons/large_stamp-law.png'
)
/datum/asset/simple/IRV
assets = list(
"jquery-ui.custom-core-widgit-mouse-sortable-min.js" = 'html/IRV/jquery-ui.custom-core-widgit-mouse-sortable-min.js',
"jquery-1.10.2.min.js" = 'html/IRV/jquery-1.10.2.min.js'
)
//Registers HTML Interface assets.
/datum/asset/HTML_interface/register()
+38 -2
View File
@@ -27,7 +27,7 @@
colour_type - a typepath (subtyped from /datum/client_colour)
*/
/mob/proc/add_client_colour(colour_type)
if(!ispath(/datum/client_colour))
if(!ispath(colour_type, /datum/client_colour))
return
var/datum/client_colour/CC = new colour_type()
@@ -41,7 +41,7 @@
colour_type - a typepath (subtyped from /datum/client_colour)
*/
/mob/proc/remove_client_colour(colour_type)
if(!ispath(/datum/client_colour))
if(!ispath(colour_type, /datum/client_colour))
return
for(var/cc in client_colours)
@@ -70,3 +70,39 @@
/datum/client_colour/glass_colour
priority = 0
colour = "red"
/datum/client_colour/glass_colour/green
colour = "#aaffaa"
/datum/client_colour/glass_colour/lightgreen
colour = "#ccffcc"
/datum/client_colour/glass_colour/blue
colour = "#aaaaff"
/datum/client_colour/glass_colour/lightblue
colour = "#ccccff"
/datum/client_colour/glass_colour/yellow
colour = "#ffff66"
/datum/client_colour/glass_colour/red
colour = "#ffaaaa"
/datum/client_colour/glass_colour/darkred
colour = "#bb5555"
/datum/client_colour/glass_colour/orange
colour = "#ffbb99"
/datum/client_colour/glass_colour/lightorange
colour = "#ffddaa"
/datum/client_colour/glass_colour/purple
colour = "#ff99ff"
/datum/client_colour/glass_colour/gray
colour = "#cccccc"
+12 -12
View File
@@ -1,5 +1,9 @@
/client
//////////////////////
//BLACK MAGIC THINGS//
//////////////////////
parent_type = /datum
////////////////
//ADMIN THINGS//
////////////////
@@ -10,6 +14,7 @@
var/jobbancache = null //Used to cache this client's jobbans to save on DB queries
var/last_message = "" //Contains the last message sent by this client - used to protect against copy-paste spamming.
var/last_message_count = 0 //contins a number of how many times a message identical to last_message was sent.
var/ircreplyamount = 0
/////////
//OTHER//
@@ -50,16 +55,11 @@
//datum that controls the displaying and hiding of tooltips
var/datum/tooltip/tooltips
//Used for var edit flagging, also defined in datums (clients are not a child of datums for some reason)
var/var_edited = 0
var/lastping = 0
var/avgping = 0
var/connection_time //world.time they connected
var/connection_realtime //world.realtime they connected
var/connection_timeofday //world.timeofday they connected
////////////
//PARALLAX//
////////////
var/list/parallax = list()
var/list/parallax_movable = list()
var/list/parallax_offset = list()
var/turf/previous_turf = null
var/obj/screen/plane_master/parallax_master/parallax_master = null
var/obj/screen/plane_master/parallax_dustmaster/parallax_dustmaster = null
var/obj/screen/plane_master/parallax_spacemaster/parallax_spacemaster = null
var/inprefs = FALSE
var/list/topiclimiter
+219 -21
View File
@@ -3,6 +3,12 @@
////////////
#define UPLOAD_LIMIT 1048576 //Restricts client uploads to the server to 1MB //Could probably do with being lower.
#define LIMITER_SIZE 5
#define CURRENT_SECOND 1
#define SECOND_COUNT 2
#define CURRENT_MINUTE 3
#define MINUTE_COUNT 4
#define ADMINSWARNED_AT 5
/*
When somebody clicks a link in game, this Topic is called first.
It does the stuff in this proc and then is redirected to the Topic() proc for the src=[0xWhatever]
@@ -18,15 +24,55 @@
- If so, is there any protection against somebody spam-clicking a link?
If you have any questions about this stuff feel free to ask. ~Carn
*/
/client/Topic(href, href_list, hsrc)
if(!usr || usr != mob) //stops us calling Topic for somebody else's client. Also helps prevent usr=null
return
// asset_cache
if(href_list["asset_cache_confirm_arrival"])
//src << "ASSET JOB [href_list["asset_cache_confirm_arrival"]] ARRIVED."
var/job = text2num(href_list["asset_cache_confirm_arrival"])
completed_asset_jobs += job
return
//because we skip the limiter, we have to make sure this is a valid arrival and not somebody tricking us
// into letting append to a list without limit.
if (job && job <= last_asset_job && !(job in completed_asset_jobs))
completed_asset_jobs += job
return
if (!holder && config.minutetopiclimit)
var/minute = round(world.time, 600)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
if (minute != topiclimiter[CURRENT_MINUTE])
topiclimiter[CURRENT_MINUTE] = minute
topiclimiter[MINUTE_COUNT] = 0
topiclimiter[MINUTE_COUNT] += 1
if (topiclimiter[MINUTE_COUNT] > config.minutetopiclimit)
var/msg = "Your previous action was ignored because you've done too many in a minute."
if (minute != topiclimiter[ADMINSWARNED_AT]) //only one admin message per-minute. (if they spam the admins can just boot/ban them)
topiclimiter[ADMINSWARNED_AT] = minute
msg += " Administrators have been informed."
log_game("[key_name(src)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
message_admins("[key_name_admin(src)] [ADMIN_KICK(usr)] Has hit the per-minute topic limit of [config.minutetopiclimit] topic calls in a given game minute")
src << "<span class='danger'>[msg]</span>"
return
if (!holder && config.secondtopiclimit)
var/second = round(world.time, 10)
if (!topiclimiter)
topiclimiter = new(LIMITER_SIZE)
if (second != topiclimiter[CURRENT_SECOND])
topiclimiter[CURRENT_SECOND] = second
topiclimiter[SECOND_COUNT] = 0
topiclimiter[SECOND_COUNT] += 1
if (topiclimiter[SECOND_COUNT] > config.secondtopiclimit)
src << "<span class='danger'>Your previous action was ignored because you've done too many in a second</span>"
return
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
// Admin PM
if(href_list["priv_msg"])
if (href_list["ahelp_reply"])
@@ -35,6 +81,14 @@
cmd_admin_pm(href_list["priv_msg"],null)
return
if(href_list["mentor_msg"])
if(config.mentors_mobname_only)
var/mob/M = locate(href_list["mentor_msg"])
cmd_mentor_pm(M,null)
else
cmd_mentor_pm(href_list["mentor_msg"],null)
return
//Logs all hrefs
if(config && config.log_hrefs && href_logfile)
href_logfile << "<small>[time2text(world.timeofday,"hh:mm")] [src] (usr:[usr])</small> || [hsrc ? "[hsrc] " : ""][href]<br>"
@@ -45,7 +99,12 @@
if("usr")
hsrc = mob
if("prefs")
return prefs.process_link(usr,href_list)
if (inprefs)
return
inprefs = TRUE
. = prefs.process_link(usr,href_list)
inprefs = FALSE
return
if("vars")
return view_var_Topic(href,href_list,hsrc)
@@ -97,7 +156,7 @@ var/next_external_rsc = 0
/client/New(TopicData)
var/tdata = TopicData //save this for later use
TopicData = null //Prevent calls to client.Topic from connect
if(connection != "seeker" && connection != "web")//Invalid connection type.
@@ -136,20 +195,34 @@ var/next_external_rsc = 0
admins |= src
holder.owner = src
//Mentor Authorisation
var/mentor = mentor_datums[ckey]
if(mentor)
verbs += /client/proc/cmd_mentor_say
verbs += /client/proc/show_mentor_memo
mentors += src
if(check_rights(R_ADMIN))
if(ahelp_count(0) > 0)
list_ahelps(src, 0)
//preferences datum - also holds some persistant data for the client (because we may as well keep these datums to a minimum)
//preferences datum - also holds some persistent data for the client (because we may as well keep these datums to a minimum)
prefs = preferences_datums[ckey]
if(!prefs)
prefs = new /datum/preferences(src)
preferences_datums[ckey] = prefs
prefs.last_ip = address //these are gonna be used for banning
prefs.last_id = computer_id //these are gonna be used for banning
if(world.byond_version >= 511 && byond_version >= 511 && prefs.clientfps)
vars["fps"] = prefs.clientfps
sethotkeys(1) //set hoykeys from preferences (from_pref = 1)
. = ..() //calls mob.Login()
connection_time = world.time
connection_realtime = world.realtime
connection_timeofday = world.timeofday
if (byond_version < config.client_error_version) //Out of date client.
src << "<span class='danger'><b>Your version of byond is too old:</b></span>"
src << config.client_error_message
@@ -159,7 +232,7 @@ var/next_external_rsc = 0
if (holder)
src << "Because you are an admin, you are being allowed to walk past this limitation, But it is still STRONGLY suggested you upgrade"
else
del(src)
qdel(src)
return 0
else if (byond_version < config.client_warn_version) //We have words for this client.
src << "<span class='danger'><b>Your version of byond may be getting out of date:</b></span>"
@@ -168,14 +241,14 @@ var/next_external_rsc = 0
src << "Required version to remove this message: [config.client_warn_version] or later"
src << "Visit http://www.byond.com/download/ to get the latest version of byond."
if (connection == "web")
if (connection == "web" && !holder)
if (!config.allowwebclient)
src << "Web client is disabled"
del(src)
qdel(src)
return 0
if (config.webclientmembersonly && !IsByondMember())
src << "Sorry, but the web client is restricted to byond members only."
del(src)
qdel(src)
return 0
if( (world.address == address || !address) && !host )
@@ -189,6 +262,9 @@ var/next_external_rsc = 0
if((global.comms_key == "default_pwd" || length(global.comms_key) <= 6) && global.comms_allowed) //It's the default value or less than 6 characters long, but it somehow didn't disable comms.
src << "<span class='danger'>The server's API key is either too short or is the default value! Consider changing it immediately!</span>"
if(mentor && !holder)
mentor_memo_output("Show")
add_verbs_from_config()
set_client_age_from_db()
@@ -197,13 +273,17 @@ var/next_external_rsc = 0
log_access("Failed Login: [key] - New account attempting to connect during panic bunker")
message_admins("<span class='adminnotice'>Failed Login: [key] - New account attempting to connect during panic bunker</span>")
src << "Sorry but the server is currently not accepting connections from never before seen players."
del(src)
if(config.allow_panic_bunker_bounce && tdata != "redirect")
src << "<span class='notice'>Sending you to [config.panic_server_name].</span>"
winset(src, null, "command=.options")
src << link("[config.panic_address]?redirect")
qdel(src)
return 0
if (config.notify_new_player_age >= 0)
message_admins("New user: [key_name_admin(src)] is connecting here for the first time.")
if (config.irc_first_connection_alert)
send2irc_adminless_only("New-user", "[key_name(src)] is connecting for the first time!")
send2admindiscord("New-user", "[key_name(src)] is connecting for the first time!")
player_age = 0 // set it from -1 to 0 so the job selection code doesn't have a panic attack
@@ -213,7 +293,7 @@ var/next_external_rsc = 0
if(!IsGuestKey(key) && dbcon.IsConnected())
findJoinDate()
sync_client_with_db()
sync_client_with_db(tdata)
check_ip_intel()
@@ -221,7 +301,6 @@ var/next_external_rsc = 0
if(!void)
void = new()
void = void.MakeGreed()
screen += void
@@ -260,8 +339,13 @@ var/next_external_rsc = 0
admins -= src
directory -= ckey
clients -= src
if(movingmob != null)
movingmob.client_mobs_in_contents -= mob
UNSETEMPTY(movingmob.client_mobs_in_contents)
return ..()
/client/Destroy()
return QDEL_HINT_HARDDEL_NOW
/client/proc/set_client_age_from_db()
if (IsGuestKey(src.key))
@@ -285,7 +369,7 @@ var/next_external_rsc = 0
player_age = -1
/client/proc/sync_client_with_db()
/client/proc/sync_client_with_db(connectiontopic)
if (IsGuestKey(src.key))
return
@@ -293,7 +377,7 @@ var/next_external_rsc = 0
if (!dbcon.IsConnected())
return
var/sql_ckey = sanitizeSQL(src.ckey)
var/sql_ckey = sanitizeSQL(ckey)
var/DBQuery/query_ip = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip = '[address]' AND ckey != '[sql_ckey]'")
query_ip.Execute()
@@ -307,14 +391,18 @@ var/next_external_rsc = 0
while (query_cid.NextRow())
related_accounts_cid += "[query_cid.item[1]], "
var/watchreason = check_watchlist(sql_ckey)
if(watchreason)
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]</font>")
send2irc_adminless_only("Watchlist", "[key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
var/admin_rank = "Player"
if (src.holder && src.holder.rank)
admin_rank = src.holder.rank.name
else
if (check_randomizer(connectiontopic))
return
var/watchreason = check_watchlist(sql_ckey)
if(watchreason)
current_watchlist[sql_ckey] = watchreason
message_admins("<font color='red'><B>Notice: </B></font><font color='blue'>[key_name_admin(src)] is on the watchlist and has just connected - Reason: [watchreason]</font>")
// send2irc_adminless_only("Watchlist", "[key_name(src)] is on the watchlist and has just connected - Reason: [watchreason]")
var/sql_ip = sanitizeSQL(src.address)
var/sql_computerid = sanitizeSQL(src.computer_id)
@@ -329,6 +417,107 @@ var/next_external_rsc = 0
var/DBQuery/query_accesslog = dbcon.NewQuery("INSERT INTO `[format_table_name("connection_log")]` (`id`,`datetime`,`serverip`,`ckey`,`ip`,`computerid`) VALUES(null,Now(),'[serverip]','[sql_ckey]','[sql_ip]','[sql_computerid]');")
query_accesslog.Execute()
/client/proc/check_randomizer(topic)
. = FALSE
if (connection != "seeker")
return
topic = params2list(topic)
if (!config.check_randomizer)
return
var/static/cidcheck = list()
var/static/tokens = list()
var/static/cidcheck_failedckeys = list() //to avoid spamming the admins if the same guy keeps trying.
var/static/cidcheck_spoofckeys = list()
var/oldcid = cidcheck[ckey]
if (oldcid)
if (!topic || !topic["token"] || !tokens[ckey] || topic["token"] != tokens[ckey])
if (!cidcheck_spoofckeys[ckey])
message_admins("<span class='adminnotice'>[key_name(src)] appears to have attempted to spoof a cid randomizer check.</span>")
cidcheck_spoofckeys[ckey] = TRUE
cidcheck[ckey] = computer_id
tokens[ckey] = cid_check_reconnect()
sleep(10) //browse is queued, we don't want them to disconnect before getting the browse() command.
qdel(src)
return TRUE
if (oldcid != computer_id) //IT CHANGED!!!
cidcheck -= ckey //so they can try again after removing the cid randomizer.
src << "<span class='userdanger'>Connection Error:</span>"
src << "<span class='danger'>Invalid ComputerID(spoofed). Please remove the ComputerID spoofer from your byond installation and try again.</span>"
if (!cidcheck_failedckeys[ckey])
message_admins("<span class='adminnotice'>[key_name(src)] has been detected as using a cid randomizer. Connection rejected.</span>")
send2admindiscord("CidRandomizer", "[key_name(src)] has been detected as using a cid randomizer. Connection rejected.")
cidcheck_failedckeys[ckey] = TRUE
note_randomizer_user()
log_access("Failed Login: [key] [computer_id] [address] - CID randomizer confirmed (oldcid: [oldcid])")
qdel(src)
return TRUE
else
if (cidcheck_failedckeys[ckey])
message_admins("<span class='adminnotice'>[key_name_admin(src)] has been allowed to connect after showing they removed their cid randomizer</span>")
send2admindiscord("CidRandomizer", "[key_name(src)] has been allowed to connect after showing they removed their cid randomizer.")
cidcheck_failedckeys -= ckey
if (cidcheck_spoofckeys[ckey])
message_admins("<span class='adminnotice'>[key_name_admin(src)] has been allowed to connect after appearing to have attempted to spoof a cid randomizer check because it <i>appears</i> they aren't spoofing one this time</span>")
cidcheck_spoofckeys -= ckey
cidcheck -= ckey
else
var/sql_ckey = sanitizeSQL(ckey)
var/DBQuery/query_cidcheck = dbcon.NewQuery("SELECT computerid FROM [format_table_name("player")] WHERE ckey = '[sql_ckey]'")
query_cidcheck.Execute()
var/lastcid
if (query_cidcheck.NextRow())
lastcid = query_cidcheck.item[1]
if (computer_id != lastcid)
cidcheck[ckey] = computer_id
tokens[ckey] = cid_check_reconnect()
sleep(10) //browse is queued, we don't want them to disconnect before getting the browse() command.
qdel(src)
return TRUE
/client/proc/cid_check_reconnect()
var/token = md5("[rand(0,9999)][world.time][rand(0,9999)][ckey][rand(0,9999)][address][rand(0,9999)][computer_id][rand(0,9999)]")
. = token
log_access("Failed Login: [key] [computer_id] [address] - CID randomizer check")
var/url = winget(src, null, "url")
//special javascript to make them reconnect under a new window.
src << browse("<a id='link' href='byond://[url]?token=[token]'>byond://[url]?token=[token]</a><script type='text/javascript'>document.getElementById(\"link\").click();window.location=\"byond://winset?command=.quit\"</script>", "border=0;titlebar=0;size=1x1")
src << "<a href='byond://[url]?token=[token]'>You will be automatically taken to the game, if not, click here to be taken manually</a>"
/client/proc/note_randomizer_user()
var/const/adminckey = "CID-Error"
var/sql_ckey = sanitizeSQL(ckey)
//check to see if we noted them in the last day.
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id FROM [format_table_name("notes")] WHERE ckey = '[sql_ckey]' AND adminckey = '[adminckey]' AND timestamp + INTERVAL 1 DAY < NOW()")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining id from notes table. Error : \[[err]\]\n")
return
if (query_get_notes.NextRow())
return
//regardless of above, make sure their last note is not from us, as no point in repeating the same note over and over.
query_get_notes = dbcon.NewQuery("SELECT adminckey FROM [format_table_name("notes")] WHERE ckey = '[sql_ckey]' ORDER BY timestamp DESC LIMIT 1")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining id from notes table. Error : \[[err]\]\n")
return
if (query_get_notes.NextRow())
if (query_get_notes.item[1] == adminckey)
return
add_note(ckey, "Detected as using a cid randomizer.", null, adminckey, 0, null, 0)
/client/proc/check_ip_intel()
set waitfor = 0 //we sleep when getting the intel, no need to hold up the client connection while we sleep
if (config.ipintel_email)
@@ -384,4 +573,13 @@ var/next_external_rsc = 0
//Hook, override it to run code when dir changes
//Like for /atoms, but clients are their own snowflake FUCK
/client/proc/setDir(newdir)
dir = newdir
dir = newdir
/client/vv_edit_var(var_name, var_value)
switch (var_name)
if ("holder")
return FALSE
if ("ckey")
return FALSE
if ("key")
return FALSE
+1 -1
View File
@@ -1,6 +1,6 @@
var/list/clientmessages = list()
proc/addclientmessage(var/ckey, var/message)
/proc/addclientmessage(var/ckey, var/message)
ckey = ckey(ckey)
if (!ckey || !message)
return
+227 -201
View File
@@ -1,10 +1,11 @@
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
var/list/preferences_datums = list()
/datum/preferences
var/client/parent
//doohickeys for savefiles
var/path
var/default_slot = 1 //Holder so it doesn't default to slot 1, rather the last one used
@@ -41,23 +42,7 @@ var/list/preferences_datums = list()
var/allow_midround_antag = 1
var/preferred_map = null
var/vore_banned_methods = 0
var/vore_extra_bans = 65535
var/list/vore_ability = list(
"1"=2,
"2"=0,
"4"=0,
"8"=0,
"16"=0,
"32"=0,
"64"=1,
"128"=0,
"256"=2) //BAAAAD way to do this
var/character_size="normal"
var/be_taur=0
var/list/p_cock=list("has"=0,"type"="human","color"="900","sheath"="FFF")
var/p_vagina=0
var/uses_glasses_colour = 0
//character preferences
var/real_name //our character's name
@@ -76,13 +61,13 @@ var/list/preferences_datums = list()
var/skin_tone = "caucasian1" //Skin color
var/eye_color = "000" //Eye color
var/datum/species/pref_species = new /datum/species/human() //Mutant race
var/list/features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "tail_lizard" = "Smooth",
"tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None",
"wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
"mam_body_markings" = "None", "mam_ears" = "None", "mam_tail" = "None", "mam_tail_animated" = "None",
"xenodorsal" = "None", "xenohead" = "None", "xenotail" = "None")
var/list/features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "tail_lizard" = "Smooth", "tail_human" = "None", "snout" = "Round", "horns" = "None", "ears" = "None", "wings" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "mam_body_markings" = "None", "mam_ears" = "None", "mam_tail" = "None", "mam_tail_animated" = "None",
"xenodorsal" = "None", "xenohead" = "None", "xenotail" = "None", "legs" = "Normal Legs")
var/list/custom_names = list("clown", "mime", "ai", "cyborg", "religion", "deity")
var/prefered_security_department = SEC_DEPT_RANDOM
var/uplink_spawn_loc = UPLINK_PDA
//Mob preview
var/icon/preview_icon = null
@@ -100,29 +85,26 @@ var/list/preferences_datums = list()
var/job_engsec_low = 0
// Want randomjob if preferences already filled - Donkie
var/userandomjob = 1 //defaults to 1 for fewer assistants
var/joblessrole = BERANDOMJOB //defaults to 1 for fewer assistants
// 0 = character settings, 1 = game preferences
var/current_tab = 0
// OOC Metadata:
//var/metadata = ""
var/flavor_text = ""
// Vore prefs
var/digestable = 1
var/list/belly_prefs = list()
// OOC Metadata:
var/metadata = ""
var/unlock_content = 0
var/list/ignoring = list()
//Parallax prefs
var/space_parallax = 1
var/space_dust = 1
var/parallax_speed = 2
var/clientfps = 0
var/parallax = PARALLAX_DISABLE //Starting disabled by default so people stop freaking about about certain issues.
/datum/preferences/New(client/C)
parent = C
custom_names["ai"] = pick(ai_names)
custom_names["cyborg"] = pick(ai_names)
custom_names["clown"] = pick(clown_names)
@@ -132,13 +114,12 @@ var/list/preferences_datums = list()
load_path(C.ckey)
unlock_content = C.IsByondMember()
if(unlock_content)
max_save_slots = 15
max_save_slots = 16
var/loaded_preferences_successfully = load_preferences()
if(loaded_preferences_successfully)
if(load_character())
if(load_vore_preferences())
return
return
//we couldn't load character data so just randomize the character appearance + name
random_character() //let's create a random character then - rather than a fat, bald and naked man.
real_name = pref_species.random_name(gender,1)
@@ -147,7 +128,6 @@ var/list/preferences_datums = list()
save_character() //let's save this new random character so it doesn't keep generating new ones.
return
/datum/preferences/proc/ShowChoices(mob/user)
if(!user || !user.client)
return
@@ -185,7 +165,7 @@ var/list/preferences_datums = list()
dat += "<a href='?_src_=prefs;preference=job;task=menu'>Set Occupation Preferences</a><br></center>"
dat += "<h2>Identity</h2>"
dat += "<table width='100%'><tr><td width='75%' valign='top'>"
if(appearance_isbanned(user))
if(jobban_isbanned(user, "appearance"))
dat += "<b>You are banned from using custom names and appearances. You can continue to adjust your characters, but you will be randomised once you join the game.</b><br>"
dat += "<a href='?_src_=prefs;preference=name;task=random'>Random Name</A> "
dat += "<a href='?_src_=prefs;preference=name'>Always Random Name: [be_random_name ? "Yes" : "No"]</a><BR>"
@@ -202,8 +182,10 @@ var/list/preferences_datums = list()
dat += "<a href ='?_src_=prefs;preference=ai_name;task=input'><b>AI:</b> [custom_names["ai"]]</a> "
dat += "<a href ='?_src_=prefs;preference=cyborg_name;task=input'><b>Cyborg:</b> [custom_names["cyborg"]]</a><BR>"
dat += "<a href ='?_src_=prefs;preference=religion_name;task=input'><b>Chaplain religion:</b> [custom_names["religion"]] </a>"
dat += "<a href ='?_src_=prefs;preference=deity_name;task=input'><b>Chaplain deity:</b> [custom_names["deity"]]</a><BR></td>"
dat += "<a href ='?_src_=prefs;preference=deity_name;task=input'><b>Chaplain deity:</b> [custom_names["deity"]]</a><BR>"
dat += "<b>Custom job preferences:</b><BR>"
dat += "<a href='?_src_=prefs;preference=sec_dept;task=input'><b>Prefered security department:</b> [prefered_security_department]</a><BR></td>"
dat += "<td valign='center'>"
@@ -219,14 +201,15 @@ var/list/preferences_datums = list()
if(config.mutant_races)
dat += "<b>Species:</b><BR><a href='?_src_=prefs;preference=species;task=input'>[pref_species.id]</a><BR>"
dat += "<BR>"
else
dat += "<b>Species:</b> Human<BR>"
dat += "<b>Underwear:</b><BR><a href ='?_src_=prefs;preference=underwear;task=input'>[underwear]</a><BR>"
dat += "<b>Undershirt:</b><BR><a href ='?_src_=prefs;preference=undershirt;task=input'>[undershirt]</a><BR>"
dat += "<b>Socks:</b><BR><a href ='?_src_=prefs;preference=socks;task=input'>[socks]</a><BR>"
dat += "<b>Backpack:</b><BR><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><BR></td>"
dat += "<b>Backpack:</b><BR><a href ='?_src_=prefs;preference=bag;task=input'>[backbag]</a><BR>"
dat += "<b>Uplink Spawn Location:</b><BR><a href ='?_src_=prefs;preference=uplink_loc;task=input'>[uplink_spawn_loc]</a><BR></td>"
// dat += "<b>Size:</b> <a href='?_src_=prefs;preference=character_size;task=input'>[character_size]</a><BR>"
dat += "<a href='byond://?src=\ref[user];preference=flavor_text;task=input'><b>Set Flavor Text</b></a><br>"
@@ -239,6 +222,7 @@ var/list/preferences_datums = list()
dat += "[TextPreview(flavor_text)]...<br>"
dat += "<br>"
dat += "<br>"
if(pref_species.use_skintones)
dat += "<td valign='top' width='21%'>"
@@ -249,7 +233,7 @@ var/list/preferences_datums = list()
dat += "</td>"
if(HAIR in pref_species.specflags)
if(HAIR in pref_species.species_traits)
dat += "<td valign='top' width='21%'>"
@@ -270,7 +254,7 @@ var/list/preferences_datums = list()
dat += "</td>"
if(EYECOLOR in pref_species.specflags)
if(EYECOLOR in pref_species.species_traits)
dat += "<td valign='top' width='21%'>"
@@ -282,7 +266,7 @@ var/list/preferences_datums = list()
if(config.mutant_races) //We don't allow mutant bodyparts for humans either unless this is true.
if((MUTCOLORS in pref_species.specflags) || (MUTCOLORS_PARTSONLY in pref_species.specflags))
if((MUTCOLORS in pref_species.species_traits) || (MUTCOLORS_PARTSONLY in pref_species.species_traits))
dat += "<td valign='top' width='21%'>"
@@ -295,7 +279,7 @@ var/list/preferences_datums = list()
dat += "<span style='border: 1px solid #161616; background-color: #[features["mcolor3"]];'>&nbsp;&nbsp;&nbsp;</span> <a href='?_src_=prefs;preference=mutant_color3;task=input'>Change</a><BR>"
dat += "</td>"
//lizard bodyparts
if("tail_lizard" in pref_species.mutant_bodyparts)
dat += "<td valign='top' width='7%'>"
@@ -349,7 +333,8 @@ var/list/preferences_datums = list()
dat += "<a href='?_src_=prefs;preference=body_markings;task=input'>[features["body_markings"]]</a><BR>"
dat += "</td>"
//Mammal bodyparts
//Mammal bodyparts
if("mam_body_markings" in pref_species.mutant_bodyparts)
dat += "<td valign='top' width='7%'>"
@@ -366,6 +351,13 @@ var/list/preferences_datums = list()
dat += "<a href='?_src_=prefs;preference=mam_tail;task=input'>[features["mam_tail"]]</a><BR>"
if("legs" in pref_species.mutant_bodyparts)
dat += "<td valign='top' width='7%'>"
dat += "<h3>Legs</h3>"
dat += "<a href='?_src_=prefs;preference=legs;task=input'>[features["legs"]]</a><BR>"
dat += "</td>"
if("mam_ears" in pref_species.mutant_bodyparts)
@@ -440,7 +432,7 @@ var/list/preferences_datums = list()
if (1) // Game Preferences
dat += "<table><tr><td width='340px' height='300px' valign='top'>"
dat += "<h2>General Settings</h2>"
dat += "<b>UI Style:</b> <a href='?_src_=prefs;preference=ui'>[UI_style]</a><br>"
dat += "<b>UI Style:</b> <a href='?_src_=prefs;task=input;preference=ui'>[UI_style]</a><br>"
dat += "<b>Keybindings:</b> <a href='?_src_=prefs;preference=hotkeys'>[(hotkeys) ? "Hotkeys" : "Default"]</a><br>"
dat += "<b>tgui Style:</b> <a href='?_src_=prefs;preference=tgui_fancy'>[(tgui_fancy) ? "Fancy" : "No Frills"]</a><br>"
dat += "<b>tgui Monitors:</b> <a href='?_src_=prefs;preference=tgui_lock'>[(tgui_lock) ? "Primary" : "All"]</a><br>"
@@ -449,14 +441,10 @@ var/list/preferences_datums = list()
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
dat += "<b>Ghost sight:</b> <a href='?_src_=prefs;preference=ghost_sight'>[(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</a><br>"
dat += "<b>Ghost whispers:</b> <a href='?_src_=prefs;preference=ghost_whispers'>[(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]</a><br>"
dat += "<b>Ghost radio:</b> <a href='?_src=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]</a><br>"
dat += "<b>Ghost pda:</b> <a href='?_src=prefs;preference=ghost_pda'>[(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]</a><br>"
dat += "<b>Ghost radio:</b> <a href='?_src_=prefs;preference=ghost_radio'>[(chat_toggles & CHAT_GHOSTRADIO) ? "Yes" : "No"]</a><br>"
dat += "<b>Ghost pda:</b> <a href='?_src_=prefs;preference=ghost_pda'>[(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]</a><br>"
dat += "<b>Pull requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]</a><br>"
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]</a><br>"
dat += "<b>Space Parallax:</b> <a href='?_src_=prefs;preference=parallax'>[space_parallax ? "Enabled" : "Disabled"]</a><br>"
if(space_parallax)
dat += "<b>Parallax Speed:</b> <a href='?_src_=prefs;preference=p_speed'>[parallax_speed]</a><br>"
dat += "<b>Space Dust:</b> <a href='?_src_=prefs;preference=dust'>[space_dust ? "Yes" : "No"]</a><br>"
if(config.allow_Metadata)
dat += "<b>OOC Notes:</b> <a href='?_src_=prefs;preference=metadata;task=input'>Edit </a><br>"
@@ -509,7 +497,23 @@ var/list/preferences_datums = list()
p_map = VM.friendlyname
else
p_map += " (No longer exists)"
dat += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a>"
dat += "<b>Preferred Map:</b> <a href='?_src_=prefs;preference=preferred_map;task=input'>[p_map]</a><br>"
dat += "<b>FPS:</b> <a href='?_src_=prefs;preference=clientfps;task=input'>[clientfps]</a><br>"
dat += "<b>Parallax (Fancy Space):</b> <a href='?_src_=prefs;preference=parallaxdown' oncontextmenu='window.location.href=\"?_src_=prefs;preference=parallaxup\";return false;'>"
switch (parallax)
if (PARALLAX_LOW)
dat += "Low"
if (PARALLAX_MED)
dat += "Medium"
if (PARALLAX_INSANE)
dat += "Insane"
if (PARALLAX_DISABLE)
dat += "Disabled"
else
dat += "High"
dat += "</a><br>"
dat += "</td><td width='300px' height='300px' valign='top'>"
@@ -546,7 +550,6 @@ var/list/preferences_datums = list()
dat += "<a href='?_src_=prefs;preference=reset_all'>Reset Setup</a>"
dat += "</center>"
//user << browse(dat, "window=preferences;size=560x560")
var/datum/browser/popup = new(user, "preferences", "<div align='center'>Character Setup</div>", 640, 750)
popup.set_content(dat)
popup.open(0)
@@ -563,108 +566,116 @@ var/list/preferences_datums = list()
var/width = widthPerColumn
var/HTML = "<center>"
HTML += "<b>Choose occupation chances</b><br>"
HTML += "<div align='center'>Left-click to raise an occupation preference, right-click to lower it.<br></div>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>Done</a></center><br>" // Easier to press up here.
HTML += "<script type='text/javascript'>function setJobPrefRedirect(level, rank) { window.location.href='?_src_=prefs;preference=job;task=setJobLevel;level=' + level + ';text=' + encodeURIComponent(rank); return false; }</script>"
HTML += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
HTML += "<table width='100%' cellpadding='1' cellspacing='0'>"
var/index = -1
if(SSjob.occupations.len <= 0)
HTML += "The job ticker is not yet finished creating jobs, please try again later"
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>Done</a></center><br>" // Easier to press up here.
//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
var/datum/job/lastJob
else
HTML += "<b>Choose occupation chances</b><br>"
HTML += "<div align='center'>Left-click to raise an occupation preference, right-click to lower it.<br></div>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=close'>Done</a></center><br>" // Easier to press up here.
HTML += "<script type='text/javascript'>function setJobPrefRedirect(level, rank) { window.location.href='?_src_=prefs;preference=job;task=setJobLevel;level=' + level + ';text=' + encodeURIComponent(rank); return false; }</script>"
HTML += "<table width='100%' cellpadding='1' cellspacing='0'><tr><td width='20%'>" // Table within a table for alignment, also allows you to easily add more colomns.
HTML += "<table width='100%' cellpadding='1' cellspacing='0'>"
var/index = -1
for(var/datum/job/job in SSjob.occupations)
//The job before the current job. I only use this to get the previous jobs color when I'm filling in blank rows.
var/datum/job/lastJob
index += 1
if((index >= limit) || (job.title in splitJobs))
width += widthPerColumn
if((index < limit) && (lastJob != null))
//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
//the last job's selection color. Creating a rather nice effect.
for(var/i = 0, i < (limit - index), i += 1)
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'>&nbsp</td><td>&nbsp</td></tr>"
HTML += "</table></td><td width='20%'><table width='100%' cellpadding='1' cellspacing='0'>"
index = 0
for(var/datum/job/job in SSjob.occupations)
HTML += "<tr bgcolor='[job.selection_color]'><td width='60%' align='right'>"
var/rank = job.title
lastJob = job
if(jobban_isbanned(user, rank))
HTML += "<font color=red>[rank]</font></td><td><a href='?_src_=prefs;jobbancheck=[rank]'> BANNED</a></td></tr>"
continue
if(!job.player_old_enough(user.client))
var/available_in_days = job.available_in_days(user.client)
HTML += "<font color=red>[rank]</font></td><td><font color=red> \[IN [(available_in_days)] DAYS\]</font></td></tr>"
continue
if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant"))
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
continue
if(config.enforce_human_authority && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features))
if(user.client.prefs.pref_species.id == "human")
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[MUTANT\]</b></font></td></tr>"
index += 1
if((index >= limit) || (job.title in splitJobs))
width += widthPerColumn
if((index < limit) && (lastJob != null))
//If the cells were broken up by a job in the splitJob list then it will fill in the rest of the cells with
//the last job's selection color. Creating a rather nice effect.
for(var/i = 0, i < (limit - index), i += 1)
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'>&nbsp</td><td>&nbsp</td></tr>"
HTML += "</table></td><td width='20%'><table width='100%' cellpadding='1' cellspacing='0'>"
index = 0
HTML += "<tr bgcolor='[job.selection_color]'><td width='60%' align='right'>"
var/rank = job.title
lastJob = job
if(jobban_isbanned(user, rank))
HTML += "<font color=red>[rank]</font></td><td><a href='?_src_=prefs;jobbancheck=[rank]'> BANNED</a></td></tr>"
continue
if(!job.player_old_enough(user.client))
var/available_in_days = job.available_in_days(user.client)
HTML += "<font color=red>[rank]</font></td><td><font color=red> \[IN [(available_in_days)] DAYS\]</font></td></tr>"
continue
if((job_civilian_low & ASSISTANT) && (rank != "Assistant") && !jobban_isbanned(user, "Assistant"))
HTML += "<font color=orange>[rank]</font></td><td></td></tr>"
continue
if(config.enforce_human_authority && !user.client.prefs.pref_species.qualifies_for_rank(rank, user.client.prefs.features))
if(user.client.prefs.pref_species.id == "human")
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[MUTANT\]</b></font></td></tr>"
else
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[NON-HUMAN\]</b></font></td></tr>"
continue
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
HTML += "<b><span class='dark'>[rank]</span></b>"
else
HTML += "<font color=red>[rank]</font></td><td><font color=red><b> \[NON-HUMAN\]</b></font></td></tr>"
continue
if((rank in command_positions) || (rank == "AI"))//Bold head jobs
HTML += "<b><span class='dark'>[rank]</span></b>"
else
HTML += "<span class='dark'>[rank]</span>"
HTML += "<span class='dark'>[rank]</span>"
HTML += "</td><td width='40%'>"
HTML += "</td><td width='40%'>"
var/prefLevelLabel = "ERROR"
var/prefLevelColor = "pink"
var/prefUpperLevel = -1 // level to assign on left click
var/prefLowerLevel = -1 // level to assign on right click
var/prefLevelLabel = "ERROR"
var/prefLevelColor = "pink"
var/prefUpperLevel = -1 // level to assign on left click
var/prefLowerLevel = -1 // level to assign on right click
if(GetJobDepartment(job, 1) & job.flag)
prefLevelLabel = "High"
prefLevelColor = "slateblue"
prefUpperLevel = 4
prefLowerLevel = 2
else if(GetJobDepartment(job, 2) & job.flag)
prefLevelLabel = "Medium"
prefLevelColor = "green"
prefUpperLevel = 1
prefLowerLevel = 3
else if(GetJobDepartment(job, 3) & job.flag)
prefLevelLabel = "Low"
prefLevelColor = "orange"
prefUpperLevel = 2
prefLowerLevel = 4
else
prefLevelLabel = "NEVER"
prefLevelColor = "red"
prefUpperLevel = 3
prefLowerLevel = 1
HTML += "<a class='white' href='?_src_=prefs;preference=job;task=setJobLevel;level=[prefUpperLevel];text=[rank]' oncontextmenu='javascript:return setJobPrefRedirect([prefLowerLevel], \"[rank]\");'>"
if(rank == "Assistant")//Assistant is special
if(job_civilian_low & ASSISTANT)
HTML += "<font color=green>Yes</font>"
if(GetJobDepartment(job, 1) & job.flag)
prefLevelLabel = "High"
prefLevelColor = "slateblue"
prefUpperLevel = 4
prefLowerLevel = 2
else if(GetJobDepartment(job, 2) & job.flag)
prefLevelLabel = "Medium"
prefLevelColor = "green"
prefUpperLevel = 1
prefLowerLevel = 3
else if(GetJobDepartment(job, 3) & job.flag)
prefLevelLabel = "Low"
prefLevelColor = "orange"
prefUpperLevel = 2
prefLowerLevel = 4
else
HTML += "<font color=red>No</font>"
prefLevelLabel = "NEVER"
prefLevelColor = "red"
prefUpperLevel = 3
prefLowerLevel = 1
HTML += "<a class='white' href='?_src_=prefs;preference=job;task=setJobLevel;level=[prefUpperLevel];text=[rank]' oncontextmenu='javascript:return setJobPrefRedirect([prefLowerLevel], \"[rank]\");'>"
if(rank == "Assistant")//Assistant is special
if(job_civilian_low & ASSISTANT)
HTML += "<font color=green>Yes</font>"
else
HTML += "<font color=red>No</font>"
HTML += "</a></td></tr>"
continue
HTML += "<font color=[prefLevelColor]>[prefLevelLabel]</font>"
HTML += "</a></td></tr>"
continue
HTML += "<font color=[prefLevelColor]>[prefLevelLabel]</font>"
HTML += "</a></td></tr>"
for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'>&nbsp</td><td>&nbsp</td></tr>"
for(var/i = 1, i < (limit - index), i += 1) // Finish the column so it is even
HTML += "<tr bgcolor='[lastJob.selection_color]'><td width='60%' align='right'>&nbsp</td><td>&nbsp</td></tr>"
HTML += "</td'></tr></table>"
HTML += "</center></table>"
HTML += "</td'></tr></table>"
HTML += "</center></table>"
HTML += "<center><br><a href='?_src_=prefs;preference=job;task=random'>[userandomjob ? "Get random job if preferences unavailable" : "Be an Assistant if preference unavailable"]</a></center>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=reset'>Reset Preferences</a></center>"
var/message = "Be an Assistant if preferences unavailable"
if(joblessrole == BERANDOMJOB)
message = "Get random job if preferences unavailable"
else if(joblessrole == RETURNTOLOBBY)
message = "Return to lobby if preferences unavailable"
HTML += "<center><br><a href='?_src_=prefs;preference=job;task=random'>[message]</a></center>"
HTML += "<center><a href='?_src_=prefs;preference=job;task=reset'>Reset Preferences</a></center>"
user << browse(null, "window=preferences")
//user << browse(HTML, "window=mob_occupation;size=[width]x[height]")
var/datum/browser/popup = new(user, "mob_occupation", "<div align='center'>Occupation Preferences</div>", width, height)
popup.set_window_options("can_close=0")
popup.set_content(HTML)
@@ -730,7 +741,7 @@ var/list/preferences_datums = list()
return 0
/datum/preferences/proc/UpdateJobPreference(mob/user, role, desiredLvl)
if(!SSjob)
if(!SSjob || SSjob.occupations.len <= 0)
return
var/datum/job/job = SSjob.GetJob(role)
@@ -835,10 +846,16 @@ var/list/preferences_datums = list()
ResetJobs()
SetChoices(user)
if("random")
if(jobban_isbanned(user, "Assistant"))
userandomjob = 1
else
userandomjob = !userandomjob
switch(joblessrole)
if(RETURNTOLOBBY)
if(jobban_isbanned(user, "Assistant"))
joblessrole = BERANDOMJOB
else
joblessrole = BEASSISTANT
if(BEASSISTANT)
joblessrole = BERANDOMJOB
if(BERANDOMJOB)
joblessrole = RETURNTOLOBBY
SetChoices(user)
if("setJobLevel")
UpdateJobPreference(user, href_list["text"], text2num(href_list["level"]))
@@ -921,19 +938,18 @@ var/list/preferences_datums = list()
if(new_age)
age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN)
/*if("metadata")
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
if(new_metadata)
metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))*/
if("flavor_text")
var/msg = input(usr,"Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!","Flavor Text",html_decode(flavor_text)) as message
if(msg != null)
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = html_encode(msg)
flavor_text = msg
if("metadata")
var/new_metadata = input(user, "Enter any information you'd like others to see, such as Roleplay-preferences:", "Game Preference" , metadata) as message|null
if(new_metadata)
metadata = sanitize(copytext(new_metadata,1,MAX_MESSAGE_LEN))
if("hair")
var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as null|color
if(new_hair)
@@ -1018,18 +1034,18 @@ var/list/preferences_datums = list()
if("species")
var/result = input(user, "Select a species", "Species Selection") as null|anything in get_racelist(user)
var/result = input(user, "Select a species", "Species Selection") as null|anything in roundstart_species
if(result)
var/newtype = roundstart_species[result]
pref_species = new newtype()
//Now that we changed our species, we must verify that the mutant colour is still allowed.
var/temp_hsv = RGBtoHSV(features["mcolor"])
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.specflags) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
if(features["mcolor"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
features["mcolor"] = pref_species.default_color
if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.specflags) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
if(features["mcolor2"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
features["mcolor2"] = pref_species.default_color
if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.specflags) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
if(features["mcolor3"] == "#000" || (!(MUTCOLORS_PARTSONLY in pref_species.species_traits) && ReadHSV(temp_hsv)[3] < ReadHSV("#202020")[3]))
features["mcolor3"] = pref_species.default_color
if("mutant_color")
@@ -1038,7 +1054,7 @@ var/list/preferences_datums = list()
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.specflags) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor"] = sanitize_hexcolor(new_mutantcolor)
else
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
@@ -1049,7 +1065,7 @@ var/list/preferences_datums = list()
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor2"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.specflags) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor2"] = sanitize_hexcolor(new_mutantcolor)
else
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
@@ -1060,7 +1076,7 @@ var/list/preferences_datums = list()
var/temp_hsv = RGBtoHSV(new_mutantcolor)
if(new_mutantcolor == "#000000")
features["mcolor3"] = pref_species.default_color
else if((MUTCOLORS_PARTSONLY in pref_species.specflags) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
else if((MUTCOLORS_PARTSONLY in pref_species.species_traits) || ReadHSV(temp_hsv)[3] >= ReadHSV("#202020")[3]) // mutantcolors must be bright, but only if they affect the skin
features["mcolor3"] = sanitize_hexcolor(new_mutantcolor)
else
user << "<span class='danger'>Invalid color. Your color is not bright enough.</span>"
@@ -1082,6 +1098,7 @@ var/list/preferences_datums = list()
new_tail = input(user, "Choose your character's tail:", "Character Preference") as null|anything in mam_tails_list
if(new_tail)
features["mam_tail"] = new_tail
/* Doesn't exist yet. will include facial overlays to mimic 5th port species heads.
if("mam_snout")
var/new_snout
@@ -1089,6 +1106,7 @@ var/list/preferences_datums = list()
if(new_snout)
features["snout"] = new_snout
*/
if("snout")
var/new_snout
new_snout = input(user, "Choose your character's snout:", "Character Preference") as null|anything in snouts_list
@@ -1162,13 +1180,19 @@ var/list/preferences_datums = list()
if(new_dors)
features["xenodorsal"] = new_dors
if("legs")
var/new_legs
new_legs = input(user, "Choose your character's legs:", "Character Preference") as null|anything in legs_list
if(new_legs)
features["legs"] = new_legs
if("s_tone")
var/new_s_tone = input(user, "Choose your character's skin-tone:", "Character Preference") as null|anything in skin_tones
if(new_s_tone)
skin_tone = new_s_tone
if("ooccolor")
var/new_ooccolor = input(user, "Choose your OOC color:", "Game Preference") as color|null
var/new_ooccolor = input(user, "Choose your OOC colour:", "Game Preference") as color|null
if(new_ooccolor)
ooccolor = sanitize_ooccolor(new_ooccolor)
@@ -1218,6 +1242,17 @@ var/list/preferences_datums = list()
custom_names["deity"] = new_deity_name
else
user << "<font color='red'>Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .</font>"
if("sec_dept")
var/department = input(user, "Choose your prefered security department:", "Security Departments") as null|anything in security_depts_prefs
if(department)
prefered_security_department = department
if("uplink_loc")
var/new_loc = input(user, "Choose your character's traitor uplink spawn location:", "Character Preference") as null|anything in uplink_spawn_loc_list
if(new_loc)
uplink_spawn_loc = new_loc
if ("preferred_map")
var/maplist = list()
var/default = "Default"
@@ -1233,6 +1268,21 @@ var/list/preferences_datums = list()
var/pickedmap = input(user, "Choose your preferred map. This will be used to help weight random map selection.", "Character Preference") as null|anything in maplist
if (pickedmap)
preferred_map = maplist[pickedmap]
if ("clientfps")
var/version_message
if (user.client && user.client.byond_version < 511)
version_message = "\nYou need to be using byond version 511 or later to take advantage of this feature, your version of [user.client.byond_version] is too low"
if (world.byond_version < 511)
version_message += "\nThis server does not currently support client side fps. You can set now for when it does."
var/desiredfps = input(user, "Choose your desired fps.[version_message]\n(0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
if (!isnull(desiredfps))
clientfps = desiredfps
if (world.byond_version >= 511 && user.client && user.client.byond_version >= 511)
user.client.vars["fps"] = clientfps
if("ui")
var/pickedui = input(user, "Choose your UI style.", "Character Preference") as null|anything in list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork")
if(pickedui)
UI_style = pickedui
else
@@ -1251,19 +1301,6 @@ var/list/preferences_datums = list()
facial_hair_style = random_facial_hair_style(gender)
hair_style = random_hair_style(gender)
if("ui")
switch(UI_style)
if("Midnight")
UI_style = "Plasmafire"
if("Plasmafire")
UI_style = "Retro"
if("Retro")
UI_style = "Slimecore"
if("Slimecore")
UI_style = "Operative"
else
UI_style = "Midnight"
if("hotkeys")
hotkeys = !hotkeys
@@ -1284,15 +1321,6 @@ var/list/preferences_datums = list()
else
be_special += be_special_type
if("parallax")
space_parallax = !space_parallax
if("dust")
space_dust = !space_dust
if("p_speed")
parallax_speed = min(max(input(user, "Enter a number between 0 and 5 included (default=2)","Parallax Speed Preferences",parallax_speed),0),5)
if("name")
be_random_name = !be_random_name
@@ -1330,10 +1358,19 @@ var/list/preferences_datums = list()
if("allow_midround_antag")
toggles ^= MIDROUND_ANTAG
if("parallaxup")
parallax = Wrap(parallax + 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
if (parent && parent.mob && parent.mob.hud_used)
parent.mob.hud_used.update_parallax_pref()
if("parallaxdown")
parallax = Wrap(parallax - 1, PARALLAX_INSANE, PARALLAX_DISABLE + 1)
if (parent && parent.mob && parent.mob.hud_used)
parent.mob.hud_used.update_parallax_pref()
if("save")
save_preferences()
save_character()
save_vore_preferences()
if("load")
load_preferences()
@@ -1371,25 +1408,8 @@ var/list/preferences_datums = list()
character.real_name = real_name
character.name = character.real_name
character.flavor_text = flavor_text
if(!length(belly_prefs))
var/datum/belly/B = new /datum/belly(src)
B.immutable = 1
B.name = "Stomach"
B.inside_flavor = "It appears to be rather warm and wet. Makes sense, considering it's inside \the [character]."
belly_prefs[B.name] = B
character.vore_organs = belly_prefs
character.vore_selected = character.vore_organs[1]
for(var/I in character.vore_organs)
var/datum/belly/B = character.vore_organs[I]
B.owner = character
character.digestable = digestable
character.gender = gender
character.age = age
@@ -1403,6 +1423,7 @@ var/list/preferences_datums = list()
character.underwear = underwear
character.undershirt = undershirt
character.socks = socks
character.backbag = backbag
character.dna.features = features.Copy()
@@ -1418,3 +1439,8 @@ var/list/preferences_datums = list()
character.update_body()
character.update_hair()
character.update_body_parts()
//vore
character.digestable = digestable
character.devourable = devourable
character.vore_organs = belly_prefs
+135 -156
View File
@@ -1,18 +1,21 @@
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
#define SAVEFILE_VERSION_MIN 8
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
#define SAVEFILE_VERSION_MIN 10
//This is the current version, anything below this will attempt to update (if it's not obsolete)
#define SAVEFILE_VERSION_MAX 15
#define SAVEFILE_VERSION_MAX 17
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
This proc checks if the current directory of the savefile S needs updating
It is to be used by the load_character and load_preferences procs.
(S.cd=="/" is preferences, S.cd=="/character[integer]" is a character slot, etc)
if the current directory's version is below SAVEFILE_VERSION_MIN it will simply wipe everything in that directory
(if we're at root "/" then it'll just wipe the entire savefile, for instance.)
if its version is below SAVEFILE_VERSION_MAX but above the minimum, it will load data but later call the
respective update_preferences() or update_character() proc.
Those procs allow coders to specify format changes so users do not lose their setups and have to redo them again.
Failing all that, the standard sanity checks are performed. They simply check the data is suitable, reverting to
initial() values if necessary.
*/
@@ -28,7 +31,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
return -1
/datum/preferences/proc/update_antagchoices(current_version)
/datum/preferences/proc/update_antagchoices(current_version, savefile/S)
if((!islist(be_special) || old_be_special ) && current_version < 12)
//Archived values of when antag pref defines were a bitfield+fitflags
var/B_traitor = 1
@@ -84,7 +87,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
be_special += ROLE_ABDUCTOR
/datum/preferences/proc/update_preferences(current_version)
/datum/preferences/proc/update_preferences(current_version, savefile/S)
if(current_version < 10)
toggles |= MEMBER_PUBLIC
if(current_version < 11)
@@ -95,71 +98,14 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(current_version < 15)
toggles |= SOUND_ANNOUNCEMENTS
//should this proc get fairly long (say 3 versions long),
//just increase SAVEFILE_VERSION_MIN so it's not as far behind
//SAVEFILE_VERSION_MAX and then delete any obsolete if clauses
//from this proc.
//It's only really meant to avoid annoying frequent players
//if your savefile is 3 months out of date, then 'tough shit'.
/datum/preferences/proc/update_character(current_version)
if(current_version < 9) //an example, underwear were an index for a hardcoded list, converting to a string
if(gender == MALE)
switch(underwear)
if(1)
underwear = "Mens White"
if(2)
underwear = "Mens Grey"
if(3)
underwear = "Mens Green"
if(4)
underwear = "Mens Blue"
if(5)
underwear = "Mens Black"
if(6)
underwear = "Mankini"
if(7)
underwear = "Mens Hearts Boxer"
if(8)
underwear = "Mens Black Boxer"
if(9)
underwear = "Mens Grey Boxer"
if(10)
underwear = "Mens Striped Boxer"
if(11)
underwear = "Mens Kinky"
if(12)
underwear = "Mens Red"
if(13)
underwear = "Nude"
else
switch(underwear)
if(1)
underwear = "Ladies Red"
if(2)
underwear = "Ladies White"
if(3)
underwear = "Ladies Yellow"
if(4)
underwear = "Ladies Blue"
if(5)
underwear = "Ladies Black"
if(6)
underwear = "Ladies Thong"
if(7)
underwear = "Babydoll"
if(8)
underwear = "Ladies Baby-Blue"
if(9)
underwear = "Ladies Green"
if(10)
underwear = "Ladies Pink"
if(11)
underwear = "Ladies Kinky"
if(12)
underwear = "Tankini"
if(13)
underwear = "Nude"
/datum/preferences/proc/update_character(current_version, savefile/S)
if(pref_species && !(pref_species.id in roundstart_species))
var/rando_race = pick(config.roundstart_races)
pref_species = new rando_race()
@@ -170,45 +116,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
backbag = DSATCHEL
else
backbag = DBACKPACK
//
// Save/Load Vore Preferences
//
/datum/preferences/proc/load_vore_preferences(slot)
if(!path) return 0 //Path couldn't be set?
if(!fexists(path)) //Never saved before
save_vore_preferences() //Make the file first
return 1
var/savefile/S = new /savefile(path)
if(!S) return 0 //Savefile object couldn't be created?
S.cd = "/character[slot]"
S["digestable"] >> digestable
S["belly_prefs"] >> belly_prefs
if(isnull(digestable))
digestable = 1
if(isnull(belly_prefs))
belly_prefs = list()
return 1
/datum/preferences/proc/save_vore_preferences()
if(!path)
return 0
var/savefile/S = new /savefile(path)
if(!S)
return 0
S.cd = "/character[default_slot]"
S["digestable"] << digestable
S["belly_prefs"] << belly_prefs
return 1
if(current_version < 16)
var/berandom
S["userandomjob"] >> berandom
if (berandom)
joblessrole = BERANDOMJOB
else
joblessrole = BEASSISTANT
if(current_version < 17)
features["legs"] = "Normal Legs"
/datum/preferences/proc/load_path(ckey,filename="preferences.sav")
if(!ckey)
@@ -237,9 +153,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["hotkeys"] >> hotkeys
S["tgui_fancy"] >> tgui_fancy
S["tgui_lock"] >> tgui_lock
S["space_parallax"] >> space_parallax
S["space_dust"] >> space_dust
S["parallax_speed"] >> parallax_speed
if(islist(S["be_special"]))
S["be_special"] >> be_special
@@ -258,24 +171,40 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["ignoring"] >> ignoring
S["ghost_hud"] >> ghost_hud
S["inquisitive_ghost"] >> inquisitive_ghost
S["uses_glasses_colour"]>> uses_glasses_colour
S["clientfps"] >> clientfps
S["parallax"] >> parallax
S["uplink_loc"] >> uplink_spawn_loc
//vore
S["digestable"] >> digestable
S["devourable"] >> devourable
S["belly_prefs"] >> belly_prefs
if(isnull(digestable))
digestable = 1
if(isnull(devourable))
devourable = 1
if(isnull(belly_prefs))
belly_prefs = list()
//try to fix any outdated data if necessary
if(needs_update >= 0)
update_preferences(needs_update) //needs_update = savefile_version if we need an update (positive integer)
update_antagchoices(needs_update)
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
update_antagchoices(needs_update, S)
//Sanitize
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
lastchangelog = sanitize_text(lastchangelog, initial(lastchangelog))
UI_style = sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative"), initial(UI_style))
UI_style = sanitize_inlist(UI_style, list("Midnight", "Plasmafire", "Retro", "Slimecore", "Operative", "Clockwork"), initial(UI_style))
hotkeys = sanitize_integer(hotkeys, 0, 1, initial(hotkeys))
tgui_fancy = sanitize_integer(tgui_fancy, 0, 1, initial(tgui_fancy))
tgui_lock = sanitize_integer(tgui_lock, 0, 1, initial(tgui_lock))
default_slot = sanitize_integer(default_slot, 1, max_save_slots, initial(default_slot))
toggles = sanitize_integer(toggles, 0, 65535, initial(toggles))
space_parallax = sanitize_integer(space_parallax, 0, 1, initial(space_parallax))
space_dust = sanitize_integer(space_dust, 0, 1, initial(space_dust))
parallax_speed = sanitize_integer(parallax_speed, 0, 5, initial(parallax_speed))
clientfps = sanitize_integer(clientfps, 0, 1000, 0)
parallax = sanitize_integer(parallax, PARALLAX_INSANE, PARALLAX_DISABLE, PARALLAX_HIGH)
ghost_form = sanitize_inlist(ghost_form, ghost_forms, initial(ghost_form))
ghost_orbit = sanitize_inlist(ghost_orbit, ghost_orbits, initial(ghost_orbit))
ghost_accs = sanitize_inlist(ghost_accs, ghost_accs_options, GHOST_ACCS_DEFAULT_OPTION)
@@ -312,9 +241,15 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["ignoring"] << ignoring
S["ghost_hud"] << ghost_hud
S["inquisitive_ghost"] << inquisitive_ghost
S["space_parallax"] << space_parallax
S["space_dust"] << space_dust
S["parallax_speed"] << parallax_speed
S["uses_glasses_colour"]<< uses_glasses_colour
S["clientfps"] << clientfps
S["parallax"] << parallax
//vore
S["digestable"] << digestable
S["devourable"] << devourable
S["belly_prefs"] << belly_prefs
return 1
@@ -351,28 +286,25 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if(!S["features["mcolor"]"] || S["features["mcolor"]"] == "#000")
S["features["mcolor"]"] << "#FFF"
if(!S["features["mcolor2"]"] || S["features["mcolor2"]"] == "#000")
S["features["mcolor2"]"] << "#FFF"
if(!S["features["mcolor3"]"] || S["features["mcolor3"]"] == "#000")
S["features["mcolor3"]"] << "#FFF"
//Character
S["real_name"] >> real_name
S["name_is_always_random"] >> be_random_name
S["body_is_always_random"] >> be_random_body
S["gender"] >> gender
S["age"] >> age
S["hair_color"] >> hair_color
S["facial_hair_color"] >> facial_hair_color
S["eye_color"] >> eye_color
S["skin_tone"] >> skin_tone
S["hair_style_name"] >> hair_style
S["facial_style_name"] >> facial_hair_style
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["socks"] >> socks
S["backbag"] >> backbag
S["flavor_text"] >> flavor_text
S["OOC_Notes"] >> metadata
S["flavor_text"] >> flavor_text
S["real_name"] >> real_name
S["name_is_always_random"] >> be_random_name
S["body_is_always_random"] >> be_random_body
S["gender"] >> gender
S["age"] >> age
S["hair_color"] >> hair_color
S["facial_hair_color"] >> facial_hair_color
S["eye_color"] >> eye_color
S["skin_tone"] >> skin_tone
S["hair_style_name"] >> hair_style
S["facial_style_name"] >> facial_hair_style
S["underwear"] >> underwear
S["undershirt"] >> undershirt
S["socks"] >> socks
S["backbag"] >> backbag
S["feature_mcolor"] >> features["mcolor"]
S["feature_mcolor2"] >> features["mcolor2"]
S["feature_mcolor3"] >> features["mcolor3"]
@@ -390,6 +322,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_xeno_tail"] >> features["xenotail"]
S["feature_xeno_dors"] >> features["xenodorsal"]
S["feature_xeno_head"] >> features["xenohead"]
S["feature_lizard_legs"] >> features["legs"]
if(!config.mutant_humans)
features["tail_human"] = "none"
features["ears"] = "none"
@@ -402,9 +335,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["cyborg_name"] >> custom_names["cyborg"]
S["religion_name"] >> custom_names["religion"]
S["deity_name"] >> custom_names["deity"]
S["prefered_security_department"] >> prefered_security_department
//Jobs
S["userandomjob"] >> userandomjob
S["joblessrole"] >> joblessrole
S["job_civilian_high"] >> job_civilian_high
S["job_civilian_med"] >> job_civilian_med
S["job_civilian_low"] >> job_civilian_low
@@ -417,10 +352,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//try to fix any outdated data if necessary
if(needs_update >= 0)
update_character(needs_update) //needs_update == savefile_version if we need an update (positive integer)
update_character(needs_update, S) //needs_update == savefile_version if we need an update (positive integer)
//Sanitize
flavor_text = sanitize_text(flavor_text, initial(flavor_text))
metadata = sanitize_text(metadata, initial(metadata))
real_name = reject_bad_name(real_name)
if(!features["mcolor"] || features["mcolor"] == "#000")
features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
@@ -468,8 +404,11 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
features["xenotail"] = sanitize_inlist(features["xenotail"], xeno_tail_list)
features["xenohead"] = sanitize_inlist(features["xenohead"], xeno_head_list)
features["xenodorsal"] = sanitize_inlist(features["xenodorsal"], xeno_dorsal_list)
features["feature_lizard_legs"] = sanitize_inlist(features["legs"], legs_list, "Normal Legs")
userandomjob = sanitize_integer(userandomjob, 0, 1, initial(userandomjob))
uplink_spawn_loc = sanitize_inlist(uplink_spawn_loc, uplink_spawn_loc_list, initial(uplink_spawn_loc))
joblessrole = sanitize_integer(joblessrole, 1, 3, initial(joblessrole))
job_civilian_high = sanitize_integer(job_civilian_high, 0, 65535, initial(job_civilian_high))
job_civilian_med = sanitize_integer(job_civilian_med, 0, 65535, initial(job_civilian_med))
job_civilian_low = sanitize_integer(job_civilian_low, 0, 65535, initial(job_civilian_low))
@@ -493,23 +432,24 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["version"] << SAVEFILE_VERSION_MAX //load_character will sanitize any bad data, so assume up-to-date.
//Character
S["real_name"] << real_name
S["name_is_always_random"] << be_random_name
S["body_is_always_random"] << be_random_body
S["gender"] << gender
S["age"] << age
S["hair_color"] << hair_color
S["facial_hair_color"] << facial_hair_color
S["eye_color"] << eye_color
S["skin_tone"] << skin_tone
S["hair_style_name"] << hair_style
S["facial_style_name"] << facial_hair_style
S["underwear"] << underwear
S["undershirt"] << undershirt
S["socks"] << socks
S["backbag"] << backbag
S["OOC_Notes"] << metadata
S["real_name"] << real_name
S["name_is_always_random"] << be_random_name
S["body_is_always_random"] << be_random_body
S["gender"] << gender
S["age"] << age
S["hair_color"] << hair_color
S["facial_hair_color"] << facial_hair_color
S["eye_color"] << eye_color
S["skin_tone"] << skin_tone
S["hair_style_name"] << hair_style
S["facial_style_name"] << facial_hair_style
S["underwear"] << underwear
S["undershirt"] << undershirt
S["socks"] << socks
S["backbag"] << backbag
S["flavor_text"] << flavor_text
S["species"] << pref_species.id
S["species"] << pref_species.id
S["feature_mcolor"] << features["mcolor"]
S["feature_mcolor2"] << features["mcolor2"]
S["feature_mcolor3"] << features["mcolor3"]
@@ -529,16 +469,19 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
S["feature_xeno_tail"] << features["xenotail"]
S["feature_xeno_dors"] << features["xenodorsal"]
S["feature_xeno_head"] << features["xenohead"]
S["feature_lizard_legs"] << features["legs"]
S["clown_name"] << custom_names["clown"]
S["mime_name"] << custom_names["mime"]
S["ai_name"] << custom_names["ai"]
S["cyborg_name"] << custom_names["cyborg"]
S["religion_name"] << custom_names["religion"]
S["deity_name"] << custom_names["deity"]
S["prefered_security_department"] << prefered_security_department
S["uplink_loc"] << uplink_spawn_loc
//Jobs
S["userandomjob"] << userandomjob
S["joblessrole"] << joblessrole
S["job_civilian_high"] << job_civilian_high
S["job_civilian_med"] << job_civilian_med
S["job_civilian_low"] << job_civilian_low
@@ -551,6 +494,42 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
return 1
/datum/preferences/proc/load_vore_preferences(slot)
if(!path) return 0
if(!fexists(path)) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/"
if(!slot) slot = default_slot
slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot))
if(slot != default_slot)
default_slot = slot
S["default_slot"] << slot
S.cd = "/character[slot]"
S["belly_prefs"] >> belly_prefs
S["devourable"] >> devourable
S["digestable"] >> digestable
digestable = sanitize_integer(digestable, 0, 1, initial(digestable))
devourable = sanitize_integer(devourable, 0, 1, initial(devourable))
if(!belly_prefs)
belly_prefs = list()
return 1
/datum/preferences/proc/save_vore_preferences()
if(!path) return 0
var/savefile/S = new /savefile(path)
if(!S) return 0
S.cd = "/character[default_slot]"
S["belly_prefs"] << belly_prefs
S["devourable"] << devourable
S["digestable"] << digestable
return 1
#undef SAVEFILE_VERSION_MAX
#undef SAVEFILE_VERSION_MIN
+7 -7
View File
@@ -147,11 +147,11 @@
prefs.save_preferences()
if(prefs.toggles & SOUND_LOBBY)
src << "You will now hear music in the game lobby."
if(istype(mob, /mob/new_player))
if(isnewplayer(mob))
playtitlemusic()
else
src << "You will no longer hear music in the game lobby."
if(istype(mob, /mob/new_player))
if(isnewplayer(mob))
mob.stopLobbySound()
feedback_add_details("admin_verb","TLobby") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -244,7 +244,7 @@ var/global/list/ghost_forms = list("ghost","ghostking","ghostian2","skeleghost",
if(new_form)
prefs.ghost_form = new_form
prefs.save_preferences()
if(istype(mob,/mob/dead/observer))
if(isobserver(mob))
var/mob/dead/observer/O = mob
O.update_icon(new_form)
@@ -258,7 +258,7 @@ var/global/list/ghost_orbits = list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
if(new_orbit)
prefs.ghost_orbit = new_orbit
prefs.save_preferences()
if(istype(mob, /mob/dead/observer))
if(isobserver(mob))
var/mob/dead/observer/O = mob
O.ghost_orbit = new_orbit
@@ -273,7 +273,7 @@ var/global/list/ghost_orbits = list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
if("default sprites")
prefs.ghost_accs = GHOST_ACCS_NONE
prefs.save_preferences()
if(istype(mob, /mob/dead/observer))
if(isobserver(mob))
var/mob/dead/observer/O = mob
O.update_icon()
@@ -306,7 +306,7 @@ var/global/list/ghost_orbits = list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
if("White Ghost")
prefs.ghost_others = GHOST_OTHERS_SIMPLE
prefs.save_preferences()
if(istype(mob, /mob/dead/observer))
if(isobserver(mob))
var/mob/dead/observer/O = mob
O.updateghostsight()
@@ -334,7 +334,7 @@ var/global/list/ghost_orbits = list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
prefs.ghost_hud = !prefs.ghost_hud
src << "Ghost HUD will now be [prefs.ghost_hud ? "visible" : "hidden"]."
prefs.save_preferences()
if(istype(mob,/mob/dead/observer))
if(isobserver(mob))
mob.hud_used.show_hud()
/client/verb/toggle_inquisition() // warning: unexpected inquisition
+79
View File
@@ -0,0 +1,79 @@
/client/verb/looc(msg as text)
set name = "LOOC"
set desc = "Local OOC, seen only by those in view."
set category = "OOC"
if(say_disabled) //This is here to try to identify lag problems
usr << "\red Speech is currently admin-disabled."
return
if(!mob) return
if(IsGuestKey(key))
src << "Guests may not use OOC."
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
if(!msg) return
if(!(prefs.toggles & CHAT_OOC))
src << "\red You have OOC muted."
return
if(!holder)
if(!ooc_allowed)
src << "\red OOC is globally muted"
return
if(!dooc_allowed && (mob.stat == DEAD))
usr << "\red OOC for dead mobs has been turned off."
return
if(prefs.muted & MUTE_OOC)
src << "\red You cannot use OOC (muted)."
return
if(handle_spam_prevention(msg,MUTE_OOC))
return
if(findtext(msg, "byond://"))
src << "<B>Advertising other servers is not allowed.</B>"
log_admin("[key_name(src)] has attempted to advertise in LOOC: [msg]")
return
log_ooc("(LOCAL) [mob.name]/[key] : [msg]")
var/list/heard = get_hearers_in_view(7, get_top_level_mob(src.mob))
for(var/mob/M in heard)
if(!M.client)
continue
var/client/C = M.client
if (C in admins)
continue //they are handled after that
if (istype(M,/mob/dead/observer))
continue //Also handled later.
if(C.prefs.toggles & CHAT_OOC)
// var/display_name = src.key
// if(holder)
// if(holder.fakekey)
// if(C.holder)
// display_name = "[holder.fakekey]/([src.key])"
// else
// display_name = holder.fakekey
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>LOOC:</span> <EM>[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
for(var/client/C in admins)
if(C.prefs.toggles & CHAT_OOC)
var/prefix = "(R)LOOC"
if (C.mob in heard)
prefix = "LOOC"
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>[prefix]:</span> <EM>[src.key]/[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
for(var/mob/dead/observer/G in world)
if(!G.client)
continue
var/client/C = G.client
if (C in admins)
continue //handled earlier.
if(C.prefs.toggles & CHAT_OOC)
var/prefix = "(G)LOOC"
if (C.mob in heard)
prefix = "LOOC"
C << "<font color='#6699CC'><span class='ooc'><span class='prefix'>[prefix]:</span> <EM>[src.key]/[src.mob.name]:</EM> <span class='message'>[msg]</span></span></font>"
+181
View File
@@ -0,0 +1,181 @@
/client/verb/ooc(msg as text)
set name = "OOC" //Gave this shit a shorter name so you only have to time out "ooc" rather than "ooc message" to use it --NeoFite
set category = "OOC"
if(say_disabled) //This is here to try to identify lag problems
usr << "<span class='danger'>Speech is currently admin-disabled.</span>"
return
if(!mob)
return
if(IsGuestKey(key))
src << "Guests may not use OOC."
return
msg = copytext(sanitize(msg), 1, MAX_MESSAGE_LEN)
var/raw_msg = msg
if(!msg)
return
msg = emoji_parse(msg)
if((copytext(msg, 1, 2) in list(".",";",":","#")) || (findtext(lowertext(copytext(msg, 1, 5)), "say")))
if(alert("Your message \"[raw_msg]\" looks like it was meant for in game communication, say it in OOC?", "Meant for OOC?", "No", "Yes") != "Yes")
return
if(!(prefs.chat_toggles & CHAT_OOC))
src << "<span class='danger'>You have OOC muted.</span>"
return
if(!holder)
if(!ooc_allowed)
src << "<span class='danger'>OOC is globally muted.</span>"
return
if(!dooc_allowed && (mob.stat == DEAD))
usr << "<span class='danger'>OOC for dead mobs has been turned off.</span>"
return
if(prefs.muted & MUTE_OOC)
src << "<span class='danger'>You cannot use OOC (muted).</span>"
return
if(src.mob)
if(jobban_isbanned(src.mob, "OOC"))
src << "<span class='danger'>You have been banned from OOC.</span>"
return
if(handle_spam_prevention(msg,MUTE_OOC))
return
if(findtext(msg, "byond://"))
src << "<B>Advertising other servers is not allowed.</B>"
log_admin("[key_name(src)] has attempted to advertise in OOC: [msg]")
message_admins("[key_name_admin(src)] has attempted to advertise in OOC: [msg]")
return
log_ooc("[mob.name]/[key] : [raw_msg]")
var/keyname = key
if(prefs.unlock_content)
if(prefs.toggles & MEMBER_PUBLIC)
keyname = "<font color='[prefs.ooccolor ? prefs.ooccolor : normal_ooc_colour]'><img style='width:9px;height:9px;' class=icon src=\ref['icons/member_content.dmi'] iconstate=blag>[keyname]</font>"
for(var/client/C in clients)
if(C.prefs.chat_toggles & CHAT_OOC)
if(holder)
if(!holder.fakekey || C.holder)
if(check_rights_for(src, R_ADMIN))
C << "<span class='adminooc'>[config.allow_admin_ooccolor && prefs.ooccolor ? "<font color=[prefs.ooccolor]>" :"" ]<span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span></font>"
else
C << "<span class='adminobserverooc'><span class='prefix'>OOC:</span> <EM>[keyname][holder.fakekey ? "/([holder.fakekey])" : ""]:</EM> <span class='message'>[msg]</span></span>"
else
C << "<font color='[normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[holder.fakekey ? holder.fakekey : key]:</EM> <span class='message'>[msg]</span></span></font>"
else if(check_mentor()) //mentors
C << "<font color='#FF3E96'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[keyname]:</EM> <span class='message'>[msg]</span></span></font>"
else if(!(key in C.prefs.ignoring))
C << "<font color='[normal_ooc_colour]'><span class='ooc'><span class='prefix'>OOC:</span> <EM>[keyname]:</EM> <span class='message'>[msg]</span></span></font>"
/proc/toggle_ooc(toggle = null)
if(toggle != null) //if we're specifically en/disabling ooc
if(toggle != ooc_allowed)
ooc_allowed = toggle
else
return
else //otherwise just toggle it
ooc_allowed = !ooc_allowed
world << "<B>The OOC channel has been globally [ooc_allowed ? "enabled" : "disabled"].</B>"
var/global/normal_ooc_colour = OOC_COLOR
/client/proc/set_ooc(newColor as color)
set name = "Set Player OOC Color"
set desc = "Modifies player OOC Color"
set category = "Fun"
normal_ooc_colour = sanitize_ooccolor(newColor)
/client/proc/reset_ooc()
set name = "Reset Player OOC Color"
set desc = "Returns player OOC Color to default"
set category = "Fun"
normal_ooc_colour = OOC_COLOR
/client/verb/colorooc()
set name = "Set Your OOC Color"
set category = "Preferences"
if(!holder || check_rights_for(src, R_ADMIN))
if(!is_content_unlocked())
return
var/new_ooccolor = input(src, "Please select your OOC color.", "OOC color", prefs.ooccolor) as color|null
if(new_ooccolor)
prefs.ooccolor = sanitize_ooccolor(new_ooccolor)
prefs.save_preferences()
feedback_add_details("admin_verb","OC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/client/verb/resetcolorooc()
set name = "Reset Your OOC Color"
set desc = "Returns your OOC Color to default"
set category = "Preferences"
if(!holder || check_rights_for(src, R_ADMIN))
if(!is_content_unlocked())
return
prefs.ooccolor = initial(prefs.ooccolor)
prefs.save_preferences()
//Checks admin notice
/client/verb/admin_notice()
set name = "Adminnotice"
set category = "Admin"
set desc ="Check the admin notice if it has been set"
if(admin_notice)
src << "<span class='boldnotice'>Admin Notice:</span>\n \t [admin_notice]"
else
src << "<span class='notice'>There are no admin notices at the moment.</span>"
/client/verb/motd()
set name = "MOTD"
set category = "OOC"
set desc ="Check the Message of the Day"
if(join_motd)
src << "<div class=\"motd\">[join_motd]</div>"
else
src << "<span class='notice'>The Message of the Day has not been set.</span>"
/client/proc/self_notes()
set name = "View Admin Remarks"
set category = "OOC"
set desc = "View the notes that admins have written about you"
if(!config.see_own_notes)
usr << "<span class='notice'>Sorry, that function is not enabled on this server.</span>"
return
show_note(usr.ckey, null, 1)
/client/proc/ignore_key(client)
var/client/C = client
if(C.key in prefs.ignoring)
prefs.ignoring -= C.key
else
prefs.ignoring |= C.key
src << "You are [(C.key in prefs.ignoring) ? "now" : "no longer"] ignoring [C.key] on the OOC channel."
prefs.save_preferences()
/client/verb/select_ignore()
set name = "Ignore"
set category = "OOC"
set desc ="Ignore a player's messages on the OOC channel"
var/selection = input("Please, select a player!", "Ignore", null, null) as null|anything in sortKey(clients)
if(!selection)
return
if(selection == src)
src << "You can't ignore yourself."
return
ignore_key(selection)
+22
View File
@@ -0,0 +1,22 @@
/client/verb/update_ping(time as num)
set instant = TRUE
set name = ".update_ping"
var/ping = pingfromtime(time)
lastping = ping
if (!avgping)
avgping = ping
else
avgping = MC_AVERAGE_SLOW(avgping, ping)
/client/proc/pingfromtime(time)
return ((world.time+world.tick_lag*world.tick_usage/100)-time)*100
/client/verb/display_ping(time as num)
set instant = TRUE
set name = ".display_ping"
src << "<span class='notice'>Round trip ping took [round(pingfromtime(time),1)]ms</span>"
/client/verb/ping()
set name = "Ping"
set category = "OOC"
winset(src, null, "command=.display_ping+[world.time+world.tick_lag*world.tick_usage/100]")
+24
View File
@@ -0,0 +1,24 @@
/client/verb/sethotkeys(from_pref = 0 as num)
set name = "Set Hotkeys"
set hidden = 1
set desc = "Used to set mob-specific hotkeys or load hoykey mode from preferences"
var/hotkey_default = "default"
var/hotkey_macro = "hotkeys"
var/current_setting
var/list/default_macros = list("default", "robot-default")
if(from_pref)
current_setting = (prefs.hotkeys ? hotkey_macro : hotkey_default)
else
current_setting = winget(src, "mainwindow", "macro")
if(mob)
hotkey_macro = mob.macro_hotkeys
hotkey_default = mob.macro_default
if(current_setting in default_macros)
winset(src, null, "mainwindow.macro=[hotkey_default] input.focus=true input.background-color=#d3b5b5")
else
winset(src, null, "mainwindow.macro=[hotkey_macro] mapwindow.map.focus=true input.background-color=#e0e0e0")
+175
View File
@@ -0,0 +1,175 @@
/mob/var/suiciding = 0
/mob/living/carbon/human/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
log_game("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
message_admins("[key_name(src)] (job: [job ? "[job]" : "None"]) commited suicide at [get_area(src)].")
var/obj/item/held_item = get_active_held_item()
if(held_item)
var/damagetype = held_item.suicide_act(src)
if(damagetype)
if(damagetype & SHAME)
adjustStaminaLoss(200)
suiciding = 0
return
var/damage_mod = 0
for(var/T in list(BRUTELOSS, FIRELOSS, TOXLOSS, OXYLOSS))
damage_mod += (T & damagetype) ? 1 : 0
damage_mod = max(1, damage_mod)
//Do 200 damage divided by the number of damage types applied.
if(damagetype & BRUTELOSS)
adjustBruteLoss(200/damage_mod)
if(damagetype & FIRELOSS)
adjustFireLoss(200/damage_mod)
if(damagetype & TOXLOSS)
adjustToxLoss(200/damage_mod)
if(damagetype & OXYLOSS)
adjustOxyLoss(200/damage_mod)
//If something went wrong, just do normal oxyloss
if(!(damagetype & (BRUTELOSS | FIRELOSS | TOXLOSS | OXYLOSS) ))
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
return
var/suicide_message = pick("[src] is attempting to bite [p_their()] tongue off! It looks like [p_theyre()] trying to commit suicide.", \
"[src] is jamming [p_their()] thumbs into [p_their()] eye sockets! It looks like [p_theyre()] trying to commit suicide.", \
"[src] is twisting [p_their()] own neck! It looks like [p_theyre()] trying to commit suicide.", \
"[src] is holding [p_their()] breath! It looks like [p_theyre()] trying to commit suicide.")
visible_message("<span class='danger'>[suicide_message]</span>", "<span class='userdanger'>[suicide_message]</span>")
adjustOxyLoss(max(200 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
/mob/living/brain/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src]'s brain is growing dull and lifeless. [p_they(TRUE)] look[p_s()] like [p_theyve()] lost the will to live.</span>", \
"<span class='userdanger'>[src]'s brain is growing dull and lifeless. [p_they(TRUE)] look[p_s()] like [p_theyve()] lost the will to live.</span>")
death(0)
/mob/living/carbon/monkey/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src] is attempting to bite [p_their()] tongue. It looks like [p_theyre()] trying to commit suicide.</span>", \
"<span class='userdanger'>[src] is attempting to bite [p_their()] tongue. It looks like [p_theyre()] trying to commit suicide.</span>")
adjustOxyLoss(max(200- getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
/mob/living/silicon/ai/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src] is powering down. It looks like [p_theyre()] trying to commit suicide.</span>", \
"<span class='userdanger'>[src] is powering down. It looks like [p_theyre()] trying to commit suicide.</span>")
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
/mob/living/silicon/robot/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src] is powering down. It looks like [p_theyre()] trying to commit suicide.</span>", \
"<span class='userdanger'>[src] is powering down. It looks like [p_theyre()] trying to commit suicide.</span>")
//put em at -175
adjustOxyLoss(max(maxHealth * 2 - getToxLoss() - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
/mob/living/silicon/pai/verb/suicide()
set category = "pAI Commands"
set desc = "Kill yourself and become a ghost (You will receive a confirmation prompt)"
set name = "pAI Suicide"
var/answer = input("REALLY kill yourself? This action can't be undone.", "Suicide", "No") in list ("Yes", "No")
if(answer == "Yes")
var/turf/T = get_turf(src.loc)
T.visible_message("<span class='notice'>[src] flashes a message across its screen, \"Wiping core files. Please acquire a new personality to continue using pAI device functions.\"</span>", null, \
"<span class='notice'>[src] bleeps electronically.</span>")
death(0)
else
src << "Aborting suicide attempt."
/mob/living/carbon/alien/humanoid/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src] is thrashing wildly! It looks like [p_theyre()] trying to commit suicide.</span>", \
"<span class='userdanger'>[src] is thrashing wildly! It looks like [p_theyre()] trying to commit suicide.</span>", \
"<span class='italics'>You hear thrashing.</span>")
//put em at -175
adjustOxyLoss(max(200 - getFireLoss() - getBruteLoss() - getOxyLoss(), 0))
death(0)
/mob/living/simple_animal/verb/suicide()
set hidden = 1
if(!canSuicide())
return
var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No")
if(!canSuicide())
return
if(confirm == "Yes")
suiciding = 1
visible_message("<span class='danger'>[src] begins to fall down. It looks like [p_theyve()] lost the will to live.</span>", \
"<span class='userdanger'>[src] begins to fall down. It looks like [p_theyve()] lost the will to live.</span>")
death(0)
/mob/living/proc/canSuicide()
if(stat == CONSCIOUS)
return TRUE
else if(stat == DEAD)
src << "You're already dead!"
else if(stat == UNCONSCIOUS)
src << "You need to be conscious to suicide!"
return
/mob/living/carbon/canSuicide()
if(!..())
return
if(!canmove || restrained()) //just while I finish up the new 'fun' suiciding verb. This is to prevent metagaming via suicide
src << "You can't commit suicide whilst restrained! ((You can type Ghost instead however.))"
return
if(has_brain_worms())
src << "You can't bring yourself to commit suicide!"
return
return TRUE
+127
View File
@@ -0,0 +1,127 @@
/client/verb/who()
set name = "Who"
set category = "OOC"
var/list/Lines = list()
var/msg = "--------\n"
if(length(admins) > 0)
Lines += "<b>Admins:</b>"
for(var/client/C in sortList(admins))
if(C.holder)
if(!C.holder.fakekey)
Lines += "<font color='#FF0000'>[C.key]</font>[show_info(C)]"
if(length(mentors) > 0)
Lines += "<b>Mentors:</b>"
for(var/client/C in sortList(clients))
var/mentor = mentor_datums[C.ckey]
if(mentor)
Lines += "<font color='#0033CC'>[C.key]</font>[show_info(C)]"
var/player_text = ""
var/display_count = 0 //Used to detect as to whether or not we should display the players list
for(var/client/C in sortList(clients))
if(C.holder)
if(C.holder.fakekey)
display_count++
player_text += "[C.holder.fakekey][show_info(C)]\n"
else if(!check_mentor_other(C))
display_count++
player_text += "[C.key][show_info(C)]\n"
if(display_count > 0)
Lines += "<b>Players:</b>"
Lines += player_text
for(var/line in Lines)
msg += "[line]\n"
msg += "<b>Total Players: [length(clients)]</b>\n"
msg += "--------"
src << msg
/client/proc/show_info(var/client/C)
if(!C)
return ""
if(!src.holder)
return ""
var/entry = "\t[C.key]"
if(C.holder && C.holder.fakekey)
entry += " <i>(as [C.holder.fakekey])</i>"
if (isnewplayer(C.mob))
entry += " - <font color='darkgray'><b>In Lobby</b></font>"
else
entry += " - Playing as [C.mob.real_name]"
switch(C.mob.stat)
if(UNCONSCIOUS)
entry += " - <font color='darkgray'><b>Unconscious</b></font>"
if(DEAD)
if(isobserver(C.mob))
var/mob/dead/observer/O = C.mob
if(O.started_as_observer)
entry += " - <font color='gray'>Observing</font>"
else
entry += " - <font color='black'><b>DEAD</b></font>"
else
entry += " - <font color='black'><b>DEAD</b></font>"
if(is_special_character(C.mob))
entry += " - <b><font color='red'>Antagonist</font></b>"
entry += " (<A HREF='?_src_=holder;adminmoreinfo=\ref[C.mob]'>?</A>)"
entry += " ([round(C.avgping, 1)]ms)"
return entry
/client/verb/adminwho()
set category = "Admin"
set name = "Adminwho"
var/msg = "<b>Current Admins:</b>\n"
if(holder)
for(var/client/C in admins)
msg += "\t[C] is a [C.holder.rank]"
if(C.holder.fakekey)
msg += " <i>(as [C.holder.fakekey])</i>"
if(isobserver(C.mob))
msg += " - Observing"
else if(istype(C.mob,/mob/new_player))
msg += " - Lobby"
else
msg += " - Playing"
if(C.is_afk())
msg += " (AFK)"
msg += "\n"
else
for(var/client/C in admins)
if(!C.holder.fakekey)
msg += "\t[C] is a [C.holder.rank]\n"
src << msg
/client/verb/mentorwho()
set category = "Mentor"
set name = "Mentorwho"
var/msg = "<b>Current Mentors:</b>\n"
for(var/client/C in mentors)
var/suffix = ""
if(holder)
if(isobserver(C.mob))
suffix += " - Observing"
else if(istype(C.mob,/mob/new_player))
suffix += " - Lobby"
else
suffix += " - Playing"
if(C.is_afk())
suffix += " (AFK)"
msg += "\t[C][suffix]\n"
src << msg