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:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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.")
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
@@ -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
|
||||
@@ -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,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!"
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(.)
|
||||
|
||||
|
||||
|
||||
+399
-357
File diff suppressed because it is too large
Load Diff
@@ -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("!=", "<>")
|
||||
|
||||
@@ -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
|
||||
@@ -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)]->[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
|
||||
X << "<B><font color='blue'>PM: [key_name(src, X, 0)]->[key_name(C, X, 0)]:</B> \blue [keywordparsedmsg]</font>" //inform X
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
@@ -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.")
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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]'")
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user