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
+3 -12
View File
@@ -8,6 +8,7 @@
establish_db_connection()
if(!dbcon.IsConnected())
src << "<span class='danger'>Failed to establish database connection.</span>"
return
var/serverip = "[world.internet_address]:[world.port]"
@@ -36,10 +37,6 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
duration = -1
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
duration = -1
@@ -136,8 +133,8 @@
if(kickbannedckey)
if(banned_mob && banned_mob.client && banned_mob.client.ckey == banckey)
del(banned_mob.client)
qdel(banned_mob.client)
return 1
/datum/admins/proc/DB_ban_unban(ckey, bantype, job = "")
@@ -160,9 +157,6 @@
if(BANTYPE_JOB_TEMP)
bantype_str = "JOB_TEMPBAN"
bantype_pass = 1
if(BANTYPE_APPEARANCE)
bantype_str = "APPEARANCE_PERMABAN"
bantype_pass = 1
if(BANTYPE_ADMIN_PERMA)
bantype_str = "ADMIN_PERMABAN"
bantype_pass = 1
@@ -361,7 +355,6 @@
output += "<option value='[BANTYPE_TEMP]'>TEMPBAN</option>"
output += "<option value='[BANTYPE_JOB_PERMA]'>JOB PERMABAN</option>"
output += "<option value='[BANTYPE_JOB_TEMP]'>JOB TEMPBAN</option>"
output += "<option value='[BANTYPE_APPEARANCE]'>IDENTITY BAN</option>"
output += "<option value='[BANTYPE_ADMIN_PERMA]'>ADMIN PERMABAN</option>"
output += "<option value='[BANTYPE_ADMIN_TEMP]'>ADMIN TEMPBAN</option>"
output += "</select></td>"
@@ -453,8 +446,6 @@
typedesc = "<b>JOBBAN</b><br><font size='2'>([job])"
if("JOB_TEMPBAN")
typedesc = "<b>TEMP JOBBAN</b><br><font size='2'>([job])<br>([duration] minutes [(unbanned) ? "" : "(<a href=\"byond://?src=\ref[src];dbbanedit=duration;dbbanid=[banid]\">Edit</a>))"]<br>Expires [expiration]"
if("APPEARANCE_PERMABAN")
typedesc = "<b>IDENTITY PERMABAN</b>"
if("ADMIN_PERMABAN")
typedesc = "<b>ADMIN PERMABAN</b>"
if("ADMIN_TEMPBAN")
+92 -9
View File
@@ -1,11 +1,17 @@
//Blocks an attempt to connect before even creating our client datum thing.
//How many new ckey matches before we revert the stickyban to it's roundstart state
//These are exclusive, so once it goes over one of these numbers, it reverts the ban
#define STICKYBAN_MAX_MATCHES 20
#define STICKYBAN_MAX_EXISTING_USER_MATCHES 5 //ie, users who were connected before the ban triggered
#define STICKYBAN_MAX_ADMIN_MATCHES 2
/world/IsBanned(key,address,computer_id)
if (!key || !address || !computer_id)
log_access("Failed Login (invalid data): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided invalid or blank information to the server on connection (byond username, IP, and Computer ID.) Provided information for reference: Username:'[key]' IP:'[address]' Computer ID:'[computer_id]'. (If you continue to get this error, please restart byond or contact byond support.)")
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
if (text2num(computer_id) == 2147483647) //this cid causes stickybans to go haywire
log_access("Failed Login (invalid cid): [key] [address]-[computer_id]")
return list("reason"="invalid login data", "desc"="Error: Could not check ban status, Please try again. Error message: Your computer provided an invalid Computer ID.)")
var/admin = 0
@@ -13,6 +19,17 @@
if((ckey in admin_datums) || (ckey in deadmins))
admin = 1
//Whitelist
if(config.usewhitelist)
if(!check_whitelist(ckey(key)))
if (admin)
log_admin("The admin [key] has been allowed to bypass the whitelist")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass the whitelist</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass the whitelist</span>")
else
log_access("Failed Login: [key] - Not on whitelist")
return list("reason"="whitelist", "desc" = "\nReason: You are not on the white list for this server")
//Guest Checking
if(IsGuestKey(key))
if (!guests_allowed)
@@ -99,17 +116,83 @@
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["reason"]]")
return .
. = ..() //default pager ban stuff
if (.)
var/list/ban = ..() //default pager ban stuff
if (ban)
var/bannedckey = "ERROR"
if (ban["ckey"])
bannedckey = ban["ckey"]
var/newmatch = FALSE
var/client/C = directory[ckey]
var/cachedban = SSstickyban.cache[bannedckey]
//rogue ban in the process of being reverted.
if (cachedban && cachedban["reverting"])
return null
if (cachedban && ckey != bannedckey)
newmatch = TRUE
if (cachedban["keys"])
if (cachedban["keys"][ckey])
newmatch = FALSE
if (cachedban["matches_this_round"][ckey])
newmatch = FALSE
if (newmatch && cachedban)
var/list/newmatches = cachedban["matches_this_round"]
var/list/newmatches_connected = cachedban["existing_user_matches_this_round"]
var/list/newmatches_admin = cachedban["admin_matches_this_round"]
newmatches[ckey] = ckey
if (C)
newmatches_connected[ckey] = ckey
if (admin)
newmatches_admin[ckey] = ckey
if (\
newmatches.len > STICKYBAN_MAX_MATCHES || \
newmatches_connected.len > STICKYBAN_MAX_EXISTING_USER_MATCHES || \
newmatches_admin.len > STICKYBAN_MAX_ADMIN_MATCHES \
)
if (cachedban["reverting"])
return null
cachedban["reverting"] = TRUE
world.SetConfig("ban", bannedckey, null)
log_game("Stickyban on [bannedckey] detected as rogue, reverting to it's roundstart state")
message_admins("Stickyban on [bannedckey] detected as rogue, reverting to it's roundstart state")
//do not convert to timer.
spawn (5)
world.SetConfig("ban", bannedckey, null)
sleep(1)
world.SetConfig("ban", bannedckey, null)
cachedban["matches_this_round"] = list()
cachedban["existing_user_matches_this_round"] = list()
cachedban["admin_matches_this_round"] = list()
cachedban -= "reverting"
world.SetConfig("ban", bannedckey, list2stickyban(cachedban))
return null
//byond will not trigger isbanned() for "global" host bans,
//ie, ones where the "apply to this game only" checkbox is not checked (defaults to not checked)
//So it's safe to let admins walk thru host/sticky bans here
if (admin)
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass a matching host/sticky ban</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching host/sticky ban</span>")
log_admin("The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]")
message_admins("<span class='adminnotice'>The admin [key] has been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
addclientmessage(ckey,"<span class='adminnotice'>You have been allowed to bypass a matching host/sticky ban on [bannedckey]</span>")
return null
else
log_access("Failed Login: [key] [computer_id] [address] - Banned [.["message"]]")
if (C) //user is already connected!.
C << "You are about to get disconnected for matching a sticky ban after you connected. If this turns out to be the ban evasion detection system going haywire, we will automatically detect this and revert the matches. if you feel that this is the case, please wait EXACTLY 6 seconds then reconnect using file -> reconnect to see if the match was reversed."
var/desc = "\nReason:(StickyBan) You, or another user of this computer or connection ([bannedckey]) is banned from playing here. The ban reason is:\n[ban["message"]]\nThis ban was applied by [ban["admin"]]\nThis is a BanEvasion Detection System ban, if you think this ban is a mistake, please wait EXACTLY 6 seconds, then try again before filing an appeal.\n"
. = list("reason" = "Stickyban", "desc" = desc)
log_access("Failed Login: [key] [computer_id] [address] - StickyBanned [ban["message"]] Target Username: [bannedckey] Placed by [ban["admin"]]")
return .
#undef STICKYBAN_MAX_MATCHES
#undef STICKYBAN_MAX_EXISTING_USER_MATCHES
#undef STICKYBAN_MAX_ADMIN_MATCHES
+2 -2
View File
@@ -117,9 +117,9 @@ var/savefile/Banlist
if (temp)
Banlist["minutes"] << bantimestamp
if(!temp)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0)
add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0, null, 0)
else
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0)
add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0, null, 0)
return 1
/proc/RemoveBan(foldername)
+27 -15
View File
@@ -34,7 +34,7 @@ var/global/BSACooldown = 0
body += " played by <b>[M.client]</b> "
body += "\[<A href='?_src_=holder;editrights=rank;ckey=[M.ckey]'>[M.client.holder ? M.client.holder.rank : "Player"]</A>\]"
if(istype(M, /mob/new_player))
if(isnewplayer(M))
body += " <B>Hasn't Entered Game</B> "
else
body += " \[<A href='?_src_=holder;revive=\ref[M]'>Heal</A>\] "
@@ -91,7 +91,7 @@ var/global/BSACooldown = 0
body += "<A href='?_src_=holder;subtlemessage=\ref[M]'>Subtle message</A>"
if (M.client)
if(!istype(M, /mob/new_player))
if(!isnewplayer(M))
body += "<br><br>"
body += "<b>Transformation:</b>"
body += "<br>"
@@ -162,6 +162,9 @@ var/global/BSACooldown = 0
body += "<br><br>"
body += "<b>Other actions:</b>"
body += "<br>"
body += "<A href='?_src_=holder;mentor=\ref[M]'>Make Mentor</A> | "
body += "<A href='?_src_=holder;removementor=\ref[M]'>Remove Mentor</A> | "
body += "<br>"
body += "<A href='?_src_=holder;forcespeech=\ref[M]'>Forcesay</A> | "
body += "<A href='?_src_=holder;tdome1=\ref[M]'>Thunderdome 1</A> | "
body += "<A href='?_src_=holder;tdome2=\ref[M]'>Thunderdome 2</A> | "
@@ -205,7 +208,7 @@ var/global/BSACooldown = 0
dat+="<HR><B>Feed Security functions:</B><BR>"
dat+="<BR><A href='?src=\ref[src];ac_menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>"
dat+="<BR><A href='?src=\ref[src];ac_menu_censor_story=1'>Censor Feed Stories</A>"
dat+="<BR><A href='?src=\ref[src];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel.</A>"
dat+="<BR><A href='?src=\ref[src];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel).</A>"
dat+="<BR><HR><A href='?src=\ref[src];ac_set_signature=1'>The newscaster recognises you as:<BR> <FONT COLOR='green'>[src.admin_signature]</FONT></A>"
if(1)
dat+= "Station Feed Channels<HR>"
@@ -513,15 +516,17 @@ var/global/BSACooldown = 0
set category = "Server"
set desc="Start the round RIGHT NOW"
set name="Start Now"
if(ticker.current_state == GAME_STATE_PREGAME)
ticker.can_fire = 1
ticker.timeLeft = 0
if(ticker.current_state == GAME_STATE_PREGAME || ticker.current_state == GAME_STATE_STARTUP)
ticker.start_immediately = TRUE
log_admin("[usr.key] has started the game.")
message_admins("<font color='blue'>[usr.key] has started the game.</font>")
var/msg = ""
if(ticker.current_state == GAME_STATE_STARTUP)
msg = " (The server is still setting up, but the round will be \
started as soon as possible.)"
message_admins("<font color='blue'>\
[usr.key] has started the game.[msg]</font>")
feedback_add_details("admin_verb","SN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return 1
else if (ticker.current_state == GAME_STATE_STARTUP)
usr << "<font color='red'>Error: Start Now: Game is in startup, please wait until it has finished.</font>"
else
usr << "<font color='red'>Error: Start Now: Game has already started.</font>"
@@ -633,7 +638,8 @@ var/global/BSACooldown = 0
var/turf/T = get_turf(usr.loc)
T.ChangeTurf(chosen)
else
new chosen(usr.loc)
var/atom/A = new chosen(usr.loc)
A.admin_spawned = TRUE
log_admin("[key_name(usr)] spawned [chosen] at ([usr.x],[usr.y],[usr.z])")
feedback_add_details("admin_verb","SA") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -687,7 +693,7 @@ var/global/BSACooldown = 0
ai_number++
if(isAI(S))
usr << "<b>AI [key_name(S, usr)]'s laws:</b>"
else if(isrobot(S))
else if(iscyborg(S))
var/mob/living/silicon/robot/R = S
usr << "<b>CYBORG [key_name(S, usr)] [R.connected_ai?"(Slaved to: [R.connected_ai])":"(Independant)"]: laws:</b>"
else if (ispAI(S))
@@ -702,7 +708,7 @@ var/global/BSACooldown = 0
if(!ai_number)
usr << "<b>No AIs located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_devil_info()
/datum/admins/proc/output_all_devil_info()
var/devil_number = 0
for(var/D in ticker.mode.devils)
devil_number++
@@ -710,6 +716,12 @@ var/global/BSACooldown = 0
if(!devil_number)
usr << "<b>No Devils located</b>" //Just so you know the thing is actually working and not just ignoring you.
/datum/admins/proc/output_devil_info(mob/living/M)
if(istype(M) && M.mind && M.mind.devilinfo)
usr << ticker.mode.printdevilinfo(M.mind)
else
usr << "<b>[M] is not a devil."
/datum/admins/proc/manage_free_slots()
if(!check_rights())
return
@@ -766,13 +778,13 @@ var/global/BSACooldown = 0
/proc/kick_clients_in_lobby(message, kick_only_afk = 0)
var/list/kicked_client_names = list()
for(var/client/C in clients)
if(istype(C.mob, /mob/new_player))
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
if(isnewplayer(C.mob))
if(kick_only_afk && !C.is_afk()) //Ignore clients who are not afk
continue
if(message)
C << message
kicked_client_names.Add("[C.ckey]")
del(C)
qdel(C)
return kicked_client_names
//returns 1 to let the dragdrop code know we are trapping this event
+7 -9
View File
@@ -37,16 +37,14 @@
src << "<font color='red'>Error: admin_investigate: [INVESTIGATE_DIR][subject] is an invalid path or cannot be accessed.</font>"
return
src << browse(F,"window=investigate[subject];size=800x300")
if("hrefs") //persistant logs and stuff
if(config && config.log_hrefs)
if(href_logfile)
src << browse(href_logfile,"window=investigate[subject];size=800x300")
else
src << "<font color='red'>Error: admin_investigate: No href logfile found.</font>"
return
if("hrefs") //persistent logs and stuff
if(href_logfile)
src << browse(href_logfile,"window=investigate[subject];size=800x300")
else if(!config.log_hrefs)
src << "<span class='danger'>Href logging is off and no logfile was found.</span>"
return
else
src << "<font color='red'>Error: admin_investigate: Href Logging is not on.</font>"
src << "<span class='danger'>No href logfile was found.</span>"
return
if("notes")
show_note()
+13 -13
View File
@@ -1,5 +1,5 @@
/client/proc/admin_memo()
set name = "Memo"
set name = "Admin Memos"
set category = "Server"
if(!check_rights(0))
return
@@ -26,7 +26,7 @@
log_game("SQL ERROR obtaining ckey from memo table. Error : \[[err]\]\n")
return
if(query_memocheck.NextRow())
src << "You already have set a memo."
src << "You already have set an admin memo."
return
var/memotext = input(src,"Write your Memo","Memo") as message
if(!memotext)
@@ -38,8 +38,8 @@
var/err = query_memoadd.ErrorMsg()
log_game("SQL ERROR adding new memo. Error : \[[err]\]\n")
return
log_admin("[key_name(src)] has set a memo: [memotext]")
message_admins("[key_name_admin(src)] has set a memo:<br>[memotext]")
log_admin("[key_name(src)] has set an admin memo: [memotext]")
message_admins("[key_name_admin(src)] has set an admin memo:<br>[memotext]")
if("Edit")
var/DBQuery/query_memolist = dbcon.NewQuery("SELECT ckey FROM [format_table_name("memo")]")
if(!query_memolist.Execute())
@@ -76,11 +76,11 @@
log_game("SQL ERROR editing memo. Error : \[[err]\]\n")
return
if(target_sql_ckey == sql_ckey)
log_admin("[key_name(src)] has edited their memo from [old_memo] to [new_memo]")
message_admins("[key_name_admin(src)] has edited their memo from<br>[old_memo]<br>to<br>[new_memo]")
log_admin("[key_name(src)] has edited their admin memo from [old_memo] to [new_memo]")
message_admins("[key_name_admin(src)] has edited their admin memo from<br>[old_memo]<br>to<br>[new_memo]")
else
log_admin("[key_name(src)] has edited [target_sql_ckey]'s memo from [old_memo] to [new_memo]")
message_admins("[key_name_admin(src)] has edited [target_sql_ckey]'s memo from<br>[old_memo]<br>to<br>[new_memo]")
log_admin("[key_name(src)] has edited [target_sql_ckey]'s admin memo from [old_memo] to [new_memo]")
message_admins("[key_name_admin(src)] has edited [target_sql_ckey]'s admin memo from<br>[old_memo]<br>to<br>[new_memo]")
if("Show")
var/DBQuery/query_memoshow = dbcon.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]")
if(!query_memoshow.Execute())
@@ -93,7 +93,7 @@
var/memotext = query_memoshow.item[2]
var/timestamp = query_memoshow.item[3]
var/last_editor = query_memoshow.item[4]
output += "<span class='memo'>Memo by <span class='prefix'>[ckey]</span> on [timestamp]"
output += "<span class='memo'>Admin memo by <span class='prefix'>[ckey]</span> on [timestamp]"
if(last_editor)
output += "<br><span class='memoedit'>Last edit by [last_editor] <A href='?_src_=holder;memoeditlist=[ckey]'>(Click here to see edit log)</A></span>"
output += "<br>[memotext]</span><br>"
@@ -124,8 +124,8 @@
log_game("SQL ERROR removing memo. Error : \[[err]\]\n")
return
if(target_sql_ckey == sql_ckey)
log_admin("[key_name(src)] has removed their memo.")
message_admins("[key_name_admin(src)] has removed their memo.")
log_admin("[key_name(src)] has removed their admin memo.")
message_admins("[key_name_admin(src)] has removed their admin memo.")
else
log_admin("[key_name(src)] has removed [target_sql_ckey]'s memo.")
message_admins("[key_name_admin(src)] has removed [target_sql_ckey]'s memo.")
log_admin("[key_name(src)] has removed [target_sql_ckey]'s admin memo.")
message_admins("[key_name_admin(src)] has removed [target_sql_ckey]'s admin memo.")
+11 -1
View File
@@ -23,6 +23,9 @@ var/list/admin_ranks = list() //list of all admin_rank datums
adds = init_adds
subs = init_subs
/datum/admin_rank/vv_edit_var(var_name, var_value)
return FALSE
/proc/admin_keyword_to_flag(word, previous_rights=0)
var/flag = 0
switch(ckey(word))
@@ -161,6 +164,9 @@ var/list/admin_ranks = list() //list of all admin_rank datums
C.holder = null
admins.Cut()
load_admin_ranks()
//Clear profile access
for(var/A in world.GetConfig("admin"))
world.SetConfig("APP/admin", A, null)
var/list/rank_names = list()
for(var/datum/admin_rank/R in admin_ranks)
@@ -189,6 +195,8 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
else
establish_db_connection()
@@ -214,6 +222,8 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/datum/admins/D = new(rank_names[rank], ckey) //create the admin datum and store it for later use
if(!D)
continue //will occur if an invalid rank is provided
if(D.rank.rights & R_DEBUG) //grant profile access
world.SetConfig("APP/admin", ckey, "role=admin")
D.associate(directory[ckey]) //find the client for a ckey if they are connected and associate them with the new admin datum
#ifdef TESTING
@@ -369,4 +379,4 @@ var/list/admin_ranks = list() //list of all admin_rank datums
var/sql_admin_rank = sanitizeSQL(newrank)
var/DBQuery/query_update = dbcon.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank = '[sql_admin_rank]' WHERE ckey = '[sql_ckey]'")
query_update.Execute()
query_update.Execute()
+116 -34
View File
@@ -8,6 +8,7 @@ var/list/admin_verbs_default = list(
/client/proc/hide_most_verbs, /*hides all our hideable adminverbs*/
/client/proc/debug_variables, /*allows us to -see- the variables of any instance in the game. +VAREDIT needed to modify*/
/client/proc/admin_memo, /*admin memo system. show/delete/write. +SERVER needed to delete admin memos of others*/
/client/proc/mentor_memo, /*mentor memo system. show/delete/write. +SERVER needed to delete mentor memos of others*/
/client/proc/deadchat, /*toggles deadchat on/off*/
/client/proc/dsay, /*talk in deadchat using our ckey/fakekey*/
/client/proc/toggleprayers, /*toggles prayers on/off*/
@@ -16,6 +17,7 @@ var/list/admin_verbs_default = list(
/client/proc/investigate_show, /*various admintools for investigation. Such as a singulo grief-log*/
/client/proc/secrets,
/client/proc/reload_admins,
/client/proc/reload_mentors,
/client/proc/reestablish_db_connection,/*reattempt a connection to the database*/
/client/proc/cmd_admin_pm_context, /*right-click adminPM interface*/
/client/proc/cmd_admin_pm_panel, /*admin-pm list*/
@@ -53,6 +55,7 @@ var/list/admin_verbs_admin = list(
/client/proc/jumptocoord, /*we ghost and jump to a coordinate*/
/client/proc/Getmob, /*teleports a mob to our location*/
/client/proc/Getkey, /*teleports a mob with a certain ckey to our location*/
// /client/proc/sendmob, /*sends a mob somewhere*/ -Removed due to it needing two sorting procs to work, which were executed every time an admin right-clicked. ~Errorage
/client/proc/jumptoarea,
/client/proc/jumptokey, /*allows us to jump to the location of a mob with a certain ckey*/
/client/proc/jumptomob, /*allows us to jump to a specific mob*/
@@ -84,6 +87,9 @@ var/list/admin_verbs_sounds = list(
var/list/admin_verbs_fun = list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/set_dynex_scale,
/client/proc/drop_dynex_bomb,
/client/proc/cinematic,
/client/proc/one_click_antag,
/client/proc/send_space_ninja,
@@ -96,16 +102,12 @@ var/list/admin_verbs_fun = list(
/client/proc/forceEvent,
/client/proc/bluespace_artillery,
/client/proc/admin_change_sec_level,
/client/proc/show_tip,
/client/proc/toggle_nuke,
/client/proc/reset_latejoin_spawns,
/client/proc/mass_zombie_infection,
/client/proc/mass_zombie_cure,
/client/proc/polymorph_all,
/client/proc/everyone_random,
/client/proc/drop_bomb
/client/proc/show_tip
)
var/list/admin_verbs_spawn = list(
/datum/admins/proc/spawn_atom, /*allows us to spawn instances*/
/client/proc/respawn_character
@@ -117,6 +119,7 @@ var/list/admin_verbs_server = list(
/datum/admins/proc/delay,
/datum/admins/proc/toggleaban,
/client/proc/toggle_log_hrefs,
/client/proc/everyone_random,
/datum/admins/proc/toggleAI,
/client/proc/cmd_admin_delete, /*delete an instance/object/mob/etc*/
/client/proc/cmd_debug_del_all,
@@ -125,7 +128,8 @@ var/list/admin_verbs_server = list(
/client/proc/forcerandomrotate,
/client/proc/adminchangemap,
#endif
/client/proc/panicbunker
/client/proc/panicbunker,
/client/proc/toggle_hub
)
var/list/admin_verbs_debug = list(
@@ -147,12 +151,19 @@ var/list/admin_verbs_debug = list(
/client/proc/check_bomb_impacts,
/proc/machine_upgrade,
/client/proc/populate_world,
/client/proc/get_dynex_power, //*debug verbs for dynex explosions.
/client/proc/get_dynex_range, //*debug verbs for dynex explosions.
/client/proc/set_dynex_scale,
/client/proc/cmd_display_del_log,
/client/proc/reset_latejoin_spawns,
/client/proc/create_outfits,
/client/proc/modify_goals,
/client/proc/debug_huds,
/client/proc/map_template_load,
/client/proc/map_template_upload,
/client/proc/jump_to_ruin
/client/proc/jump_to_ruin,
/client/proc/clear_dynamic_transit,
/client/proc/toggle_medal_disable
)
var/list/admin_verbs_possess = list(
/proc/possess,
@@ -197,6 +208,10 @@ var/list/admin_verbs_hideable = list(
/client/proc/cmd_admin_dress,
/client/proc/cmd_admin_gib_self,
/client/proc/drop_bomb,
/client/proc/drop_dynex_bomb,
/client/proc/get_dynex_range,
/client/proc/get_dynex_power,
/client/proc/set_dynex_scale,
/client/proc/cinematic,
/client/proc/send_space_ninja,
/client/proc/cmd_admin_add_freeform_ai_law,
@@ -244,6 +259,7 @@ var/list/admin_verbs_hideable = list(
var/rights = holder.rank.rights
verbs += admin_verbs_default
verbs += /client/proc/cmd_mentor_say
if(rights & R_BUILDMODE)
verbs += /client/proc/togglebuildmodeself
if(rights & R_ADMIN)
@@ -302,7 +318,7 @@ var/list/admin_verbs_hideable = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control,
/client/proc/startSinglo,
/client/proc/set_fps,
/client/proc/set_server_fps,
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/readmin
@@ -350,7 +366,7 @@ var/list/admin_verbs_hideable = list(
set name = "Aghost"
if(!holder)
return
if(istype(mob,/mob/dead/observer))
if(isobserver(mob))
//re-enter
var/mob/dead/observer/ghost = mob
if(!ghost.mind || !ghost.mind.current) //won't do anything if there is no body
@@ -361,7 +377,7 @@ var/list/admin_verbs_hideable = list(
ghost.can_reenter_corpse = 1 //force re-entering even when otherwise not possible
ghost.reenter_corpse()
feedback_add_details("admin_verb","P") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
else if(istype(mob,/mob/new_player))
else if(isnewplayer(mob))
src << "<font color='red'>Error: Aghost: Can't admin-ghost whilst in the lobby. Join or Observe first.</font>"
else
//ghostize
@@ -472,7 +488,7 @@ var/list/admin_verbs_hideable = list(
holder.fakekey = new_key
createStealthKey()
if(isobserver(mob))
mob.invisibility = INVISIBILITY_ABSTRACT //JUST IN CASE
mob.invisibility = INVISIBILITY_MAXIMUM //JUST IN CASE
mob.alpha = 0 //JUUUUST IN CASE
mob.name = " "
mob.mouse_opacity = 0
@@ -481,22 +497,25 @@ var/list/admin_verbs_hideable = list(
feedback_add_details("admin_verb","SM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_bomb()
set category = "Special Verbs"
set category = "Dangerous"
set name = "Drop Bomb"
set desc = "Cause an explosion of varying strength at your location."
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/choice = input("What size explosion would you like to produce?") in choices
var/list/choices = list("Small Bomb (1, 2, 3, 3)", "Medium Bomb (2, 3, 4, 4)", "Big Bomb (3, 5, 7, 5)", "Maxcap", "Custom Bomb")
var/choice = input("What size explosion would you like to produce? WARNING: These ignore the maxcap") as null|anything in choices
var/turf/epicenter = mob.loc
switch(choice)
if(null)
return 0
if("Small Bomb")
explosion(epicenter, 1, 2, 3, 3)
if("Medium Bomb")
explosion(epicenter, 2, 3, 4, 4)
if("Big Bomb")
explosion(epicenter, 3, 5, 7, 5)
if("Small Bomb (1, 2, 3, 3)")
explosion(epicenter, 1, 2, 3, 3, TRUE, TRUE)
if("Medium Bomb (2, 3, 4, 4)")
explosion(epicenter, 2, 3, 4, 4, TRUE, TRUE)
if("Big Bomb (3, 5, 7, 5)")
explosion(epicenter, 3, 5, 7, 5, TRUE, TRUE)
if("Maxcap")
explosion(epicenter, MAX_EX_DEVESTATION_RANGE, MAX_EX_HEAVY_RANGE, MAX_EX_LIGHT_RANGE, MAX_EX_FLASH_RANGE)
if("Custom Bomb")
var/devastation_range = input("Devastation range (in tiles):") as null|num
if(devastation_range == null)
@@ -510,11 +529,58 @@ var/list/admin_verbs_hideable = list(
var/flash_range = input("Flash range (in tiles):") as null|num
if(flash_range == null)
return
if(devastation_range > MAX_EX_DEVESTATION_RANGE || heavy_impact_range > MAX_EX_HEAVY_RANGE || light_impact_range > MAX_EX_LIGHT_RANGE || flash_range > MAX_EX_FLASH_RANGE)
if(alert("Bomb is bigger than the maxcap. Continue?",,"Yes","No") != "Yes")
return
epicenter = mob.loc //We need to reupdate as they may have moved again
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range)
message_admins("<span class='adminnotice'>[ckey] creating an admin explosion at [epicenter.loc].</span>")
explosion(epicenter, devastation_range, heavy_impact_range, light_impact_range, flash_range, TRUE, TRUE)
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
feedback_add_details("admin_verb","DB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/drop_dynex_bomb()
set category = "Dangerous"
set name = "Drop DynEx Bomb"
set desc = "Cause an explosion of varying strength at your location."
var/ex_power = input("Explosive Power:") as null|num
var/turf/epicenter = mob.loc
if(ex_power && epicenter)
dyn_explosion(epicenter, ex_power)
message_admins("[ADMIN_LOOKUPFLW(usr)] creating an admin explosion at [epicenter.loc].")
log_admin("[key_name(usr)] created an admin explosion at [epicenter.loc].")
feedback_add_details("admin_verb","DDXB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/get_dynex_range()
set category = "Debug"
set name = "Get DynEx Range"
set desc = "Get the estimated range of a bomb, using explosive power."
var/ex_power = input("Explosive Power:") as null|num
var/range = round((2 * ex_power)**DYN_EX_SCALE)
usr << "Estimated Explosive Range: (Devestation: [round(range*0.25)], Heavy: [round(range*0.5)], Light: [round(range)])"
/client/proc/get_dynex_power()
set category = "Debug"
set name = "Get DynEx Power"
set desc = "Get the estimated required power of a bomb, to reach a specific range."
var/ex_range = input("Light Explosion Range:") as null|num
var/power = (0.5 * ex_range)**(1/DYN_EX_SCALE)
usr << "Estimated Explosive Power: [power]"
/client/proc/set_dynex_scale()
set category = "Debug"
set name = "Set DynEx Scale"
set desc = "Set the scale multiplier of dynex explosions. The default is 0.5."
var/ex_scale = input("New DynEx Scale:") as null|num
if(!ex_scale)
return
DYN_EX_SCALE = ex_scale
log_admin("[key_name(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
message_admins("[key_name_admin(usr)] has modified Dynamic Explosion Scale: [ex_scale]")
/client/proc/give_spell(mob/T in mob_list)
set category = "Fun"
set name = "Give Spell"
@@ -527,16 +593,30 @@ var/list/admin_verbs_hideable = list(
var/obj/effect/proc_holder/spell/S = input("Choose the spell to give to that guy", "ABRAKADABRA") as null|anything in spell_list
if(!S)
return
S = spell_list[S]
feedback_add_details("admin_verb","GS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
log_admin("[key_name(usr)] gave [key_name(T)] the spell [S].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the spell [S].</span>")
S = spell_list[S]
if(T.mind)
T.mind.AddSpell(new S)
else
T.AddSpell(new S)
message_admins("<span class='danger'>Spells given to mindless mobs will not be transferred in mindswap or cloning!</span>")
/client/proc/remove_spell(mob/T in mob_list)
set category = "Fun"
set name = "Remove Spell"
set desc = "Remove a spell from the selected mob."
if(T && T.mind)
var/obj/effect/proc_holder/spell/S = input("Choose the spell to remove", "NO ABRAKADABRA") as null|anything in T.mind.spell_list
if(S)
T.mind.RemoveSpell(S)
log_admin("[key_name(usr)] removed the spell [S] from [key_name(T)].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed the spell [S] from [key_name(T)].</span>")
feedback_add_details("admin_verb","RS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/give_disease(mob/T in mob_list)
set category = "Fun"
@@ -637,7 +717,6 @@ var/list/admin_verbs_hideable = list(
var/list/candidates
var/turf/open/floor/tile
var/j,k
var/mob/living/carbon/human/mob
for (var/i = 1 to amount)
j = 100
@@ -657,16 +736,19 @@ var/list/admin_verbs_hideable = list(
while ((!tile || !istype(tile)) && --k > 0)
if (tile)
mob = new/mob/living/carbon/human/interactive(tile)
testing("Spawned test mob with name \"[mob.name]\" at [tile.x],[tile.y],[tile.z]")
new/mob/living/carbon/human/interactive(tile)
testing("Spawned test mob at [tile.x],[tile.y],[tile.z]")
while (!area && --j > 0)
/client/proc/toggle_AI_interact()
set name = "Toggle Admin AI Interact"
set category = "Admin"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
/client/proc/toggle_AI_interact()
set name = "Toggle Admin AI Interact"
set category = "Admin"
set desc = "Allows you to interact with most machines as an AI would as a ghost"
AI_Interact = !AI_Interact
if(mob && IsAdminGhost(mob))
mob.has_unlimited_silicon_privilege = AI_Interact
log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact")
message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction")
-110
View File
@@ -1,110 +0,0 @@
//ban people from using custom names and appearances. that'll show 'em.
var/appearanceban_runonce //Updates legacy bans with new info
var/appearance_keylist[0] //to store the keys
/proc/appearance_fullban(mob/M, reason)
if (!M || !M.key) return
appearance_keylist.Add(text("[M.ckey] ## [reason]"))
appearance_savebanfile()
/proc/appearance_client_fullban(ckey)
if (!ckey) return
appearance_keylist.Add(text("[ckey]"))
appearance_savebanfile()
//returns a reason if M is banned, returns 0 otherwise
/proc/appearance_isbanned(mob/M)
if(M)
for(var/s in appearance_keylist)
if(findtext(s, "[M.ckey]") == 1)
var/startpos = findtext(s, "## ") + 3
if(startpos && startpos < length(s))
var/text = copytext(s, startpos, 0)
if(text)
return text
return "Reason Unspecified"
return 0
/*
DEBUG
/mob/verb/list_all_appearances()
set name = "list all appearances"
for(var/s in appearance_keylist)
world << s
/mob/verb/reload_appearances()
set name = "reload appearances"
appearance_loadbanfile()
*/
/proc/appearance_loadbanfile()
if(config.ban_legacy_system)
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] >> appearance_keylist
log_admin("Loading appearance_rank")
S["runonce"] >> appearanceban_runonce
if (!length(appearance_keylist))
appearance_keylist=list()
log_admin("appearance_keylist was empty")
else
if(!establish_db_connection())
world.log << "Database connection failed. Reverting to the legacy ban system."
diary << "Database connection failed. Reverting to the legacy ban system."
config.ban_legacy_system = 1
appearance_loadbanfile()
return
//appearance bans
var/DBQuery/query = dbcon.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_PERMABAN' AND NOT unbanned = 1")
query.Execute()
while(query.NextRow())
var/ckey = query.item[1]
appearance_keylist.Add("[ckey]")
/proc/appearance_savebanfile()
var/savefile/S=new("data/appearance_full.ban")
S["keys[0]"] << appearance_keylist
/proc/appearance_unban(mob/M)
appearance_remove("[M.ckey]")
appearance_savebanfile()
/proc/appearance_updatelegacybans()
if(!appearanceban_runonce)
log_admin("Updating appearancefile!")
// Updates bans.. Or fixes them. Either way.
for(var/T in appearance_keylist)
if(!T)
continue
appearanceban_runonce++ //don't run this update again
/proc/appearance_remove(X)
for (var/i = 1; i <= length(appearance_keylist); i++)
if( findtext(appearance_keylist[i], "[X]") )
appearance_keylist.Remove(appearance_keylist[i])
appearance_savebanfile()
return 1
return 0
/*
/proc/DB_ban_isappearancebanned(var/playerckey)
establish_db_connection()
if(!dbcon.IsConnected())
return
var/sqlplayerckey = sanitizeSQL(ckey(playerckey))
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM [format_table_name("ban")] WHERE CKEY = '[sqlplayerckey]' AND ((bantype = 'APPEARANCE_PERMABAN') OR (bantype = 'APPEARANCE_TEMPBAN' AND expiration_time > Now())) AND unbanned != 1")
query.Execute()
while(query.NextRow())
return 1
return 0
*/
+26 -11
View File
@@ -34,7 +34,7 @@
return
/client/proc/create_poll_function()
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice")
var/polltype = input("Choose poll type.","Poll Type") in list("Single Option","Text Reply","Rating","Multiple Choice", "Instant Runoff Voting")|null
var/choice_amount = 0
switch(polltype)
if("Single Option")
@@ -48,6 +48,10 @@
choice_amount = input("How many choices should be allowed?","Select choice amount") as num|null
if(!choice_amount)
return
if ("Instant Runoff Voting")
polltype = POLLTYPE_IRV
else
return 0
var/starttime = SQLtime()
var/endtime = input("Set end time for poll as format YYYY-MM-DD HH:MM:SS. All times in server time. HH:MM:SS is optional and 24-hour. Must be later than starting time for obvious reasons.", "Set end time", SQLtime()) as text
if(!endtime)
@@ -81,12 +85,20 @@
adminonly = 0
else
return
var/dontshow
switch(alert("Hide poll results from tracking until completed?",,"Yes","No","Cancel"))
if("Yes")
dontshow = 1
if("No")
dontshow = 0
else
return
var/sql_ckey = sanitizeSQL(ckey)
var/question = input("Write your question","Question") as message|null
if(!question)
return
question = sanitizeSQL(question)
var/DBQuery/query_polladd_question = dbcon.NewQuery("INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]')")
var/DBQuery/query_polladd_question = dbcon.NewQuery("INSERT INTO [format_table_name("poll_question")] (polltype, starttime, endtime, question, adminonly, multiplechoiceoptions, createdby_ckey, createdby_ip, dontshow) VALUES ('[polltype]', '[starttime]', '[endtime]', '[question]', '[adminonly]', '[choice_amount]', '[sql_ckey]', '[address]', '[dontshow]')")
if(!query_polladd_question.Execute())
var/err = query_polladd_question.ErrorMsg()
log_game("SQL ERROR adding new poll question to table. Error : \[[err]\]\n")
@@ -109,14 +121,15 @@
if(!option)
return pollid
option = sanitizeSQL(option)
var/percentagecalc
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/percentagecalc = 1
if (polltype != POLLTYPE_IRV)
switch(alert("Calculate option results as percentage?",,"Yes","No","Cancel"))
if("Yes")
percentagecalc = 1
if("No")
percentagecalc = 0
else
return pollid
var/minval = 0
var/maxval = 0
var/descmin = ""
@@ -152,9 +165,11 @@
var/err = query_polladd_option.ErrorMsg()
log_game("SQL ERROR adding new poll option to table. Error : \[[err]\]\n")
return pollid
switch(alert(" ",,"Add option","Finish"))
switch(alert(" ",,"Add option","Finish", "Cancel"))
if("Add option")
add_option = 1
if("Finish")
add_option = 0
else
return 0
return pollid
+72 -5
View File
@@ -51,17 +51,16 @@
bodies += M
var/question = "Would you like to be [group_name]?"
var/list/candidates = pollCandidates(question, "pAI", null, FALSE, 100)
var/list/candidates = pollCandidatesForMobs(question, "pAI", null, FALSE, 100, bodies)
while(candidates.len && bodies.len)
var/mob/dead/observer/ghost = pick_n_take(candidates)
var/mob/living/body = pick_n_take(bodies)
body << "Your mob has been taken over by a ghost!"
message_admins("[key_name_admin(ghost)] has taken control \
of ([key_name_admin(body)])")
message_admins("[key_name_admin(ghost)] has taken control of ([key_name_admin(body)])")
body.ghostize(0)
body.key = ghost.key
PoolOrNew(/obj/effect/overlay/temp/sparkle, body)
new /obj/effect/overlay/temp/gravpush(get_turf(body))
/obj/effect/fun_balloon/sentience/emergency_shuttle
name = "shuttle sentience fun balloon"
@@ -80,6 +79,74 @@
/obj/effect/fun_balloon/scatter/effect()
for(var/mob/living/M in range(effect_range, get_turf(src)))
var/turf/T = find_safe_turf()
PoolOrNew(/obj/effect/overlay/temp/sparkle, M)
new /obj/effect/overlay/temp/gravpush(get_turf(M))
M.forceMove(T)
M << "<span class='notice'>Pop!</span>"
/obj/effect/station_crash
name = "station crash"
desc = "With no survivors!"
icon = 'icons/obj/weapons.dmi'
icon_state = "syndballoon"
anchored = TRUE
/obj/effect/station_crash/New()
for(var/S in SSshuttle.stationary)
var/obj/docking_port/stationary/SM = S
if(SM.id == "emergency_home")
var/new_dir = turn(SM.dir, 180)
SM.loc = get_ranged_target_turf(SM, new_dir, rand(3,15))
break
qdel(src)
//Luxury Shuttle Blockers
/obj/effect/forcefield/luxury_shuttle
var/threshhold = 500
var/list/approved_passengers = list()
/obj/effect/forcefield/luxury_shuttle/CanPass(atom/movable/mover, turf/target, height=0)
if(mover in approved_passengers)
return 1
if(!isliving(mover)) //No stowaways
return 0
var/total_cash = 0
var/list/counted_money = list()
for(var/obj/item/weapon/coin/C in mover)
total_cash += C.value
counted_money += C
if(total_cash >= threshhold)
break
for(var/obj/item/stack/spacecash/S in mover)
total_cash += S.value * S.amount
counted_money += S
if(total_cash >= threshhold)
break
if(total_cash >= threshhold)
for(var/obj/I in counted_money)
qdel(I)
mover << "Thank you for your payment! Please enjoy your flight."
approved_passengers += mover
return 1
else
mover << "You don't have enough money to enter the main shuttle. You'll have to fly coach."
return 0
//Shuttle Build
/obj/effect/shuttle_build
name = "shuttle_build"
desc = "Some assembly required"
icon = 'icons/obj/weapons.dmi'
icon_state = "syndballoon"
anchored = TRUE
/obj/effect/shuttle_build/New()
SSshuttle.emergency.dock(SSshuttle.getDock("emergency_home"))
qdel(src)
+5 -1
View File
@@ -5,6 +5,7 @@ var/list/admin_datums = list()
var/client/owner = null
var/fakekey = null
var/following = null
var/datum/marked_datum
@@ -56,13 +57,16 @@ var/list/admin_datums = list()
return 1 //we have all the rights they have and more
return 0
/datum/admins/vv_edit_var(var_name, var_value)
return FALSE //nice try trialmin
/*
checks if usr is an admin with at least ONE of the flags in rights_required. (Note, they don't need all the flags)
if rights_required == 0, then it simply checks if they are an admin.
if it doesn't return 1 and show_msg=1 it will prints a message explaining why the check has failed
generally it would be used like so:
proc/admin_proc()
/proc/admin_proc()
if(!check_rights(R_ADMIN)) return
world << "you have enough rights!"
+3 -3
View File
@@ -53,9 +53,9 @@
if (query.NextRow())
res.cache = TRUE
res.cachedate = query.item[1]
res.intel = query.item[2]
res.cacheminutesago = query.item[3]
res.cacherealtime = world.realtime - (query.item[3]*10*60)
res.intel = text2num(query.item[2])
res.cacheminutesago = text2num(query.item[3])
res.cacherealtime = world.realtime - (text2num(query.item[3])*10*60)
SSipintel.cache[ip] = res
return
res.intel = ip_intel_query(ip)
+22 -82
View File
@@ -244,7 +244,7 @@
M_job = "AI"
else if(ispAI(M))
M_job = "pAI"
else if(isrobot(M))
else if(iscyborg(M))
M_job = "Cyborg"
else
M_job = "Silicon-based"
@@ -260,7 +260,7 @@
else
M_job = "Living"
else if(istype(M,/mob/new_player))
else if(isnewplayer(M))
M_job = "New player"
else if(isobserver(M))
@@ -346,7 +346,7 @@
for(var/datum/mind/N in ticker.mode.syndicates)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -356,11 +356,11 @@
for(var/obj/item/weapon/disk/nuclear/N in poi_list)
dat += "<tr><td>[N.name], "
var/atom/disk_loc = N.loc
while(!istype(disk_loc, /turf))
if(istype(disk_loc, /mob))
while(!isturf(disk_loc))
if(ismob(disk_loc))
var/mob/M = disk_loc
dat += "carried by <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> "
if(istype(disk_loc, /obj))
if(isobj(disk_loc))
var/obj/O = disk_loc
dat += "in \a [O.name] "
disk_loc = disk_loc.loc
@@ -375,20 +375,20 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Head Revolutionary body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Leader)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in ticker.mode.revolutionaries)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table><table cellspacing=5><tr><td><B>Target(s)</B></td><td></td><td><B>Location</B></td></tr>"
for(var/datum/mind/N in ticker.mode.get_living_heads())
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
var/turf/mob_loc = get_turf(M)
@@ -406,13 +406,13 @@
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Gang Boss body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
else
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a> <b>(Boss)</b>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
for(var/datum/mind/N in G.gangsters)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td></tr>"
dat += "</table>"
@@ -421,7 +421,7 @@
for(var/datum/mind/changeling in ticker.mode.changelings)
var/mob/M = changeling.current
if(M)
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td>[M.mind.changeling.changelingID] as <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -435,7 +435,7 @@
for(var/datum/mind/wizard in ticker.mode.wizards)
var/mob/M = wizard.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -449,7 +449,7 @@
for(var/datum/mind/apprentice in ticker.mode.apprentices)
var/mob/M = apprentice.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -463,7 +463,7 @@
for(var/datum/mind/N in ticker.mode.cult)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
@@ -478,72 +478,12 @@
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deities.len || ticker.mode.red_deity_prophets.len || ticker.mode.blue_deity_prophets.len || ticker.mode.red_deity_followers.len || ticker.mode.blue_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deities.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deities)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deity_prophets.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity Prophets</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deity_prophets.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity Prophets</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deity_prophets)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Prophet: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.red_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Red Deity Followers</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.red_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Red Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.blue_deity_followers.len)
dat += "<br><table cellspacing=5><tr><td><B>Blue Deity Followers</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.blue_deity_followers)
var/mob/M = N.current
if(M)
dat += "<tr><td>Blue Deity Followers: <a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.traitors.len > 0)
dat += "<br><table cellspacing=5><tr><td><B>Traitors</B></td><td></td><td></td></tr>"
for(var/datum/mind/traitor in ticker.mode.traitors)
var/mob/M = traitor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -557,7 +497,7 @@
for(var/datum/mind/abductor in ticker.mode.abductors)
var/mob/M = abductor.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -570,7 +510,7 @@
for(var/datum/mind/abductee in E.abductee_minds)
var/mob/M = abductee.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
@@ -585,7 +525,7 @@
var/datum/mind/devil = X
var/mob/M = devil.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name] : [devil.devilinfo.truename]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
dat += "<td><A HREF='?_src_=holder;admincheckdevilinfo=\ref[M]'>Show all devil info</A></td></tr>"
@@ -600,7 +540,7 @@
var/datum/mind/sintouched = X
var/mob/M = sintouched.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A HREF='?_src_=holder;traitor=\ref[M]'>Show Objective</A></td></tr>"
else
@@ -622,7 +562,7 @@
for(var/datum/mind/blob in blob_minds)
var/mob/M = blob.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
@@ -638,7 +578,7 @@
for(var/datum/mind/eek in mode.ape_infectees)
var/mob/M = eek.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(No Client)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
+20 -2
View File
@@ -9,6 +9,9 @@
<A href='?src=\ref[src];secrets=list_job_debug'>Show Job Debug</A><BR>
<A href='?src=\ref[src];secrets=admin_log'>Admin Log</A><BR>
<A href='?src=\ref[src];secrets=show_admins'>Show Admin List</A><BR>
<A href='?src=\ref[src];secrets=mentor_log'>Mentor Log</A><BR>
<A href='?src=\ref[src];secrets=show_current_watchlist'>Show online players in the watchlist</A><BR>
<BR>
"}
@@ -99,6 +102,14 @@
dat += "No-one has done anything this round!"
usr << browse(dat, "window=admin_log")
if("mentor_log")
var/dat = "<B>Mentor Log<HR></B>"
for(var/l in mentor_log)
dat += "<li>[l]</li>"
if(!mentor_log.len)
dat += "No mentors have done anything this round!"
usr << browse(dat, "window=mentor_log")
if("list_job_debug")
var/dat = "<B>Job Debug info.</B><HR>"
if(SSjob)
@@ -119,6 +130,13 @@
dat += "[ckey] - [D.rank.name]<br>"
usr << browse(dat, "window=showadmins;size=600x500")
if("show_current_watchlist")
var/dat = "<B>Watchlist: </B><HR>"
if(current_watchlist)
for(var/ckey in current_watchlist)
dat += "[ckey] - [current_watchlist[ckey]]"
usr << browse(dat, "window=showcurrentwatchlist;size=600x500")
if("tdomereset")
if(!check_rights(R_ADMIN))
return
@@ -389,7 +407,7 @@
feedback_add_details("admin_secrets_fun_used","BO")
message_admins("[key_name_admin(usr)] broke all lights")
for(var/obj/machinery/light/L in machines)
L.broken()
L.break_light_tube()
if("anime")
if(!check_rights(R_FUN))
@@ -411,7 +429,7 @@
var/forename = names.len > 1 ? names[2] : names[1]
var/newname = "[forename]-[pick(honorifics["[H.gender]"])]"
H.fully_replace_character_name(H.real_name,newname)
H.unEquip(H.w_uniform)
H.temporarilyRemoveItemFromInventory(H.w_uniform, TRUE)
H.equip_to_slot_or_del(I, slot_w_uniform)
I.flags |= NODROP
else
+59 -16
View File
@@ -1,4 +1,4 @@
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server)
/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server, secret)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
@@ -13,12 +13,12 @@
log_game("SQL ERROR obtaining ckey from player table. Error : \[[err]\]\n")
return
if(!query_find_ckey.NextRow())
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add them to the watchlist?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
if(alert(usr, "[new_ckey] has not been seen before, are you sure you want to add a note for them?", "Unknown ckey", "Yes", "No", "Cancel") != "Yes")
return
target_ckey = new_ckey
var/target_sql_ckey = sanitizeSQL(target_ckey)
if(!notetext)
notetext = input(usr,"Write your Note","Add Note") as message
notetext = input(usr,"Write your Note","Add Note") as null|message
if(!notetext)
return
notetext = sanitizeSQL(notetext)
@@ -33,7 +33,15 @@
if (config && config.server_name)
server = config.server_name
server = sanitizeSQL(server)
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')")
if(isnull(secret))
switch(alert("Hide note from being viewed by players?", "Secret Note?","Yes","No","Cancel"))
if("Yes")
secret = 1
if("No")
secret = 0
else
return
var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, secret) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]', '[secret]')")
if(!query_noteadd.Execute())
var/err = query_noteadd.ErrorMsg()
log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n")
@@ -89,7 +97,7 @@
target_ckey = query_find_note_edit.item[1]
var/old_note = query_find_note_edit.item[2]
var/adminckey = query_find_note_edit.item[3]
var/new_note = input("Input new note", "New Note", "[old_note]") as message
var/new_note = input("Input new note", "New Note", "[old_note]") as null|message
if(!new_note)
return
new_note = sanitizeSQL(new_note)
@@ -104,12 +112,40 @@
message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from<br>[old_note]<br>to<br>[new_note]")
show_note(target_ckey)
/proc/toggle_note_secrecy(note_id)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
if(!note_id)
return
note_id = text2num(note_id)
var/DBQuery/query_find_note_secret = dbcon.NewQuery("SELECT ckey, adminckey, secret FROM [format_table_name("notes")] WHERE id = [note_id]")
if(!query_find_note_secret.Execute())
var/err = query_find_note_secret.ErrorMsg()
log_game("SQL ERROR obtaining ckey, adminckey, secret from notes table. Error : \[[err]\]\n")
return
if(query_find_note_secret.NextRow())
var/target_ckey = query_find_note_secret.item[1]
var/adminckey = query_find_note_secret.item[2]
var/secret = text2num(query_find_note_secret.item[3])
var/sql_ckey = sanitizeSQL(usr.ckey)
var/edit_text = "Made [secret ? "not secret" : "secret"] by [sql_ckey] on [SQLtime()]<hr>"
var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET secret = NOT secret, last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]")
if(!query_update_note.Execute())
var/err = query_update_note.ErrorMsg()
log_game("SQL ERROR toggling note secrecy. Error : \[[err]\]\n")
return
log_admin("[key_name(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
message_admins("[key_name_admin(usr)] has toggled [target_ckey]'s note made by [adminckey] to [secret ? "not secret" : "secret"]")
show_note(target_ckey)
/proc/show_note(target_ckey, index, linkless = 0)
if(!dbcon.IsConnected())
usr << "<span class='danger'>Failed to establish database connection.</span>"
return
var/output
var/navbar
var/ruler
ruler = "<hr style='background:#000000; border:0; height:3px'>"
navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
var/ruler = "<hr style='background:#000000; border:0; height:3px'>"
var/navbar = "<a href='?_src_=holder;nonalpha=1'>\[All\]</a>|<a href='?_src_=holder;nonalpha=2'>\[#\]</a>"
for(var/letter in alphabet)
navbar += "|<a href='?_src_=holder;shownote=[letter]'>\[[letter]\]</a>"
navbar += "<br><form method='GET' name='search' action='?'>\
@@ -120,25 +156,32 @@
output = navbar
if(target_ckey)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT secret, timestamp, notetext, adminckey, last_editor, server, id FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp")
if(!query_get_notes.Execute())
var/err = query_get_notes.ErrorMsg()
log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n")
usr << "<span class='danger'>SQL ERROR: Failed to obtain DB records. Error : \[[err]\]\</span>"
log_game("SQL ERROR obtaining secret, timestamp, notetext, adminckey, last_editor, server, id from notes table. Error : \[[err]\]\n")
return
output += "<h2><center>Notes of [target_ckey]</center></h2>"
if(!linkless)
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a></center>"
output += "<center><a href='?_src_=holder;addnote=[target_ckey]'>\[Add Note\]</a>"
output += " <a href='?_src_=holder;shownoteckey=[target_ckey]'>\[Refresh Page\]</a></center>"
else
output += " <a href='?_src_=holder;shownoteckeylinkless=[target_ckey]'>\[Refresh Page\]</a></center>"
output += ruler
while(query_get_notes.NextRow())
var/id = query_get_notes.item[1]
var/secret = text2num(query_get_notes.item[1])
if(linkless && secret)
continue
var/timestamp = query_get_notes.item[2]
var/notetext = query_get_notes.item[3]
var/adminckey = query_get_notes.item[4]
var/last_editor = query_get_notes.item[5]
var/server = query_get_notes.item[6]
var/id = query_get_notes.item[7]
output += "<b>[timestamp] | [server] | [adminckey]</b>"
if(!linkless)
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
output += " <a href='?_src_=holder;removenote=[id]'>\[Remove Note\]</a> <a href='?_src_=holder;secretnote=[id]'>[secret ? "<b>\[Secret\]</b>" : "\[Not Secret\]"]</a> <a href='?_src_=holder;editnote=[id]'>\[Edit Note\]</a>"
if(last_editor)
output += " <font size='2'>Last edit by [last_editor] <a href='?_src_=holder;noteedits=[id]'>(Click here to see edit log)</a></font>"
output += "<br>[notetext]<hr style='background:#000000; border:0; height:1px'>"
@@ -196,7 +239,7 @@
if(query_convert_time.NextRow())
timestamp = query_convert_time.item[1]
if(ckey && notetext && timestamp && adminckey && server)
add_note(ckey, notetext, timestamp, adminckey, 0, server)
add_note(ckey, notetext, timestamp, adminckey, 0, server, 1)
notesfile.cd = "/"
notesfile.dir.Remove(ckey)
@@ -214,4 +257,4 @@ this proc can take several minutes to execute fully if converting and cause DD t
world << "Deleting NOTESFILE"
fdel(NOTESFILE)
world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/
#undef NOTESFILE
#undef NOTESFILE
+51 -7
View File
@@ -18,6 +18,8 @@
if (!ckey)
return
ckey = ckey(ckey)
ban["ckey"] = ckey
if (get_stickyban_from_ckey(ckey))
usr << "<span class='adminnotice'>Error: Can not add a stickyban: User already has a current sticky ban</span>"
@@ -125,9 +127,37 @@
log_admin("[key_name(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has edited [ckey]'s sticky ban reason from [oldreason] to [reason]</span>")
if ("revert")
if (!data["ckey"])
return
var/ckey = data["ckey"]
if (alert("Are you sure you want to revert the sticky ban on [ckey] to its state at round start?","Are you sure","Yes","No") == "No")
return
var/ban = get_stickyban_from_ckey(ckey)
if (!ban)
usr << "<span class='adminnotice'>Error: No sticky ban for [ckey] found!"
return
var/cached_ban = SSstickyban.cache[ckey]
if (!cached_ban)
usr << "<span class='adminnotice'>Error: No cached sticky ban for [ckey] found!"
world.SetConfig("ban",ckey,null)
log_admin("[key_name(usr)] has reverted [ckey]'s sticky ban to it's state at round start.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] has reverted [ckey]'s sticky ban to it's state at round start.</span>")
//revert is mostly used when shit goes rouge, so we have to set it to null
// and wait a byond tick before assigning it to ensure byond clears its shit.
sleep(world.tick_lag)
world.SetConfig("ban",ckey,list2stickyban(cached_ban))
/datum/admins/proc/stickyban_gethtml(ckey, ban)
. = "<a href='?_src_=holder;stickyban=remove&ckey=[ckey]'>\[-\]</a><b>[ckey]</b><br />"
. += "[ban["message"]] <b><a href='?_src_=holder;stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />"
. = {"
<a href='?_src_=holder;stickyban=remove&ckey=[ckey]'>\[-\]</a>
<a href='?_src_=holder;stickyban=revert&ckey=[ckey]'>\[revert\]</a>
<b>[ckey]</b>
<br />"
[ban["message"]] <b><a href='?_src_=holder;stickyban=edit&ckey=[ckey]'>\[Edit\]</a></b><br />
"}
if (ban["admin"])
. += "[ban["admin"]]<br />"
else
@@ -175,7 +205,13 @@
if (!ban)
return null
. = params2list(ban)
.["keys"] = splittext(.["keys"], ",")
if (.["keys"])
var/keys = splittext(.["keys"], ",")
var/ckeys = list()
for (var/key in keys)
var/ckey = ckey(key)
ckeys[ckey] = ckey //to make searching faster.
.["keys"] = ckeys
.["type"] = splittext(.["type"], ",")
.["IP"] = splittext(.["IP"], ",")
.["computer_id"] = splittext(.["computer_id"], ",")
@@ -189,10 +225,18 @@
.["keys"] = jointext(.["keys"], ",")
if (.["type"])
.["type"] = jointext(.["type"], ",")
if (.["IP"])
.["IP"] = jointext(.["IP"], ",")
if (.["computer_id"])
.["computer_id"] = jointext(.["computer_id"], ",")
//internal tracking only, shouldn't be stored
. -= "existing_user_matches_this_round"
. -= "admin_matches_this_round"
. -= "matches_this_round"
. -= "reverting"
//storing these can sometimes cause sticky bans to start matching everybody
// and isn't even needed for sticky ban matching, as the hub tracks these seperately
. -= "IP"
. -= "computer_id"
. = list2params(.)
File diff suppressed because it is too large Load Diff
+27 -20
View File
@@ -121,6 +121,7 @@
else
text += ": [t]<br>"
CHECK_TICK
usr << browse(text, "window=SDQL-result")
@@ -134,7 +135,7 @@
vals += v
vals[v] = SDQL_expression(d, set_list[v])
if(istype(d, /turf))
if(isturf(d))
for(var/v in vals)
if(v == "x" || v == "y" || v == "z")
continue
@@ -246,42 +247,48 @@
return out
type = text2path(type)
var/typecache = typecacheof(type)
if(ispath(type, /mob))
for(var/mob/d in location)
if(istype(d, type))
if(typecache[d.type])
out += d
CHECK_TICK
else if(ispath(type, /turf))
for(var/turf/d in location)
if(istype(d, type))
if(typecache[d.type])
out += d
CHECK_TICK
else if(ispath(type, /obj))
for(var/obj/d in location)
if(istype(d, type))
if(typecache[d.type])
out += d
CHECK_TICK
else if(ispath(type, /area))
for(var/area/d in location)
if(istype(d, type))
if(typecache[d.type])
out += d
CHECK_TICK
else if(ispath(type, /atom))
for(var/atom/d in location)
if(istype(d, type))
out += d
CHECK_TICK
else
for(var/datum/d in location)
if(istype(d, type))
if(typecache[d.type])
out += d
CHECK_TICK
else if(ispath(type, /datum))
if(location == world) //snowflake for byond shortcut
for(var/datum/d) //stupid byond trick to have it not return atoms to make this less laggy
if(typecache[d.type])
out += d
CHECK_TICK
else
for(var/datum/d in location)
if(typecache[d.type])
out += d
CHECK_TICK
return out
@@ -304,19 +311,19 @@
if(op != "")
switch(op)
if("+")
result += val
result = (result + val)
if("-")
result -= val
result = (result - val)
if("*")
result *= val
result = (result * val)
if("/")
result /= val
result = (result / val)
if("&")
result &= val
result = (result & val)
if("|")
result |= val
result = (result | val)
if("^")
result ^= val
result = (result ^ val)
if("=", "==")
result = (result == val)
if("!=", "<>")
+83 -47
View File
@@ -12,8 +12,7 @@
var/list/ckeys = list()
for(var/mob/M in mob_list)
var/list/indexing = list(M.real_name, M.name)
if(M.mind)
indexing += M.mind.name
if(M.mind) indexing += M.mind.name
for(var/string in indexing)
var/list/L = splittext(string, " ")
@@ -53,10 +52,7 @@
mobs_found += found
if(!ai_found && isAI(found))
ai_found = 1
var/is_antag = 0
if(found.mind && found.mind.special_role)
is_antag = 1
msg += "[original_word]<font size='1' color='[is_antag ? "red" : "black"]'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
msg += "[original_word]<font size='1' color='black'>(<A HREF='?_src_=holder;adminmoreinfo=\ref[found]'>?</A>|<A HREF='?_src_=holder;adminplayerobservefollow=\ref[found]'>F</A>)</font> "
continue
msg += "[original_word] "
return msg
@@ -82,7 +78,6 @@
return
if(src.handle_spam_prevention(msg,MUTE_ADMINHELP))
return
var/ref_mob = "\ref[mob]"
for(var/datum/adminticket/T in admintickets)
if(T.permckey == src.ckey && T.resolved == "No")
@@ -91,7 +86,7 @@
if(T.admin == "N/A")
usr << "<b>Due to the fact your Adminhelp had no assigned admin, admins have been pinged.</b>"
message_admins("[src.ckey] has bumped their adminhelp #[T.ID], still no assigned admin!")
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[T];resolve=\ref[T]'>R</a>):</b> [T.msg]</span>"
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[T];resolve=\ref[T]'>R</a>) (<A HREF='?_src_=holder;rejectadminhelp=[ref_mob]'>REJT</A>):</b> [T.msg]</span>"
for(var/client/X in admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
@@ -100,13 +95,13 @@
usr << "<b>Admins have been notified.</b>"
message_admins("[src.ckey] has bumped their adminhelp #[T.ID].")
src.verbs -= /client/verb/adminhelp
adminhelptimerid = addtimer(src,"giveadminhelpverb",1200, FALSE)
adminhelptimerid = addtimer(CALLBACK(src, .proc/giveadminhelpverb), 1200, TIMER_STOPPABLE) //2 minute cooldown of admin helps
return
usr << "<b>Thank you for your patience.</b>"
return
src.verbs -= /client/verb/adminhelp
adminhelptimerid = addtimer(src,"giveadminhelpverb",1200, FALSE)
adminhelptimerid = addtimer(CALLBACK(src, .proc/giveadminhelpverb), 1200, TIMER_STOPPABLE)
//clean the input msg
if(!msg) return
@@ -119,6 +114,7 @@
if(!mob) return //this doesn't happen
createticket(src, msg, src.ckey, mob)
var/datum/adminticket/ticket
for(var/datum/adminticket/T in admintickets)
@@ -127,62 +123,102 @@
msg = "<span class='adminnotice'><b><font color=red>ADMINHELP: </font><A HREF='?priv_msg=[ckey];ahelp_reply=1'>[key_name(src)]</A> (<A HREF='?_src_=holder;adminmoreinfo=[ref_mob]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=[ref_mob]'>PP</A>) (<A HREF='?_src_=vars;Vars=[ref_mob]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=[ref_mob]'>SM</A>) (<A HREF='?_src_=holder;traitor=[ref_mob]'>TP</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=[ref_mob]'>FLW</A>) (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>):</b> [msg]</span>"
//send this msg to all admins
for(var/client/X in admins)
if(X.prefs.toggles & SOUND_ADMINHELP)
X << 'sound/effects/adminhelp.ogg'
window_flash(X)
X << msg
//show it to the person adminhelping too
src << "<span class='adminnotice'>PM to-<b>Admins</b>: [original_msg]</span>"
//send it to irc if nobody is on and tell us how many were on
var/admin_number_present = send2irc_adminless_only(ckey,original_msg)
log_admin("HELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
var/admin_number_present = send2irc_admin_notice_handler("adminhelp", ckey, original_msg)
log_admin("ADMINHELP: [key_name(src)]: [original_msg] - heard by [admin_number_present] non-AFK admins who have +BAN.")
feedback_add_details("admin_verb","AH") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
return
/proc/get_admin_counts(requiredflags = R_BAN)
. = list("total" = 0, "noflags" = 0, "afk" = 0, "stealth" = 0, "present" = 0)
/proc/calculate_admins(type, requiredflags = R_BAN)
var/admin_number_total = 0 //Total number of admins
var/admin_number_afk = 0 //Holds the number of admins who are afk
var/admin_number_ignored = 0 //Holds the number of admins without +BAN (so admins who are not really admins)
var/admin_number_decrease = 0 //Holds the number of admins with are afk, ignored or both
for(var/client/X in admins)
.["total"]++
admin_number_total++;
var/invalid = 0
if(requiredflags != 0 && !check_rights_for(X, requiredflags))
.["noflags"]++
else if(X.is_afk())
.["afk"]++
else if(X.holder.fakekey)
.["stealth"]++
else
.["present"]++
admin_number_ignored++
invalid = 1
if(X.is_afk())
admin_number_afk++
invalid = 1
if(X.holder.fakekey)
admin_number_ignored++
invalid = 1
if(invalid)
admin_number_decrease++
switch(type)
if("ignored")
return admin_number_ignored
if("total")
return admin_number_total
if("away")
return admin_number_afk
if("present")
return admin_number_total - admin_number_decrease
return 0
/proc/send2irc_adminless_only(source, msg, requiredflags = R_BAN)
var/list/adm = get_admin_counts(requiredflags)
. = adm["present"]
if(. <= 0)
var/final = ""
if(!adm["afk"] && !adm["stealth"] && !adm["noflags"])
final = "[msg] - No admins online"
else
final = "[msg] - All admins AFK ([adm["afk"]]/[adm["total"]]), stealthminned ([adm["stealth"]]/[adm["total"]]), or lack[rights2text(requiredflags, " ")] ([adm["noflags"]]/[adm["total"]])"
send2irc(source,final)
send2otherserver(source,final)
/proc/send2irc_admin_notice_handler(type, source, msg)
var/afk_admins = calculate_admins("away")
var/total_admins = calculate_admins("total")
var/ignored_admins = calculate_admins("ignored")
var/admin_number_present = calculate_admins("present") //Number of admins who are neither afk nor invalid
var/irc_message_afk = "[msg] - All admins AFK ([afk_admins]/[total_admins]) or skipped ([ignored_admins]/[total_admins])"
var/irc_message_normal = "[msg] - heard by [admin_number_present] non-AFK admins who have +BAN."
var/irc_message_adminless = "[msg] - No admins online"
switch(type)
if("adminhelp")
if(config.announce_adminhelps)
send2irc(source, irc_message_normal)
else
if(admin_number_present <= 0)
if(!afk_admins && !ignored_admins)
send2admindiscord(source, irc_message_adminless)
else if(afk_admins >= 1)
send2admindiscord(source, irc_message_afk)
else
send2admindiscord(source, irc_message_normal)
if("watchlist")
if(config.announce_watchlist)
send2irc(source, irc_message_normal)
else
if(admin_number_present <= 0)
if(!afk_admins && !ignored_admins)
send2admindiscord(source, irc_message_adminless)
else if(afk_admins >= 1)
send2admindiscord(source, irc_message_afk)
else
send2admindiscord(source, irc_message_normal)
if("new_player")
if(config.irc_first_connection_alert)
send2irc(source, irc_message_normal)
else
if(admin_number_present <= 0)
if(!afk_admins && !ignored_admins)
send2admindiscord(source, irc_message_adminless)
else if(afk_admins >= 1)
send2admindiscord(source, irc_message_afk)
else
send2admindiscord(source, irc_message_normal)
return admin_number_present
/proc/send2irc(msg,msg2)
if(config.useircbot)
shell("python nudge.py [msg] [msg2]")
return
/proc/send2otherserver(source,msg,type = "Ahelp")
if(global.cross_allowed)
var/list/message = list()
message["message_sender"] = source
message["message"] = msg
message["source"] = "([config.cross_name])"
message["key"] = global.comms_key
message["crossmessage"] = type
world.Export("[global.cross_address]?[list2params(message)]")
shell("python nudge.py [msg] \"[msg2]\"")
return
+41 -34
View File
@@ -5,8 +5,7 @@
if(!holder)
src << "<font color='red'>Error: Admin-PM-Context: Only administrators may use this command.</font>"
return
if( !ismob(M) || !M.client )
return
if( !ismob(M) || !M.client ) return
cmd_admin_pm(M.client,null)
feedback_add_details("admin_verb","APMM") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
@@ -45,9 +44,9 @@
else if(istype(whom,/client))
C = whom
if(!C)
if(holder)
src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
return
var/datum/adminticket/ticket
for(var/datum/adminticket/T in admintickets)
@@ -105,23 +104,18 @@
else if(istype(whom,/client))
C = whom
if(!C)
if(holder)
src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else
adminhelp(msg) //admin we are replying to left. adminhelp instead
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else adminhelp(msg) //admin we are replying to left. adminhelp instead
return
//get message text, limit it's length.and clean/escape html
if(!msg)
msg = input(src,"Message:", "Private message to [key_name(C, 0, 0)]") as text|null
if(!msg)
return
if(!msg) return
if(!C)
if(holder)
src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else
adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
if(holder) src << "<font color='red'>Error: Admin-PM: Client not found.</font>"
else adminhelp(msg) //admin we are replying to has vanished, adminhelp instead
return
if (src.handle_spam_prevention(msg,MUTE_ADMINHELP))
@@ -130,28 +124,37 @@
//clean the message if it's not sent by a high-rank admin
if(!check_rights(R_SERVER|R_DEBUG,0))
msg = sanitize(copytext(msg,1,MAX_MESSAGE_LEN))
if(!msg)
return
var/rawmsg = msg
if(holder)
msg = emoji_parse(msg)
if(!msg) return
msg = emoji_parse(msg)
var/keywordparsedmsg = keywords_lookup(msg)
var/datum/adminticket/ticket
if(C.holder)
if(holder) //both are admins
for(var/datum/adminticket/T in admintickets)
if(T.permckey == C.ckey && T.resolved == "No")
if(T.permckey == src.ckey && T.resolved == "No")
T.logs += "<span class='notice'>[src] TO [C]: [msg] </span>"
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [keywordparsedmsg]</font>"
ticket = T
else if(T.permckey == src.ckey)
ticket = T
if(ticket && ticket.resolved == "No")
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg] (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>)</font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [keywordparsedmsg] (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>)</font>"
else
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [keywordparsedmsg]</font>"
else //recipient is an admin but sender is not
for(var/datum/adminticket/T in admintickets)
if(T.permckey == C.ckey && T.resolved == "No")
if(T.permckey == src.ckey && T.resolved == "No")
T.logs += "<span class='notice'>[src] TO [C]: [msg] </span>"
C << "<font color='red'>Reply PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>"
ticket = T
else if(T.permckey == src.ckey)
ticket = T
if(ticket && ticket.resolved == "No")
C << "<font color='red'>Reply PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg] (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>)</font>"
else
C << "<font color='red'>Reply PM from-<b>[key_name(src, C, 1)]</b>: [keywordparsedmsg]</font>"
src << "<font color='blue'>PM to-<b>Admins</b>: [msg]</font>"
//play the recieving admin the adminhelp sound (if they have them enabled)
@@ -160,16 +163,20 @@
else
if(holder) //sender is an admin but recipient is not. Do BIG RED TEXT
for(var/datum/adminticket/T in admintickets)
if(T.permckey == C.ckey && T.resolved == "No")
T.logs += "<span class='notice'>[src] TO [C]: [msg] </span>"
ticket = T
else if(T.permckey == C.ckey)
ticket = T
C << "<font color='red' size='4'><b>-- Administrator private message --</b></font>"
C << "<font color='red'>Admin PM from-<b>[key_name(src, C, 0)]</b>: [msg]</font>"
C << "<font color='red'><i>Click on the administrator's name to reply.</i></font>"
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
for(var/datum/adminticket/T in admintickets)
if(T.permckey == C.ckey && T.resolved == "No")
T.logs += "<span class='notice'>[src] TO [C]: [msg] </span>"
if(ticket && ticket.resolved == "No")
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg] (<a href='?src=\ref[ticket];resolve=\ref[ticket]'>R</a>)</font>"
else
src << "<font color='blue'>Admin PM to-<b>[key_name(C, src, 1)]</b>: [msg]</font>"
//always play non-admin recipients the adminhelp sound
C << 'sound/effects/adminhelp.ogg'
@@ -193,9 +200,9 @@
src << "<font color='red'>Error: Admin-PM: Non-admin to non-admin PM communication is forbidden.</font>"
return
log_admin("PM: [key_name(src)]->[key_name(C)]: [rawmsg]")
log_admin("PM: [key_name(src)]->[key_name(C)]: [msg]")
//we don't use message_admins here because the sender/receiver might get it too
for(var/client/X in admins)
if(X.key!=key && X.key!=C.key) //check client/X is an admin and isn't the sender or recipient
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]-&gt;[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]-&gt;[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
+2 -2
View File
@@ -24,8 +24,8 @@
T.break_tile()
target << "<span class='userdanger'>You're hit by bluespace artillery!</span>"
log_admin("[target.name] has been hit by Bluespace Artillery fired by [usr]")
message_admins("[target.name] has been hit by Bluespace Artillery fired by [usr]")
log_admin("[key_name(target)] has been hit by Bluespace Artillery fired by [key_name(usr)]")
message_admins("[ADMIN_LOOKUPFLW(target)] has been hit by Bluespace Artillery fired by [ADMIN_LOOKUPFLW(usr)]")
if(target.health <= 1)
target.gib(1, 1)
+9 -9
View File
@@ -242,34 +242,34 @@
. = 1
switch(mode)
if(BASIC_BUILDMODE)
if(istype(object,/turf) && left_click && !alt_click && !ctrl_click)
if(isturf(object) && left_click && !alt_click && !ctrl_click)
var/turf/T = object
if(istype(object,/turf/open/space))
if(isspaceturf(object))
T.ChangeTurf(/turf/open/floor/plasteel)
else if(istype(object,/turf/open/floor))
else if(isfloorturf(object))
T.ChangeTurf(/turf/closed/wall)
else if(istype(object,/turf/closed/wall))
else if(iswallturf(object))
T.ChangeTurf(/turf/closed/wall/r_wall)
log_admin("Build Mode: [key_name(user)] built [T] at ([T.x],[T.y],[T.z])")
return
else if(right_click)
log_admin("Build Mode: [key_name(user)] deleted [object] at ([object.x],[object.y],[object.z])")
if(istype(object,/turf/closed/wall))
if(iswallturf(object))
var/turf/T = object
T.ChangeTurf(/turf/open/floor/plasteel)
else if(istype(object,/turf/open/floor))
else if(isfloorturf(object))
var/turf/T = object
T.ChangeTurf(/turf/open/space)
else if(istype(object,/turf/closed/wall/r_wall))
var/turf/T = object
T.ChangeTurf(/turf/closed/wall)
else if(istype(object,/obj))
else if(isobj(object))
qdel(object)
return
else if(istype(object,/turf) && alt_click && left_click)
else if(isturf(object) && alt_click && left_click)
log_admin("Build Mode: [key_name(user)] built an airlock at ([object.x],[object.y],[object.z])")
new/obj/machinery/door/airlock(get_turf(object))
else if(istype(object,/turf) && ctrl_click && left_click)
else if(isturf(object) && ctrl_click && left_click)
switch(build_dir)
if(NORTH)
var/obj/structure/window/reinforced/WIN = new/obj/structure/window/reinforced(get_turf(object))
+1 -1
View File
@@ -24,7 +24,7 @@
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>ADMIN([src.holder.fakekey ? pick(nicknames) : src.key])</span> says, <span class='message'>\"[msg]\"</span></span>"
for (var/mob/M in player_list)
if (istype(M, /mob/new_player))
if(isnewplayer(M))
continue
if (M.stat == DEAD || (M.client && M.client.holder && (M.client.prefs.chat_toggles & CHAT_DEAD))) //admins can toggle deadchat on and off. This is a proc in admin.dm and is only give to Administrators and above
M.show_message(rendered, 2)
+105 -116
View File
@@ -33,36 +33,17 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!check_rights(R_DEBUG)) return
var/target = null
var/datum/target = null
var/targetselected = 0
var/returnval = null
var/class = null
switch(alert("Proc owned by something?",,"Yes","No"))
if("Yes")
targetselected = 1
if(src.holder && src.holder.marked_datum)
class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client","Marked datum ([holder.marked_datum.type])")
if(class == "Marked datum ([holder.marked_datum.type])")
class = "Marked datum"
else
class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client")
switch(class)
if("Obj")
target = input("Enter target:","Target",usr) as obj in world
if("Mob")
target = input("Enter target:","Target",usr) as mob in world
if("Area or Turf")
target = input("Enter target:","Target",usr.loc) as area|turf in world
if("Client")
var/list/keys = list()
for(var/client/C)
keys += C
target = input("Please, select a player!", "Selection", null, null) as null|anything in keys
if("Marked datum")
target = holder.marked_datum
else
return
var/list/value = vv_get_value(default_class = VV_ATOM_REFERENCE, classes = list(VV_ATOM_REFERENCE, VV_DATUM_REFERENCE, VV_MOB_REFERENCE, VV_CLIENT))
if (!value["class"] || !value["value"])
return
target = value["value"]
if("No")
target = null
targetselected = 0
@@ -70,8 +51,9 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null
if(!procname)
return
if(targetselected && !hascall(target,procname))
usr << "<font color='red'>Error: callproc(): target has no such call [procname].</font>"
usr << "<font color='red'>Error: callproc(): type [target.type] has no proc named [procname].</font>"
return
else
var/procpath = text2path(procname)
@@ -99,7 +81,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
usr << .
feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/callproc_datum(A as null|area|mob|obj|turf)
/client/proc/callproc_datum(datum/A as null|area|mob|obj|turf)
set category = "Debug"
set name = "Atom ProcCall"
set waitfor = 0
@@ -111,7 +93,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!procname)
return
if(!hascall(A,procname))
usr << "<span class='warning'>Error: callproc_datum(): target has no such call [procname].</span>"
usr << "<font color='red'>Error: callproc_datum(): type [A.type] has no proc named [procname].</font>"
return
var/list/lst = get_callproc_args()
if(!lst)
@@ -133,59 +115,17 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
/client/proc/get_callproc_args()
var/argnum = input("Number of arguments","Number:",0) as num|null
if(!argnum && (argnum!=0))
if(isnull(argnum))
return
var/list/lst = list()
//TODO: make a list to store whether each argument was initialised as null.
//Reason: So we can abort the proccall if say, one of our arguments was a mob which no longer exists
//this will protect us from a fair few errors ~Carn
while(argnum--)
var/class = null
// Make a list with each index containing one variable, to be given to the proc
if(src.holder && src.holder.marked_datum)
class = input("What kind of variable?","Variable Type") in list("text","num","type","reference","mob reference","icon","file","client","mob's area","Marked datum ([holder.marked_datum.type])","CANCEL")
if(holder.marked_datum && class == "Marked datum ([holder.marked_datum.type])")
class = "Marked datum"
else
class = input("What kind of variable?","Variable Type") in list("text","num","type","reference","mob reference","icon","file","client","mob's area","CANCEL")
switch(class)
if("CANCEL")
return null
var/value = vv_get_value(restricted_classes = list(VV_RESTORE_DEFAULT))
if (!value["class"])
return
lst += value["value"]
if("text")
lst += input("Enter new text:","Text",null) as text
if("num")
lst += input("Enter new number:","Num",0) as num
if("type")
lst += input("Enter type:","Type") in typesof(/obj,/mob,/area,/turf)
if("reference")
lst += input("Select reference:","Reference",src) as mob|obj|turf|area in world
if("mob reference")
lst += input("Select reference:","Reference",usr) as mob in world
if("file")
lst += input("Pick file:","File") as file
if("icon")
lst += input("Pick icon:","Icon") as icon
if("client")
var/list/keys = list()
for(var/mob/M in world)
keys += M.client
lst += input("Please, select a player!", "Selection", null, null) as null|anything in keys
if("mob's area")
var/mob/temp = input("Select mob", "Selection", usr) as mob in world
lst += temp.loc
if("Marked datum")
lst += holder.marked_datum
return lst
@@ -210,7 +150,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
. += "</font>"
else
. = "<font color='blue'>[procname] returned: [returnval ? returnval : "null"]</font>"
. = "<font color='blue'>[procname] returned: [!isnull(returnval) ? returnval : "null"]</font>"
/client/proc/Cell()
@@ -220,7 +160,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
return
var/turf/T = mob.loc
if (!( istype(T, /turf) ))
if(!isturf(T))
return
var/datum/gas_mixture/env = T.return_air()
@@ -241,7 +181,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
log_admin("[key_name(src)] has robotized [M.key].")
var/mob/living/carbon/human/H = M
spawn(0)
@@ -257,11 +197,11 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if(istype(M, /mob/living/carbon/human))
if(ishuman(M))
log_admin("[key_name(src)] has blobized [M.key].")
var/mob/living/carbon/human/H = M
spawn(0)
var/mob/camera/blob/B = H.become_overmind()
var/mob/camera/blob/B = H.become_overmind(FALSE)
B.place_blob_core(B.base_point_rate, -1) //place them wherever they are
else
@@ -280,7 +220,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
alert("That mob doesn't seem to exist, close the panel and try again.")
return
if(istype(M, /mob/new_player))
if(isnewplayer(M))
alert("The mob must not be a new_player.")
return
@@ -301,7 +241,7 @@ But you can call procs that are of type /mob/living/carbon/human/proc/ for that
var/mob/choice = input("Choose a player to play the pAI", "Spawn pAI") in available
if(!choice)
return 0
if(!istype(choice, /mob/dead/observer))
if(!isobserver(choice))
var/confirm = input("[choice.key] isn't ghosting right now. Are you sure you want to yank him out of them out of their body and place them in this pAI?", "Spawn pAI Confirmation", "No") in list("Yes", "No")
if(confirm != "Yes")
return 0
@@ -358,26 +298,51 @@ var/list/TYPES_SHORTCUTS = list(
/obj/item/weapon/reagent_containers/food/drinks = "DRINK", //longest paths comes first
/obj/item/weapon/reagent_containers/food = "FOOD",
/obj/item/weapon/reagent_containers = "REAGENT_CONTAINERS",
/obj/machinery/atmospherics = "ATMOS",
/obj/item/weapon = "WEAPON",
/obj/machinery/atmospherics = "ATMOS_MECH",
/obj/machinery/portable_atmospherics = "PORT_ATMOS",
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/launcher/missile_rack = "MECHA_MISSILE_RACK",
/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/missile_rack = "MECHA_MISSILE_RACK",
/obj/item/mecha_parts/mecha_equipment = "MECHA_EQUIP",
/obj/item/organ = "ORGAN",
/obj/item = "ITEM",
/obj/machinery = "MACHINERY",
/obj/effect = "EFFECT",
/obj = "O",
/datum = "D",
/turf/open = "OPEN",
/turf/closed = "CLOSED",
/turf = "T",
/mob/living/carbon = "CARBON",
/mob/living/simple_animal = "SIMPLE",
/mob/living = "LIVING",
/mob = "M"
)
var/global/list/g_fancy_list_of_types = null
/proc/get_fancy_list_of_types()
if (isnull(g_fancy_list_of_types)) //init
var/list/temp = sortList(subtypesof(/atom) - typesof(/area) - /atom/movable)
g_fancy_list_of_types = new(temp.len)
for(var/type in temp)
var/typename = "[type]"
for (var/tn in TYPES_SHORTCUTS)
if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ )
typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/"))
break
g_fancy_list_of_types[typename] = type
return g_fancy_list_of_types
/proc/make_types_fancy(var/list/types)
if (ispath(types))
types = list(types)
. = list()
for(var/type in types)
var/typename = "[type]"
for (var/tn in TYPES_SHORTCUTS)
if (copytext(typename,1, length("[tn]/")+1)=="[tn]/" /*findtextEx(typename,"[tn]/",1,2)*/ )
typename = TYPES_SHORTCUTS[tn]+copytext(typename,length("[tn]/"))
break
.[typename] = type
/proc/get_fancy_list_of_atom_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(typesof(/atom))
return pre_generated_list
/proc/get_fancy_list_of_datum_types()
var/static/list/pre_generated_list
if (!pre_generated_list) //init
pre_generated_list = make_types_fancy(sortList(typesof(/datum) - typesof(/atom)))
return pre_generated_list
/proc/filter_fancy_list(list/L, filter as text)
var/list/matches = new
@@ -392,7 +357,7 @@ var/global/list/g_fancy_list_of_types = null
set category = "Debug"
set name = "Del-All"
var/list/matches = get_fancy_list_of_types()
var/list/matches = get_fancy_list_of_atom_types()
if (!isnull(object) && object!="")
matches = filter_fancy_list(matches, object)
@@ -427,7 +392,7 @@ var/global/list/g_fancy_list_of_types = null
if(!ticker || !ticker.mode)
alert("Wait until the game starts")
return
if (istype(M, /mob/living/carbon/human))
if(ishuman(M))
var/mob/living/carbon/human/H = M
var/obj/item/worn = H.wear_id
var/obj/item/weapon/card/id/id = null
@@ -573,7 +538,6 @@ var/global/list/g_fancy_list_of_types = null
if(!ishuman(M))
alert("Invalid mob")
return
//log_admin("[key_name(src)] has alienized [M.key].")
var/list/outfits = list("Naked","Custom","As Job...")
@@ -587,12 +551,20 @@ var/global/list/g_fancy_list_of_types = null
if (isnull(dresscode))
return
var/datum/job/jobdatum
if (outfits[dresscode])
dresscode = outfits[dresscode]
if (dresscode == "As Job...")
var/jobname = input("Select job", "Robust quick dress shop") as null|anything in get_all_jobs()
if(isnull(jobname))
var/list/job_paths = subtypesof(/datum/outfit/job)
var/list/job_outfits = list()
for(var/path in job_paths)
var/datum/outfit/O = path
job_outfits[initial(O.name)] = path
dresscode = input("Select job equipment", "Robust quick dress shop") as null|anything in job_outfits
dresscode = job_outfits[dresscode]
if(isnull(dresscode))
return
jobdatum = SSjob.GetJob(jobname)
var/datum/outfit/custom = null
@@ -606,9 +578,7 @@ var/global/list/g_fancy_list_of_types = null
return
feedback_add_details("admin_verb","SEQ") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
for (var/obj/item/I in M)
if (istype(I, /obj/item/weapon/implant))
continue
for (var/obj/item/I in M.get_equipped_items())
qdel(I)
switch(dresscode)
if ("Naked")
@@ -616,21 +586,14 @@ var/global/list/g_fancy_list_of_types = null
if ("Custom")
//use custom one
M.equipOutfit(custom)
if ("As Job...")
if(jobdatum)
dresscode = jobdatum.title
M.job = jobdatum.title
jobdatum.equip(M)
else
M.equipOutfit(outfits[dresscode])
M.equipOutfit(dresscode)
M.regenerate_icons()
log_admin("[key_name(usr)] changed the equipment of [key_name(M)] to [dresscode].")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode]..</span>")
return
message_admins("<span class='adminnotice'>[key_name_admin(usr)] changed the equipment of [key_name_admin(M)] to [dresscode].</span>")
/client/proc/startSinglo()
@@ -766,4 +729,30 @@ var/global/list/g_fancy_list_of_types = null
var/datum/map_template/ruin/template = landmark.ruin_template
usr.forceMove(get_turf(landmark))
usr << "<span class='name'>[template.name]</span>"
usr << "<span class='italics'>[template.description]</span>"
usr << "<span class='italics'>[template.description]</span>"
/client/proc/clear_dynamic_transit()
set category = "Debug"
set name = "Clear Dynamic Transit"
set desc = "Deallocates all transit space, restoring it to round start \
conditions."
if(!holder)
return
SSshuttle.clear_transit = TRUE
message_admins("<span class='adminnotice'>[key_name_admin(src)] cleared dynamic transit space.</span>")
feedback_add_details("admin_verb","CDT") // If...
log_admin("[key_name(src)] cleared dynamic transit space.")
/client/proc/toggle_medal_disable()
set category = "Debug"
set name = "Toggle Medal Disable"
set desc = "Toggles the safety lock on trying to contact the medal hub."
if(!holder)
return
global.medals_enabled = !global.medals_enabled
message_admins("<span class='adminnotice'>[key_name_admin(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.</span>")
feedback_add_details("admin_verb","TMH") // If...
log_admin("[key_name(src)] [global.medals_enabled ? "disabled" : "enabled"] the medal hub lockout.")
+1 -1
View File
@@ -8,7 +8,7 @@
var/datum/gas_mixture/GM = target.return_air()
var/list/GM_gases
var/burning = 0
if(istype(target, /turf/open))
if(isopenturf(target))
var/turf/open/T = target
if(T.active_hotspot)
burning = 1
+9 -9
View File
@@ -1,24 +1,24 @@
//replaces the old Ticklag verb, fps is easier to understand
/client/proc/set_fps()
/client/proc/set_server_fps()
set category = "Debug"
set name = "Set fps"
set name = "Set Server FPS"
set desc = "Sets game speed in frames-per-second. Can potentially break the game"
if(!check_rights(R_DEBUG))
return
var/fps = round(input("Sets game frames-per-second. Can potentially break the game","FPS", config.fps) as num|null)
var/new_fps = round(input("Sets game frames-per-second. Can potentially break the game (default: [config.fps])","FPS", world.fps) as num|null)
if(fps <= 0)
src << "<span class='danger'>Error: ticklag(): Invalid world.ticklag value. No changes made.</span>"
if(new_fps <= 0)
src << "<span class='danger'>Error: set_server_fps(): Invalid world.fps value. No changes made.</span>"
return
if(fps > config.fps)
if(alert(src, "You are setting fps to a high value:\n\t[fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
if(new_fps > config.fps*1.5)
if(alert(src, "You are setting fps to a high value:\n\t[new_fps] frames-per-second\n\tconfig.fps = [config.fps]","Warning!","Confirm","ABORT-ABORT-ABORT") != "Confirm")
return
var/msg = "[key_name(src)] has modified world.fps to [fps]"
var/msg = "[key_name(src)] has modified world.fps to [new_fps]"
log_admin(msg, 0)
message_admins(msg, 0)
feedback_add_details("admin_verb","TICKLAG") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
world.fps = fps
world.fps = new_fps
+5 -5
View File
@@ -14,7 +14,7 @@
var/mob //The mob adminhelping mob.
/client/proc/list_ahelps(user, resolved)
if(!check_rights(R_BAN))
if(!check_rights(R_ADMIN))
src << "<font color='red'>Error: Only administrators may use this command.</font>"
return
@@ -68,7 +68,7 @@
set name = "List Adminhelps"
set desc = "List all current adminhelps"
if(!check_rights(R_BAN))
if(!check_rights(R_ADMIN))
src << "<font color='red'>Error: Only administrators may use this command.</font>"
return
@@ -100,7 +100,7 @@
set name = "List Unresolved Adminhelps"
set desc = "List all current unresolved adminhelps"
if(!check_rights(R_BAN))
if(!check_rights(R_ADMIN))
src << "<font color='red'>Error: Only administrators may use this command.</font>"
return
@@ -134,7 +134,7 @@
set name = "View Handling Ahelps"
set desc = "List all current handling ahelps"
if(!check_rights(R_BAN))
if(!check_rights(R_ADMIN))
src << "<font color='red'>Error: Only administrators may use this command.</font>"
return
@@ -253,7 +253,7 @@
set name = "Resolve Handling Ahelp"
set desc = "Resolve my own adminhelp"
if(!check_rights(R_BAN))
if(!check_rights(R_ADMIN))
src << "<font color='red'>Error: Only administrators may use this command.</font>"
return
@@ -26,10 +26,12 @@
organ.implant(C)
if("drop organ/implant", "remove organ/implant")
for(var/obj/item/organ/I in C.internal_organs)
for(var/X in C.internal_organs)
var/obj/item/organ/I = X
organs["[I.name] ([I.type])"] = I
for(var/obj/item/weapon/implant/I in C)
for(var/X in C.implants)
var/obj/item/weapon/implant/I = X
organs["[I.name] ([I.type])"] = I
var/obj/item/organ = input("Select organ/implant:", "Organ Manipulation", null) in organs
+7 -1
View File
@@ -33,7 +33,7 @@ var/list/admin_verbs_debug_mapping = list(
/client/proc/count_objects_all,
/client/proc/cmd_assume_direct_control, //-errorage
/client/proc/startSinglo,
/client/proc/set_fps, //allows you to set the ticklag.
/client/proc/set_server_fps, //allows you to set the ticklag.
/client/proc/cmd_admin_grantfullaccess,
/client/proc/cmd_admin_areatest,
/client/proc/cmd_admin_rejuvenate,
@@ -45,6 +45,12 @@ var/list/admin_verbs_debug_mapping = list(
/client/proc/manipulate_organs
)
/obj/effect/debugging/mapfix_marker
name = "map fix marker"
icon = 'icons/mob/screen_gen.dmi'
icon_state = "mapfixmarker"
desc = "I am a mappers mistake."
/obj/effect/debugging/marker
icon = 'icons/turf/areas.dmi'
icon_state = "yellow"
+205 -477
View File
@@ -3,46 +3,32 @@
set name = "Mass Edit Variables"
set desc="(target) Edit all instances of a target item's variables"
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL itms)
var/method = 0 //0 means strict type detection while 1 means this type and all subtypes (IE: /obj/item with this set to 1 will set it to ALL items)
if(!check_rights(R_VAREDIT))
return
if(A && A.type)
if(typesof(A.type))
switch(input("Strict object type detection?") as null|anything in list("Strictly this type","This type and subtypes", "Cancel"))
if("Strictly this type")
method = 0
if("This type and subtypes")
method = 1
if("Cancel")
return
if(null)
return
method = vv_subtype_prompt(A.type)
src.massmodify_variables(A, var_name, method)
feedback_add_details("admin_verb","MEV") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/massmodify_variables(atom/O, var_name = "", method = 0)
/client/proc/massmodify_variables(datum/O, var_name = "", method = 0)
if(!check_rights(R_VAREDIT))
return
for(var/p in forbidden_varedit_object_types)
if( istype(O,p) )
usr << "<span class='danger'>It is forbidden to edit this object's variables.</span>"
return
var/list/names = list()
for (var/V in O.vars)
names += V
names = sortList(names)
if(!istype(O))
return
var/variable = ""
if(!var_name)
variable = input("Which var?","Var") as null|anything in names
var/list/names = list()
for (var/V in O.vars)
names += V
names = sortList(names)
variable = input("Which var?", "Var") as null|anything in names
else
variable = var_name
@@ -50,10 +36,9 @@
return
var/default
var/var_value = O.vars[variable]
var/dir
if(variable in VVckey_edit)
usr << "It's forbidden to mass-modify ckeys. I'll crash everyone's client you dummy."
src << "It's forbidden to mass-modify ckeys. It'll crash everyone's client you dummy."
return
if(variable in VVlocked)
if(!check_rights(R_DEBUG))
@@ -61,478 +46,221 @@
if(variable in VVicon_edit_lock)
if(!check_rights(R_FUN|R_DEBUG))
return
if(variable in VVpixelmovement)
if(!check_rights(R_DEBUG))
return
var/prompt = alert(src, "Editing this var may irreparably break tile gliding for the rest of the round. THIS CAN'T BE UNDONE", "DANGER", "ABORT ", "Continue", " ABORT")
if (prompt != "Continue")
return
if(isnull(var_value))
usr << "Unable to determine variable type."
else if(isnum(var_value))
usr << "Variable appears to be <b>NUM</b>."
default = "num"
setDir(1)
else if(istext(var_value))
usr << "Variable appears to be <b>TEXT</b>."
default = "text"
else if(isloc(var_value))
usr << "Variable appears to be <b>REFERENCE</b>."
default = "reference"
else if(isicon(var_value))
usr << "Variable appears to be <b>ICON</b>."
var_value = "\icon[var_value]"
default = "icon"
else if(istype(var_value,/atom) || istype(var_value,/datum))
usr << "Variable appears to be <b>TYPE</b>."
default = "type"
else if(istype(var_value,/list))
usr << "Variable appears to be <b>LIST</b>."
default = "list"
else if(istype(var_value,/client))
usr << "Variable appears to be <b>CLIENT</b>."
default = "cancel"
default = vv_get_class(var_value)
if(isnull(default))
src << "Unable to determine variable type."
else
usr << "Variable appears to be <b>FILE</b>."
default = "file"
src << "Variable appears to be <b>[uppertext(default)]</b>."
usr << "Variable contains: [var_value]"
if(dir)
switch(var_value)
if(1)
setDir("NORTH")
if(2)
setDir("SOUTH")
if(4)
setDir("EAST")
if(8)
setDir("WEST")
if(5)
setDir("NORTHEAST")
if(6)
setDir("SOUTHEAST")
if(9)
setDir("NORTHWEST")
if(10)
setDir("SOUTHWEST")
else
setDir(null)
if(dir)
usr << "If a direction, direction is: [dir]"
src << "Variable contains: [var_value]"
var/class = input("What kind of variable?","Variable Type",default) as null|anything in list("text",
"num","type","icon","file","edit referenced object","restore to default")
if(default == VV_NUM)
var/dir_text = ""
if(dir < 0 && dir < 16)
if(dir & 1)
dir_text += "NORTH"
if(dir & 2)
dir_text += "SOUTH"
if(dir & 4)
dir_text += "EAST"
if(dir & 8)
dir_text += "WEST"
if(!class)
if(dir_text)
src << "If a direction, direction is: [dir_text]"
var/value = vv_get_value(default_class = default)
var/new_value = value["value"]
var/class = value["class"]
if(!class || !new_value == null && class != VV_NULL)
return
var/original_name
if (class == VV_MESSAGE)
class = VV_TEXT
if (!istype(O, /atom))
original_name = "\ref[O] ([O])"
else
original_name = O:name
if (value["type"])
class = VV_NEW_TYPE
var/original_name = "[O]"
var/rejected = 0
var/accepted = 0
switch(class)
if("restore to default")
O.vars[variable] = initial(O.vars[variable])
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("edit referenced object")
return .(O.vars[variable])
if("text")
var/new_value = input("Enter new text:","Text",O.vars[variable]) as message|null
if(new_value == null) return
var/process_vars = 0
var/unique = 0
if(findtext(new_value,"\["))
process_vars = alert(usr,"\[] detected in string, process as variables?","Process Variables?","Yes","No")
if(process_vars == "Yes")
process_vars = 1
unique = alert(usr,"Process vars unique to each instance, or same for all?","Variable Association","Unique","Same")
if(unique == "Unique")
unique = 1
else
unique = 0
if(VV_RESTORE_DEFAULT)
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
src << "Changing [items.len] items..."
for(var/thing in items)
if (!thing)
continue
var/datum/D = thing
if (D.vv_edit_var(variable, initial(D.vars[variable])) != FALSE)
accepted++
else
process_vars = 0
rejected++
CHECK_TICK
if(VV_TEXT)
var/list/varsvars = vv_parse_text(O, new_value)
var/pre_processing = new_value
var/list/varsvars = list()
if(process_vars)
varsvars = string2listofvars(new_value, O)
if(varsvars.len)
var/unique
if (varsvars && varsvars.len)
unique = alert(usr, "Process vars unique to each instance, or same for all?", "Variable Association", "Unique", "Same")
if(unique == "Unique")
unique = TRUE
else
unique = FALSE
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[O.vars[V]]")
O.vars[variable] = new_value
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
src << "Changing [items.len] items..."
for(var/thing in items)
if (!thing)
continue
var/datum/D = thing
if(unique)
new_value = pre_processing
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[D.vars[V]]")
//Convert the string vars for anything that's not O
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
new_value = pre_processing //reset new_value, ready to convert it uniquely for the next iteration
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[M.vars[V]]")
else
new_value = O.vars[variable] //We already processed the non-unique form for O, reuse it
M.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[M.vars[V]]")
else
new_value = O.vars[variable]
M.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
new_value = pre_processing
if(process_vars)
if(unique)
for(var/V in varsvars)
new_value = replacetext(new_value,"\[[V]]","[A.vars[V]]")
else
new_value = O.vars[variable]
A.vars[variable] = new_value
CHECK_TICK
if("num")
var/new_value = input("Enter new number:","Num",\
O.vars[variable]) as num|null
if(new_value == null) return
if(variable=="luminosity")
O.set_light(new_value)
else
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
if(variable=="luminosity")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
if(variable=="luminosity")
M.set_light(new_value)
else
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
if(variable=="luminosity")
A.set_light(new_value)
else
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("type")
var/new_value
new_value = input("Enter type:","Type",O.vars[variable]) as null|anything in typesof(/obj,/mob,/area,/turf)
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("file")
var/new_value = input("Pick file:","File",O.vars[variable]) as null|file
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O.type, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O.type, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if("icon")
var/new_value = input("Pick icon:","Icon",O.vars[variable]) as null|icon
if(new_value == null) return
O.vars[variable] = new_value
if(method)
if(istype(O, /mob))
for(var/mob/M in mob_list)
if ( istype(M , O.type) )
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if ( istype(A , O.type) )
A.vars[variable] = O.vars[variable]
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if (M.type == O.type)
M.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if (A.type == O.type)
A.vars[variable] = O.vars[variable]
CHECK_TICK
if(method)
if(istype(O,/mob))
for(var/mob/M in mob_list)
if(istype(M,O.type))
M.on_varedit(variable)
if (D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
else if(istype(O,/obj))
for(var/obj/A in world)
if(istype(A,O.type))
A.on_varedit(variable)
if (VV_NEW_TYPE)
var/many = alert(src, "Create only one [value["type"]] and assign each or a new one for each thing", "How Many", "One", "Many", "Cancel")
if (many == "Cancel")
return
if (many == "Many")
many = TRUE
else
many = FALSE
var/type = value["type"]
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
src << "Changing [items.len] items..."
for(var/thing in items)
if (!thing)
continue
var/datum/D = thing
if(many && !new_value)
new_value = new type()
if (D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
new_value = null
CHECK_TICK
else if(istype(O,/turf))
for(var/turf/A in block(locate(1,1,1),locate(world.maxx,world.maxy,world.maxz)))
if(istype(A,O.type))
A.on_varedit(variable)
else
src << "Finding items..."
var/list/items = get_all_of_type(O.type, method)
src << "Changing [items.len] items..."
for(var/thing in items)
if (!thing)
continue
var/datum/D = thing
if (D.vv_edit_var(variable, new_value) != FALSE)
accepted++
else
rejected++
CHECK_TICK
var/count = rejected+accepted
if (!count)
src << "No objects found"
return
if (!accepted)
src << "Every object rejected your edit"
return
if (rejected)
src << "[rejected] out of [count] objects rejected your edit"
world.log << "### MassVarEdit by [src]: [O.type] (A/R [accepted]/[rejected]) [variable]=[html_encode("[O.vars[variable]]")]([list2params(value)])"
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]] ([accepted] objects modified)")
/proc/get_all_of_type(var/T, subtypes = TRUE)
var/list/typecache = list()
typecache[T] = 1
if (subtypes)
typecache = typecacheof(typecache)
. = list()
if (ispath(T, /mob))
for(var/mob/thing in mob_list)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery/door))
for(var/obj/machinery/door/thing in airlocks)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj/machinery))
for(var/obj/machinery/thing in machines)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /obj))
for(var/obj/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /atom/movable))
for(var/atom/movable/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /turf))
for(var/turf/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /atom))
for(var/atom/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /client))
for(var/client/thing in clients)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if (ispath(T, /datum))
for(var/datum/thing)
if (typecache[thing.type])
. += thing
CHECK_TICK
else
if(istype(O, /mob))
for(var/mob/M in mob_list)
if(M.type == O.type)
M.on_varedit(variable)
CHECK_TICK
for(var/datum/thing in world)
if (typecache[thing.type])
. += thing
CHECK_TICK
else if(istype(O, /obj))
for(var/obj/A in world)
if(A.type == O.type)
A.on_varedit(variable)
CHECK_TICK
else if(istype(O, /turf))
for(var/turf/A in world)
if(A.type == O.type)
A.on_varedit(variable)
CHECK_TICK
world.log << "### MassVarEdit by [src]: [O.type] [variable]=[html_encode("[O.vars[variable]]")]"
log_admin("[key_name(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
message_admins("[key_name_admin(src)] mass modified [original_name]'s [variable] to [O.vars[variable]]")
File diff suppressed because it is too large Load Diff
+15 -15
View File
@@ -11,18 +11,18 @@
/datum/admins/proc/one_click_antag()
var/dat = {"
<a href='?src=\ref[src];makeAntag=1'>Make Traitors</a><br>
<a href='?src=\ref[src];makeAntag=2'>Make Changelings</a><br>
<a href='?src=\ref[src];makeAntag=3'>Make Revs</a><br>
<a href='?src=\ref[src];makeAntag=4'>Make Cult</a><br>
<a href='?src=\ref[src];makeAntag=15'>Make Clockwork Cult</a><br>
<a href='?src=\ref[src];makeAntag=11'>Make Blob</a><br>
<a href='?src=\ref[src];makeAntag=12'>Make Gangsters</a><br>
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=7'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=13'>Make Centcom Response Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=14'>Make Abductor Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=15'>Make Revenant (Requires Ghost)</a><br>
<a href='?src=\ref[src];makeAntag=traitors'>Make Traitors</a><br>
<a href='?src=\ref[src];makeAntag=changelings'>Make Changelings</a><br>
<a href='?src=\ref[src];makeAntag=revs'>Make Revs</a><br>
<a href='?src=\ref[src];makeAntag=cult'>Make Cult</a><br>
<a href='?src=\ref[src];makeAntag=clockcult'>Make Clockwork Cult</a><br>
<a href='?src=\ref[src];makeAntag=blob'>Make Blob</a><br>
<a href='?src=\ref[src];makeAntag=gangs'>Make Gangsters</a><br>
<a href='?src=\ref[src];makeAntag=wizard'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=nukeops'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=centcom'>Make Centcom Response Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=abductors'>Make Abductor Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=revenant'>Make Revenant (Requires Ghost)</a><br>
"}
var/datum/browser/popup = new(usr, "oneclickantag", "Quick-Create Antagonist", 400, 400)
@@ -134,7 +134,7 @@
var/list/mob/dead/observer/candidates = pollCandidates("Do you wish to be considered for the position of a Wizard Foundation 'diplomat'?", "wizard", null)
var/mob/dead/observer/selected = popleft(candidates)
var/mob/dead/observer/selected = pick_n_take(candidates)
var/mob/living/carbon/human/new_character = makeBody(selected)
new_character.mind.make_Wizard()
@@ -239,7 +239,7 @@
if(agentcount < 3)
return 0
var/nuke_code = "[rand(10000, 99999)]"
var/nuke_code = random_nukecode()
var/obj/machinery/nuclearbomb/nuke = locate("syndienuke") in nuke_list
if(nuke)
@@ -552,5 +552,5 @@
return 1
/datum/admins/proc/makeRevenant()
new /datum/round_event/ghost_role/revenant
new /datum/round_event/ghost_role/revenant(TRUE, TRUE)
return 1
+76 -50
View File
@@ -1,54 +1,77 @@
/client/proc/only_one()
var/highlander = FALSE
/client/proc/only_one() //Gives everyone kilts, berets, claymores, and pinpointers, with the objective to hijack the emergency shuttle.
if(!ticker || !ticker.mode)
alert("The game hasn't started yet!")
return
highlander = TRUE
world << "<span class='userdanger'><i>THERE CAN BE ONLY ONE!!!</i></span>"
world << sound('sound/misc/highlander.ogg')
for(var/obj/item/weapon/disk/nuclear/N in poi_list)
N.relocate() //Gets it out of bags and such
for(var/mob/living/carbon/human/H in player_list)
if(H.stat == 2 || !(H.client)) continue
if(is_special_character(H)) continue
ticker.mode.traitors += H.mind
H.mind.special_role = "traitor"
var/datum/objective/steal/steal_objective = new
steal_objective.owner = H.mind
steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
H.mind.objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.owner = H.mind
H.mind.objectives += hijack_objective
H << "<B>You are the traitor.</B>"
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
H << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
for (var/obj/item/I in H)
if (istype(I, /obj/item/weapon/implant))
continue
qdel(I)
H.equip_to_slot_or_del(new /obj/item/clothing/under/kilt(H), slot_w_uniform)
H.equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(H), slot_ears)
H.equip_to_slot_or_del(new /obj/item/clothing/head/beret(H), slot_head)
H.equip_to_slot_or_del(new /obj/item/weapon/claymore(H), slot_l_hand)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(H), slot_shoes)
H.equip_to_slot_or_del(new /obj/item/weapon/pinpointer(H.loc), slot_l_store)
var/obj/item/weapon/card/id/W = new(H)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = H.real_name
W.update_label(H.real_name)
H.equip_to_slot_or_del(W, slot_wear_id)
if(H.stat == DEAD || !(H.client))
continue
H.make_scottish()
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used THERE CAN BE ONLY ONE!</span>")
log_admin("[key_name(usr)] used there can be only one.")
log_admin("[key_name(usr)] used THERE CAN BE ONLY ONE.")
addtimer(CALLBACK(SSshuttle.emergency, /obj/docking_port/mobile/emergency.proc/request, null, 1), 50)
/mob/living/carbon/human/proc/make_scottish()
ticker.mode.traitors += mind
mind.special_role = "highlander"
dna.species.species_traits |= NOGUNS //nice try jackass
var/datum/objective/steal/steal_objective = new
steal_objective.owner = mind
steal_objective.set_target(new /datum/objective_item/steal/nukedisc)
mind.objectives += steal_objective
var/datum/objective/hijack/hijack_objective = new
hijack_objective.explanation_text = "Escape on the shuttle alone. Ensure that nobody else makes it out."
hijack_objective.owner = mind
mind.objectives += hijack_objective
mind.announce_objectives()
for(var/obj/item/I in get_equipped_items())
qdel(I)
for(var/obj/item/I in held_items)
qdel(I)
equip_to_slot_or_del(new /obj/item/clothing/under/kilt/highlander(src), slot_w_uniform)
equip_to_slot_or_del(new /obj/item/device/radio/headset/heads/captain(src), slot_ears)
equip_to_slot_or_del(new /obj/item/clothing/head/beret/highlander(src), slot_head)
equip_to_slot_or_del(new /obj/item/clothing/shoes/combat(src), slot_shoes)
equip_to_slot_or_del(new /obj/item/weapon/pinpointer(src), slot_l_store)
for(var/obj/item/weapon/pinpointer/P in src)
P.attack_self(src)
var/obj/item/weapon/card/id/W = new(src)
W.icon_state = "centcom"
W.access = get_all_accesses()
W.access += get_all_centcom_access()
W.assignment = "Highlander"
W.registered_name = real_name
W.flags |= NODROP
W.update_label(real_name)
equip_to_slot_or_del(W, slot_wear_id)
var/obj/item/weapon/claymore/highlander/H1 = new(src)
if(!highlander)
H1.admin_spawned = TRUE //To prevent announcing
put_in_hands(H1)
H1.pickup(src) //For the stun shielding
var/obj/item/weapon/bloodcrawl/antiwelder = new(src)
antiwelder.name = "compulsion of honor"
antiwelder.desc = "You are unable to hold anything in this hand until you're the last one left!"
antiwelder.icon_state = "bloodhand_right"
put_in_hands(antiwelder)
src << "<span class='boldannounce'>Your [H1.name] cries out for blood. Join in the slaughter, lest you be claimed yourself...\n\
Activate it in your hand, and it will lead to the nearest target. Attack the nuclear authentication disk with it, and you will store it.</span>"
/proc/only_me()
if(!ticker || !ticker.mode)
@@ -67,18 +90,21 @@
H.mind.objectives += hijack_objective
H << "<B>You are the multiverse summoner. Activate your blade to summon copies of yourself from another universe to fight by your side.</B>"
var/obj_count = 1
for(var/datum/objective/OBJ in H.mind.objectives)
H << "<B>Objective #[obj_count]</B>: [OBJ.explanation_text]"
obj_count++
H.mind.announce_objectives()
var/datum/gang/multiverse/G = new(src, "[H.real_name]")
ticker.mode.gangs += G
G.bosses += H.mind
G.add_gang_hud(H.mind)
H.mind.gang_datum = G
var/obj/item/slot_item_ID = H.get_item_by_slot(slot_wear_id)
qdel(slot_item_ID)
var/obj/item/slot_item_hand = H.get_item_by_slot(slot_r_hand)
H.unEquip(slot_item_hand)
var/obj/item/slot_item_hand = H.get_item_for_held_index(2)
H.dropItemToGround(slot_item_hand)
var /obj/item/weapon/multisword/multi = new(H)
H.equip_to_slot_or_del(multi, slot_r_hand)
H.put_in_hands_or_del(multi)
var/obj/item/weapon/card/id/W = new(H)
W.icon_state = "centcom"
+32 -9
View File
@@ -18,15 +18,26 @@
return
var/image/cross = image('icons/obj/storage.dmi',"bible")
var/font_color = "purple"
var/prayer_type = "PRAYER"
var/deity
if(usr.job == "Chaplain")
cross = image('icons/obj/storage.dmi',"kingyellow")
msg = "<span class='adminnotice'>\icon[cross] <b><font color=blue>CHAPLAIN PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
font_color = "blue"
prayer_type = "CHAPLAIN PRAYER"
if(SSreligion.Bible_deity_name)
deity = SSreligion.Bible_deity_name
else if(iscultist(usr))
cross = image('icons/obj/storage.dmi',"tome")
msg = "<span class='adminnotice'>\icon[cross] <b><font color=red>CULTIST PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
else
cross = image('icons/obj/storage.dmi',"bible")
msg = "<span class='adminnotice'>\icon[cross] <b><font color=purple>PRAYER: </font>[key_name_admin(src)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[src]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[src]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[src]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[src]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[src]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[src]'>TP</A>) (<A HREF='?_src_=holder;adminspawncookie=\ref[src]'>SC</a>):</b> [msg]</span>"
font_color = "red"
prayer_type = "CULTIST PRAYER"
deity = "Nar-Sie"
msg = "<span class='adminnotice'>\icon[cross] \
<b><font color=[font_color]>[prayer_type][deity ? " (to [deity])" : ""]: </font>\
[ADMIN_FULLMONTY(src)] [ADMIN_SC(src)]:</b> \
[msg]</span>"
for(var/client/C in admins)
if(C.prefs.chat_toggles & CHAT_PRAYER)
C << msg
@@ -40,22 +51,34 @@
/proc/Centcomm_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=orange>CENTCOM:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
msg = "<span class='adminnotice'>\
<b><font color=orange>CENTCOM:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_CENTCOM_REPLY(Sender)]:</b> \
[msg]</span>"
admins << msg
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
/proc/Syndicate_announce(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=crimson>SYNDICATE:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;SyndicateReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
msg = "<span class='adminnotice'><b>\
<font color=crimson>SYNDICATE:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_SYNDICATE_REPLY(Sender)]:</b> \
[msg]</span>"
admins << msg
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
/proc/Nuke_request(text , mob/Sender)
var/msg = copytext(sanitize(text), 1, MAX_MESSAGE_LEN)
msg = "<span class='adminnotice'><b><font color=orange>NUKE CODE REQUEST:</font>[key_name_admin(Sender)] (<A HREF='?_src_=holder;adminmoreinfo=\ref[Sender]'>?</A>) (<A HREF='?_src_=holder;adminplayeropts=\ref[Sender]'>PP</A>) (<A HREF='?_src_=vars;Vars=\ref[Sender]'>VV</A>) (<A HREF='?_src_=holder;subtlemessage=\ref[Sender]'>SM</A>) (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[Sender]'>FLW</A>) (<A HREF='?_src_=holder;traitor=\ref[Sender]'>TP</A>) (<A HREF='?_src_=holder;BlueSpaceArtillery=\ref[Sender]'>BSA</A>) (<A HREF='?_src_=holder;CentcommReply=\ref[Sender]'>RPLY</A>):</b> [msg]</span>"
msg = "<span class='adminnotice'>\
<b><font color=orange>NUKE CODE REQUEST:</font>\
[ADMIN_FULLMONTY(Sender)] [ADMIN_BSA(Sender)] \
[ADMIN_CENTCOM_REPLY(Sender)] \
[ADMIN_SET_SD_CODE]:</b> \
[msg]</span>"
admins << msg
admins << "<span class='adminnotice'><b>At this current time, the nuke must have the code manually set via varedit.</b></span>"
for(var/obj/machinery/computer/communications/C in machines)
C.overrideCooldown()
+52 -19
View File
@@ -10,7 +10,7 @@
return
for(var/obj/item/W in M)
if(!M.unEquip(W))
if(!M.dropItemToGround(W))
qdel(W)
M.regenerate_icons()
@@ -58,7 +58,7 @@
return
world << "[msg]"
log_admin("GlobalNarrate: [key_name(usr)] : [msg]")
message_admins("<span class='adminnotice'><b> GlobalNarrate: [key_name_admin(usr)] :</b> [msg]<BR></span>")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] Sent a global narrate</span>")
feedback_add_details("admin_verb","GLN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_direct_narrate(mob/M)
@@ -70,7 +70,7 @@
return
if(!M)
M = input("Direct narrate to who?", "Active Players") as null|anything in player_list
M = input("Direct narrate to whom?", "Active Players") as null|anything in player_list
if(!M)
return
@@ -521,7 +521,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
feedback_add_details("admin_verb","MFS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/cmd_admin_explosion(atom/O as obj|mob|turf in world)
set category = "Abusive"
set category = "Dangerous"
set name = "Explosion"
if (!holder)
@@ -553,7 +553,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
return
/client/proc/cmd_admin_emp(atom/O as obj|mob|turf in world)
set category = "Special Verbs"
set category = "Dangerous"
set name = "EM Pulse"
if (!holder)
@@ -594,8 +594,8 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] has gibbed [key_name(M)]")
message_admins("[key_name_admin(usr)] has gibbed [key_name_admin(M)]")
if(istype(M, /mob/dead/observer))
gibs(M.loc, M.viruses)
if(isobserver(M))
new /obj/effect/gibspawner/generic(M.loc, M.viruses)
return
if(confirm == "Yes")
M.gib()
@@ -612,7 +612,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
log_admin("[key_name(usr)] used gibself.")
message_admins("<span class='adminnotice'>[key_name_admin(usr)] used gibself.</span>")
feedback_add_details("admin_verb","GIBS") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
mob.gib(1, 1)
mob.gib(1, 1, 1)
/client/proc/cmd_admin_check_contents(mob/living/M in mob_list)
set category = "Special Verbs"
@@ -689,7 +689,7 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/everyone_random()
set category = "Abusive"
set category = "Dangerous"
set name = "Make Everyone Random"
set desc = "Make everyone have a random appearance. You can only use this before rounds!"
@@ -754,29 +754,32 @@ Traitors and the like can also be revived with the previous role mostly intact.
/client/proc/toggle_nuke(obj/machinery/nuclearbomb/N in nuke_list)
set name = "Toggle Nuke"
set category = "Abusive"
set category = "Dangerous"
set popup_menu = 0
if(!check_rights(R_DEBUG))
return
if(!N.timing)
var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timeleft]") as num
var/newtime = input(usr, "Set activation timer.", "Activate Nuke", "[N.timer_set]") as num
if(!newtime)
return
N.timeleft = newtime
N.timer_set = newtime
N.set_safety()
N.set_active()
log_admin("[key_name(usr)] [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z]).")
message_admins("[key_name_admin(usr)] (<A HREF='?_src_=holder;adminplayerobservefollow=\ref[usr]'>FLW</A>) [N.timing ? "activated" : "deactivated"] a nuke at ([N.x],[N.y],[N.z] - <A HREF='?_src_=holder;adminplayerobservecoodjump=1;X=[N.x];Y=[N.y];Z=[N.z]'>JMP</a>).")
message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_COORDJMP(N)].")
feedback_add_details("admin_verb","TN") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/proc/reset_latejoin_spawns()
set category = "Abusive"
set category = "Debug"
set name = "Remove Latejoin Spawns"
if(!check_rights(R_DEBUG))
return
var/confirm = alert(src, "Disable Latejoin spawns??", "Message", "Yes", "No")
if(confirm != "Yes")
return
latejoin.Cut()
@@ -994,7 +997,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
M.ui_interact(usr)
/client/proc/mass_zombie_infection()
set category = "Abusive"
set category = "Dangerous"
set name = "Mass Zombie Infection"
set desc = "Infects all humans with a latent organ that will zombify \
them on death."
@@ -1007,14 +1010,14 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
return
for(var/mob/living/carbon/human/H in mob_list)
new /obj/item/organ/body_egg/zombie_infection(H)
new /obj/item/organ/zombie_infection(H)
message_admins("[key_name_admin(usr)] added a latent zombie infection to all humans.")
log_admin("[key_name(usr)] added a latent zombie infection to all humans.")
feedback_add_details("admin_verb","MZI")
/client/proc/mass_zombie_cure()
set category = "Abusive"
set category = "Dangerous"
set name = "Mass Zombie Cure"
set desc = "Removes the zombie infection from all humans, returning them to normal."
if(!holder)
@@ -1024,7 +1027,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
if(confirm != "Yes")
return
for(var/obj/item/organ/body_egg/zombie_infection/I in zombie_infection_list)
for(var/obj/item/organ/zombie_infection/I in zombie_infection_list)
qdel(I)
message_admins("[key_name_admin(usr)] cured all zombies.")
@@ -1032,7 +1035,7 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
feedback_add_details("admin_verb","MZC")
/client/proc/polymorph_all()
set category = "Abusive"
set category = "Dangerous"
set name = "Polymorph All"
set desc = "Applies the effects of the bolt of change to every single mob."
@@ -1137,3 +1140,33 @@ var/list/datum/outfit/custom_outfits = list() //Admin created outfits
H.regenerate_icons()
#undef ON_PURRBATION
/client/proc/modify_goals()
set category = "Debug"
set name = "Modify goals"
if(!check_rights(R_ADMIN))
return
holder.modify_goals()
/datum/admins/proc/modify_goals()
var/dat = ""
for(var/datum/station_goal/S in ticker.mode.station_goals)
dat += "[S.name] - <a href='?src=\ref[S];announce=1'>Announce</a> | <a href='?src=\ref[S];remove=1'>Remove</a><br>"
dat += "<br><a href='?src=\ref[src];add_station_goal=1'>Add New Goal</a>"
usr << browse(dat, "window=goals;size=400x400")
/client/proc/toggle_hub()
set category = "Server"
set name = "Toggle Hub"
world.visibility = (!world.visibility)
log_admin("[key_name(usr)] has toggled the server's hub status for the round, it is now [(world.visibility?"on":"off")] the hub.")
message_admins("[key_name_admin(usr)] has toggled the server's hub status for the round, it is now [(world.visibility?"on":"off")] the hub.")
if (world.visibility && !world.reachable)
message_admins("WARNING: The server will not show up on the hub because byond is detecting that a filewall is blocking incoming connections.")
feedback_add_details("admin_verb","HUB") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
+2
View File
@@ -36,6 +36,8 @@
if(browse)
watchlist_show(target_sql_ckey)
add_note(target_ckey, "Added to Watchlist - [reason]", null, usr.ckey, 0, null, 1)
/client/proc/watchlist_remove(target_ckey, browse = 0)
var/target_sql_ckey = sanitizeSQL(target_ckey)
var/DBQuery/query_watchdel = dbcon.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey = '[target_sql_ckey]'")
+22
View File
@@ -0,0 +1,22 @@
#define WHITELISTFILE "config/whitelist.txt"
var/list/whitelist
/proc/load_whitelist()
whitelist = list()
for(var/line in file2list(WHITELISTFILE))
if(!line)
continue
if(findtextEx(line,"#",1,2))
continue
whitelist += line
if(!whitelist.len)
whitelist = null
/proc/check_whitelist(var/ckey)
if(!whitelist)
return FALSE
. = (ckey in whitelist)
#undef WHITELISTFILE