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:
@@ -22,7 +22,7 @@
|
||||
// Takes care blood loss and regeneration
|
||||
/mob/living/carbon/human/handle_blood()
|
||||
|
||||
if(NOBLOOD in dna.species.specflags)
|
||||
if(NOBLOOD in dna.species.species_traits)
|
||||
bleed_rate = 0
|
||||
return
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
add_splatter_floor(src.loc, 1)
|
||||
|
||||
/mob/living/carbon/human/bleed(amt)
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
|
||||
@@ -162,8 +162,13 @@
|
||||
blood_data["trace_chem"] = list2params(temp_chem)
|
||||
if(mind)
|
||||
blood_data["mind"] = mind
|
||||
else if(last_mind)
|
||||
blood_data["mind"] = last_mind
|
||||
if(ckey)
|
||||
blood_data["ckey"] = ckey
|
||||
else if(last_mind)
|
||||
blood_data["ckey"] = ckey(last_mind.key)
|
||||
|
||||
if(!suiciding)
|
||||
blood_data["cloneable"] = 1
|
||||
blood_data["blood_type"] = copytext(dna.blood_type,1,0)
|
||||
@@ -188,7 +193,7 @@
|
||||
/mob/living/carbon/human/get_blood_id()
|
||||
if(dna.species.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.specflags) || (disabilities & NOCLONE))
|
||||
else if((NOBLOOD in dna.species.species_traits) || (disabilities & NOCLONE))
|
||||
return
|
||||
return "blood"
|
||||
|
||||
@@ -216,70 +221,43 @@
|
||||
return list("O-", "O+")
|
||||
if("L")
|
||||
return list("L")
|
||||
if("X")
|
||||
return list("X")
|
||||
|
||||
//to add a splatter of blood or other mob liquid.
|
||||
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
|
||||
if(get_blood_id() != "blood" && get_blood_id() != "xblood")
|
||||
if(get_blood_id() != "blood")
|
||||
return
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
|
||||
var/list/temp_blood_DNA
|
||||
if(small_drip)
|
||||
// Only a certain number of drips (or one large splatter) can be on a given turf.
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.dna.species.id == "xeno")
|
||||
var/obj/effect/decal/cleanable/xdrip/xdrop = locate() in T
|
||||
if(xdrop)
|
||||
if(xdrop.drips < 3)
|
||||
xdrop.drips++
|
||||
xdrop.overlays |= pick(xdrop.random_icon_states)
|
||||
xdrop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= xdrop.blood_DNA.Copy()
|
||||
qdel(xdrop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
xdrop = new(T)
|
||||
xdrop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T
|
||||
if(drop)
|
||||
if(drop.drips < 3)
|
||||
drop.drips++
|
||||
drop.overlays |= pick(drop.random_icon_states)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T)
|
||||
var/obj/effect/decal/cleanable/blood/drip/drop = locate() in T
|
||||
if(drop)
|
||||
if(drop.drips < 3)
|
||||
drop.drips++
|
||||
drop.overlays |= pick(drop.random_icon_states)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T)
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
return
|
||||
|
||||
// Find a blood decal or create a new one.
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in T
|
||||
if(!B)
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.dna.species.id == "xeno")
|
||||
B = new /obj/effect/decal/cleanable/xenoblood(T)
|
||||
else
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
else
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T)
|
||||
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
|
||||
if(temp_blood_DNA)
|
||||
B.blood_DNA |= temp_blood_DNA
|
||||
|
||||
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
|
||||
@@ -295,4 +273,4 @@
|
||||
T = get_turf(src)
|
||||
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
|
||||
if(!B)
|
||||
B = new(T)
|
||||
B = new(T)
|
||||
@@ -6,7 +6,7 @@
|
||||
density = 0
|
||||
anchored = 1
|
||||
invisibility = 60
|
||||
burn_state = LAVA_PROOF
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
/obj/effect/dummy/slaughter/relaymove(mob/user, direction)
|
||||
forceMove(get_step(src,direction))
|
||||
@@ -19,15 +19,12 @@
|
||||
/obj/effect/dummy/slaughter/singularity_act()
|
||||
return
|
||||
|
||||
/obj/effect/dummy/slaughter/Destroy()
|
||||
..()
|
||||
return QDEL_HINT_PUTINPOOL
|
||||
|
||||
|
||||
/mob/living/proc/phaseout(obj/effect/decal/cleanable/B)
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.l_hand || C.r_hand)
|
||||
for(var/obj/item/I in C.held_items)
|
||||
//TODO make it toggleable to either forcedrop the items, or deny
|
||||
//entry when holding them
|
||||
// literally only an option for carbons though
|
||||
@@ -53,7 +50,7 @@
|
||||
playsound(get_turf(src), 'sound/magic/enter_blood.ogg', 100, 1, -1)
|
||||
// Extinguish, unbuckle, stop being pulled, set our location into the
|
||||
// dummy object
|
||||
var/obj/effect/dummy/slaughter/holder = PoolOrNew(/obj/effect/dummy/slaughter,mobloc)
|
||||
var/obj/effect/dummy/slaughter/holder = new /obj/effect/dummy/slaughter(mobloc)
|
||||
src.ExtinguishMob()
|
||||
|
||||
// Keep a reference to whatever we're pulling, because forceMove()
|
||||
@@ -68,7 +65,7 @@
|
||||
return
|
||||
|
||||
// if the thing we're pulling isn't alive
|
||||
if (!(istype(pullee, /mob/living)))
|
||||
if (!isliving(pullee))
|
||||
return
|
||||
|
||||
var/mob/living/victim = pullee
|
||||
@@ -145,15 +142,14 @@
|
||||
|
||||
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
var/oldcolor = src.color
|
||||
//Makes the mob have the color of the blood pool it came out of
|
||||
var/newcolor = rgb(149, 10, 10)
|
||||
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
|
||||
src.color = rgb(43, 186, 0)
|
||||
else
|
||||
src.color = rgb(149, 10, 10)
|
||||
newcolor = rgb(43, 186, 0)
|
||||
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
|
||||
// but only for a few seconds
|
||||
spawn(30)
|
||||
src.color = oldcolor
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
@@ -172,7 +168,6 @@
|
||||
var/mob/living/carbon/C = src
|
||||
for(var/obj/item/weapon/bloodcrawl/BC in C)
|
||||
BC.flags = null
|
||||
C.unEquip(BC)
|
||||
qdel(BC)
|
||||
qdel(src.holder)
|
||||
src.holder = null
|
||||
|
||||
+54
-37
@@ -1,20 +1,20 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/obj/item/device/mmi
|
||||
name = "Man-Machine Interface"
|
||||
desc = "The Warrior's bland acronym, MMI, obscures the true horror of this monstrosity, that nevertheless has become standard-issue on Nanotrasen stations."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "mmi_empty"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "biotech=2;programming=3;engineering=2"
|
||||
var/braintype = "Cyborg"
|
||||
var/obj/item/device/radio/radio = null //Let's give it a radio.
|
||||
var/hacked = 0 //Whether or not this is a Syndicate MMI
|
||||
var/mob/living/carbon/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/brain/brainmob = null //The current occupant.
|
||||
var/mob/living/silicon/robot = null //Appears unused.
|
||||
var/obj/mecha = null //This does not appear to be used outside of reference in mecha.dm.
|
||||
var/obj/item/organ/brain/brain = null //The actual brain
|
||||
var/clockwork = FALSE //If this is a soul vessel
|
||||
var/datum/ai_laws/laws = new()
|
||||
var/force_replace_ai_name = FALSE
|
||||
|
||||
/obj/item/device/mmi/update_icon()
|
||||
if(brain)
|
||||
@@ -38,7 +38,9 @@
|
||||
radio = new(src) //Spawns a radio inside the MMI.
|
||||
radio.broadcasting = 0 //researching radio mmis turned the robofabs into radios because this didnt start as 0.
|
||||
|
||||
|
||||
/obj/item/device/mmi/Initialize()
|
||||
..()
|
||||
laws.set_laws_config()
|
||||
|
||||
/obj/item/device/mmi/attackby(obj/item/O, mob/user, params)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
@@ -51,9 +53,9 @@
|
||||
user << "<span class='warning'>You aren't sure where this brain came from, but you're pretty sure it's a useless brain!</span>"
|
||||
return
|
||||
|
||||
if(!user.unEquip(O))
|
||||
if(!user.transferItemToLoc(O, src))
|
||||
return
|
||||
var/mob/living/carbon/brain/B = newbrain.brainmob
|
||||
var/mob/living/brain/B = newbrain.brainmob
|
||||
if(!B.key)
|
||||
B.notify_ghost_cloning("Someone has put your brain in a MMI!", source = src)
|
||||
visible_message("[user] sticks \a [newbrain] into \the [src].")
|
||||
@@ -68,9 +70,6 @@
|
||||
living_mob_list += brainmob
|
||||
|
||||
brainmob.reset_perspective()
|
||||
if(clockwork)
|
||||
add_servant_of_ratvar(brainmob, TRUE)
|
||||
newbrain.loc = src //P-put your brain in it
|
||||
brain = newbrain
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
@@ -78,12 +77,11 @@
|
||||
|
||||
feedback_inc("cyborg_mmis_filled",1)
|
||||
|
||||
return
|
||||
|
||||
else if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
return
|
||||
..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/device/mmi/attack_self(mob/user)
|
||||
if(!brain)
|
||||
@@ -91,23 +89,27 @@
|
||||
user << "<span class='notice'>You toggle the MMI's radio system [radio.on==1 ? "on" : "off"].</span>"
|
||||
else
|
||||
user << "<span class='notice'>You unlock and upend the MMI, spilling the brain onto the floor.</span>"
|
||||
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.loc = brain //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
brain = null //No more brain in here
|
||||
|
||||
eject_brain(user)
|
||||
update_icon()
|
||||
name = "Man-Machine Interface"
|
||||
|
||||
/obj/item/device/mmi/proc/eject_brain(mob/user)
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
brainmob.loc = brain //Throw mob into brain.
|
||||
brainmob.stat = DEAD
|
||||
brainmob.emp_damage = 0
|
||||
brainmob.reset_perspective() //so the brainmob follows the brain organ instead of the mmi. And to update our vision
|
||||
living_mob_list -= brainmob //Get outta here
|
||||
dead_mob_list += brainmob
|
||||
brain.brainmob = brainmob //Set the brain to use the brainmob
|
||||
brainmob = null //Set mmi brainmob var to null
|
||||
if(user)
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
else
|
||||
brain.forceMove(get_turf(src))
|
||||
brain = null //No more brain in here
|
||||
|
||||
|
||||
/obj/item/device/mmi/proc/transfer_identity(mob/living/L) //Same deal as the regular brain proc. Used for human-->robot people.
|
||||
if(!brainmob)
|
||||
brainmob = new(src)
|
||||
@@ -115,9 +117,9 @@
|
||||
brainmob.real_name = L.real_name
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
brainmob.container = src
|
||||
|
||||
if(ishuman(L))
|
||||
@@ -133,6 +135,8 @@
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/proc/replacement_ai_name()
|
||||
return brainmob.name
|
||||
|
||||
/obj/item/device/mmi/verb/Toggle_Listening()
|
||||
set name = "Toggle Listening"
|
||||
@@ -151,7 +155,7 @@
|
||||
brainmob << "<span class='notice'>Radio is [radio.listening==1 ? "now" : "no longer"] receiving broadcast.</span>"
|
||||
|
||||
/obj/item/device/mmi/emp_act(severity)
|
||||
if(!brainmob)
|
||||
if(!brainmob || iscyborg(loc))
|
||||
return
|
||||
else
|
||||
switch(severity)
|
||||
@@ -165,18 +169,31 @@
|
||||
..()
|
||||
|
||||
/obj/item/device/mmi/Destroy()
|
||||
if(isrobot(loc))
|
||||
if(iscyborg(loc))
|
||||
var/mob/living/silicon/robot/borg = loc
|
||||
borg.mmi = null
|
||||
if(brainmob)
|
||||
qdel(brainmob)
|
||||
brainmob = null
|
||||
if(brain)
|
||||
qdel(brain)
|
||||
brain = null
|
||||
if(mecha)
|
||||
mecha = null
|
||||
if(radio)
|
||||
qdel(radio)
|
||||
radio = null
|
||||
return ..()
|
||||
|
||||
/obj/item/device/mmi/deconstruct(disassembled = TRUE)
|
||||
if(brain)
|
||||
eject_brain()
|
||||
qdel(src)
|
||||
|
||||
/obj/item/device/mmi/examine(mob/user)
|
||||
..()
|
||||
if(brainmob)
|
||||
var/mob/living/carbon/brain/B = brainmob
|
||||
var/mob/living/brain/B = brainmob
|
||||
if(!B.key || !B.mind || B.stat == DEAD)
|
||||
user << "<span class='warning'>The MMI indicates the brain is completely unresponsive.</span>"
|
||||
|
||||
@@ -189,10 +206,10 @@
|
||||
|
||||
/obj/item/device/mmi/syndie
|
||||
name = "Syndicate Man-Machine Interface"
|
||||
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs created with it, but doesn't fit in Nanotrasen AI cores."
|
||||
desc = "Syndicate's own brand of MMI. It enforces laws designed to help Syndicate agents achieve their goals upon cyborgs and AIs created with it."
|
||||
origin_tech = "biotech=4;programming=4;syndicate=2"
|
||||
hacked = 1
|
||||
|
||||
/obj/item/device/mmi/syndie/New()
|
||||
..()
|
||||
laws = new /datum/ai_laws/syndicate_override()
|
||||
radio.on = 0
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
|
||||
/mob/living/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/brain/New(loc)
|
||||
..()
|
||||
create_dna(src)
|
||||
stored_dna.initialize_dna(random_blood_type())
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
src.loc = OB
|
||||
OB.brainmob = src
|
||||
|
||||
|
||||
/mob/living/brain/proc/create_dna()
|
||||
stored_dna = new /datum/dna/stored(src)
|
||||
if(!stored_dna.species)
|
||||
var/rando_race = pick(config.roundstart_races)
|
||||
stored_dna.species = new rando_race()
|
||||
|
||||
/mob/living/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
|
||||
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
/mob/living/brain/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
/mob/living/brain/get_eye_protection()//no eyes
|
||||
return 2
|
||||
|
||||
/mob/living/brain/get_ear_protection()//no ears
|
||||
return 2
|
||||
|
||||
/mob/living/brain/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= HEALTH_THRESHOLD_DEAD)
|
||||
return 0
|
||||
|
||||
/mob/living/brain/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(stored_dna)
|
||||
stored_dna.real_name = real_name
|
||||
+36
-34
@@ -10,35 +10,35 @@
|
||||
vital = 1
|
||||
origin_tech = "biotech=5"
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
var/mob/living/carbon/brain/brainmob = null
|
||||
var/damaged_brain = 0 //whether the brain organ is damaged.
|
||||
var/mob/living/brain/brainmob = null
|
||||
var/damaged_brain = FALSE //whether the brain organ is damaged.
|
||||
var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go.
|
||||
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0)
|
||||
..()
|
||||
name = "brain"
|
||||
if(brainmob)
|
||||
if(M.key)
|
||||
M.ghostize()
|
||||
if(C.key)
|
||||
C.ghostize()
|
||||
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(M)
|
||||
brainmob.mind.transfer_to(C)
|
||||
else
|
||||
M.key = brainmob.key
|
||||
C.key = brainmob.key
|
||||
|
||||
qdel(brainmob)
|
||||
|
||||
//Update the body's icon so it doesnt appear debrained anymore
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
C.update_hair()
|
||||
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0)
|
||||
..()
|
||||
if(!special)
|
||||
transfer_identity(M)
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.update_hair(0)
|
||||
if(C.has_brain_worms())
|
||||
var/mob/living/simple_animal/borer/B = C.has_brain_worms()
|
||||
B.leave_victim() //Should remove borer if the brain is removed - RR
|
||||
transfer_identity(C)
|
||||
C.update_hair()
|
||||
|
||||
/obj/item/organ/brain/prepare_eat()
|
||||
return // Too important to eat.
|
||||
@@ -51,9 +51,9 @@
|
||||
brainmob.timeofhostdeath = L.timeofdeath
|
||||
if(L.has_dna())
|
||||
var/mob/living/carbon/C = L
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
if(L.mind && L.mind.current && (L.mind.current.stat == DEAD))
|
||||
L.mind.transfer_to(brainmob)
|
||||
brainmob << "<span class='notice'>You feel slightly disoriented. That's normal when you're just a brain.</span>"
|
||||
@@ -68,17 +68,20 @@
|
||||
|
||||
if(brainmob)
|
||||
if(brainmob.client)
|
||||
if(brainmob.health <= config.health_threshold_dead)
|
||||
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
user << "It's lifeless and severely damaged."
|
||||
else
|
||||
user << "You can feel the small spark of life still left in this one."
|
||||
else
|
||||
user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later."
|
||||
else
|
||||
user << "This one is completely devoid of life."
|
||||
if(decoy_override)
|
||||
user << "This one seems particularly lifeless. Perhaps it will regain some of its luster later."
|
||||
else
|
||||
user << "This one is completely devoid of life."
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
|
||||
if(!istype(M))
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/C, mob/user)
|
||||
if(!istype(C))
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
@@ -86,31 +89,30 @@
|
||||
if(user.zone_selected != "head")
|
||||
return ..()
|
||||
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(istype(H) && ((H.head && H.head.flags_cover & HEADCOVERSEYES) || (H.wear_mask && H.wear_mask.flags_cover & MASKCOVERSEYES) || (H.glasses && H.glasses.flags & GLASSESCOVERSEYES)))
|
||||
if((C.head && (C.head.flags_cover & HEADCOVERSEYES)) || (C.wear_mask && (C.wear_mask.flags_cover & MASKCOVERSEYES)) || (C.glasses && (C.glasses.flags & GLASSESCOVERSEYES)))
|
||||
user << "<span class='warning'>You're going to need to remove their head cover first!</span>"
|
||||
return
|
||||
|
||||
//since these people will be dead M != usr
|
||||
|
||||
if(!M.getorgan(/obj/item/organ/brain))
|
||||
if(istype(H) && !H.get_bodypart("head"))
|
||||
if(!C.getorgan(/obj/item/organ/brain))
|
||||
if(!C.get_bodypart("head"))
|
||||
return
|
||||
user.drop_item()
|
||||
var/msg = "[M] has [src] inserted into \his head by [user]."
|
||||
if(M == user)
|
||||
msg = "[user] inserts [src] into \his head!"
|
||||
var/msg = "[C] has [src] inserted into [C.p_their()] head by [user]."
|
||||
if(C == user)
|
||||
msg = "[user] inserts [src] into [user.p_their()] head!"
|
||||
|
||||
M.visible_message("<span class='danger'>[msg]</span>",
|
||||
C.visible_message("<span class='danger'>[msg]</span>",
|
||||
"<span class='userdanger'>[msg]</span>")
|
||||
|
||||
if(M != user)
|
||||
M << "<span class='notice'>[user] inserts [src] into your head.</span>"
|
||||
user << "<span class='notice'>You insert [src] into [M]'s head.</span>"
|
||||
if(C != user)
|
||||
C << "<span class='notice'>[user] inserts [src] into your head.</span>"
|
||||
user << "<span class='notice'>You insert [src] into [C]'s head.</span>"
|
||||
else
|
||||
user << "<span class='notice'>You insert [src] into your head.</span>" //LOL
|
||||
|
||||
Insert(M)
|
||||
Insert(C)
|
||||
else
|
||||
..()
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/brain/death(gibbed)
|
||||
/mob/living/brain/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/gib()
|
||||
/mob/living/brain/gib()
|
||||
if(container)
|
||||
qdel(container)//Gets rid of the MMI if there is one
|
||||
if(loc)
|
||||
@@ -0,0 +1,34 @@
|
||||
/datum/emote/brain
|
||||
mob_type_allowed_typecache = list(/mob/living/brain)
|
||||
mob_type_blacklist_typecache = list()
|
||||
|
||||
/datum/emote/brain/can_run_emote(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/brain/B = user
|
||||
if(!istype(B) || (!(B.container && istype(B.container, /obj/item/device/mmi))))
|
||||
return FALSE
|
||||
|
||||
/datum/emote/brain/alarm
|
||||
key = "alarm"
|
||||
message = "sounds an alarm."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/brain/alert
|
||||
key = "alert"
|
||||
message = "lets out a distressed noise."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/brain/flash
|
||||
key = "flash"
|
||||
message = "lights' blink."
|
||||
|
||||
/datum/emote/brain/notice
|
||||
key = "notice"
|
||||
message = "plays a loud tone."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/brain/whistle
|
||||
key = "whistle"
|
||||
key_third_person = "whistles"
|
||||
message = "whistles."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
+8
-19
@@ -1,5 +1,5 @@
|
||||
|
||||
/mob/living/carbon/brain/Life()
|
||||
/mob/living/brain/Life()
|
||||
set invisibility = 0
|
||||
set background = BACKGROUND_ENABLED
|
||||
|
||||
@@ -10,19 +10,10 @@
|
||||
. = ..()
|
||||
handle_emp_damage()
|
||||
|
||||
/mob/living/carbon/brain/handle_breathing()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_mutations_and_radiation()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_environment(datum/gas_mixture/environment)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/update_stat()
|
||||
/mob/living/brain/update_stat()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(health <= config.health_threshold_dead)
|
||||
if(health <= HEALTH_THRESHOLD_DEAD)
|
||||
if(stat != DEAD)
|
||||
death()
|
||||
var/obj/item/organ/brain/BR
|
||||
@@ -34,27 +25,25 @@
|
||||
BR.damaged_brain = 1 //beaten to a pulp
|
||||
|
||||
/* //currently unused feature, since brain outside a mmi is always dead.
|
||||
/mob/living/carbon/brain/proc/handle_brain_revival_life()
|
||||
/mob/living/brain/proc/handle_brain_revival_life()
|
||||
if(stat != DEAD)
|
||||
if(config.revival_brain_life != -1)
|
||||
if( !container && (world.time - timeofhostdeath) > config.revival_brain_life)
|
||||
death()
|
||||
*/
|
||||
|
||||
/mob/living/carbon/brain/proc/handle_emp_damage()
|
||||
/mob/living/brain/proc/handle_emp_damage()
|
||||
if(emp_damage)
|
||||
if(stat == DEAD)
|
||||
emp_damage = 0
|
||||
else
|
||||
emp_damage = max(emp_damage-1, 0)
|
||||
|
||||
/mob/living/carbon/brain/handle_status_effects()
|
||||
/mob/living/brain/handle_status_effects()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_disabilities()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/handle_changeling()
|
||||
/mob/living/brain/handle_disabilities()
|
||||
return
|
||||
|
||||
|
||||
|
||||
+26
-33
@@ -5,7 +5,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
desc = "A cube of shining metal, four inches to a side and covered in shallow grooves."
|
||||
icon = 'icons/obj/assemblies.dmi'
|
||||
icon_state = "posibrain"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
origin_tech = "biotech=3;programming=3;plasmatech=2"
|
||||
var/notified = 0
|
||||
var/askDelay = 600 //one minute
|
||||
@@ -14,6 +14,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
req_access = list(access_robotics)
|
||||
mecha = null//This does not appear to be used outside of reference in mecha.dm.
|
||||
braintype = "Android"
|
||||
var/autoping = TRUE //if it pings on creation immediately
|
||||
var/begin_activation_message = "<span class='notice'>You carefully locate the manual activation switch and start the positronic brain's boot process.</span>"
|
||||
var/success_message = "<span class='notice'>The positronic brain pings, and its lights start flashing. Success!</span>"
|
||||
var/fail_message = "<span class='notice'>The positronic brain buzzes quietly, and the golden lights fade away. Perhaps you could try again?</span>"
|
||||
@@ -25,6 +26,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
var/new_mob_message = "<span class='notice'>The positronic brain chimes quietly.</span>"
|
||||
var/dead_message = "<span class='deadsay'>It appears to be completely inactive. The reset light is blinking.</span>"
|
||||
var/list/fluff_names = list("PBU","HIU","SINA","ARMA","OSI","HBL","MSO","RR","CHRI","CDB","HG","XSI","ORNG","GUN","KOR","MET","FRE","XIS","SLI","PKP","HOG","RZH","GOOF","MRPR","JJR","FIRC","INC","PHL","BGB","ANTR","MIW","WJ","JRD","CHOC","ANCL","JLLO","JNLG","KOS","TKRG","XAL","STLP","CBOS","DUNC","FXMC","DRSD")
|
||||
var/picked_fluff_name //which fluff name we picked
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/Topic(href, href_list)
|
||||
@@ -38,7 +40,7 @@ var/global/posibrain_notif_cooldown = 0
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/effects/ghost2.ogg':null, enter_link = "<a href=?src=\ref[src];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK)
|
||||
if(!newlymade)
|
||||
posibrain_notif_cooldown = 1
|
||||
addtimer(src, "reset_posibrain_cooldown", askDelay, FALSE)
|
||||
addtimer(CALLBACK(src, .proc/reset_posibrain_cooldown), askDelay)
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/reset_posibrain_cooldown()
|
||||
posibrain_notif_cooldown = 0
|
||||
@@ -79,11 +81,10 @@ var/global/posibrain_notif_cooldown = 0
|
||||
name = "[initial(name)] ([C])"
|
||||
brainmob.name = C.real_name
|
||||
brainmob.real_name = C.real_name
|
||||
brainmob.dna = C.dna
|
||||
if(C.has_dna())
|
||||
if(!brainmob.dna)
|
||||
brainmob.dna = new /datum/dna(brainmob)
|
||||
C.dna.copy_dna(brainmob.dna)
|
||||
if(!brainmob.stored_dna)
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
brainmob.timeofhostdeath = C.timeofdeath
|
||||
brainmob.stat = CONSCIOUS
|
||||
if(brainmob.mind)
|
||||
@@ -94,61 +95,53 @@ var/global/posibrain_notif_cooldown = 0
|
||||
brainmob.mind.remove_all_antag()
|
||||
brainmob.mind.wipe_memory()
|
||||
update_icon()
|
||||
return
|
||||
|
||||
/obj/item/device/mmi/posibrain/proc/transfer_personality(mob/candidate)
|
||||
if(used || (brainmob && brainmob.key)) //Prevents hostile takeover if two ghosts get the prompt or link for the same brain.
|
||||
candidate << "This brain has already been taken! Please try your possesion again later!"
|
||||
return
|
||||
candidate << "This brain has already been taken! Please try your possession again later!"
|
||||
return FALSE
|
||||
notified = 0
|
||||
brainmob.ckey = candidate.ckey
|
||||
if(candidate.mind && !isobserver(candidate))
|
||||
candidate.mind.transfer_to(brainmob)
|
||||
else
|
||||
brainmob.ckey = candidate.ckey
|
||||
name = "[initial(name)] ([brainmob.name])"
|
||||
brainmob << welcome_message
|
||||
brainmob.mind.assigned_role = new_role
|
||||
brainmob.stat = CONSCIOUS
|
||||
dead_mob_list -= brainmob
|
||||
living_mob_list += brainmob
|
||||
if(clockwork)
|
||||
add_servant_of_ratvar(brainmob, TRUE)
|
||||
|
||||
visible_message(new_mob_message)
|
||||
update_icon()
|
||||
used = 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/device/mmi/posibrain/examine()
|
||||
|
||||
set src in oview()
|
||||
|
||||
if(!usr || !src)
|
||||
return
|
||||
if( (usr.disabilities & BLIND || usr.stat) && !istype(usr,/mob/dead/observer) )
|
||||
usr << "<span class='notice'>Something is there but you can't see it.</span>"
|
||||
return
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n[desc]\n"
|
||||
msg += "<span class='warning'>"
|
||||
|
||||
/obj/item/device/mmi/posibrain/examine(mob/user)
|
||||
. = ..()
|
||||
var/msg
|
||||
if(brainmob && brainmob.key)
|
||||
switch(brainmob.stat)
|
||||
if(CONSCIOUS)
|
||||
if(!src.brainmob.client)
|
||||
msg += "It appears to be in stand-by mode.\n" //afk
|
||||
msg = "It appears to be in stand-by mode." //afk
|
||||
if(DEAD)
|
||||
msg += "<span class='deadsay'>It appears to be completely inactive.</span>\n"
|
||||
msg = "<span class='deadsay'>It appears to be completely inactive.</span>"
|
||||
else
|
||||
msg += "[dead_message]\n"
|
||||
msg += "<span class='info'>*---------*</span>"
|
||||
usr << msg
|
||||
return
|
||||
msg = "[dead_message]"
|
||||
|
||||
user << msg
|
||||
|
||||
/obj/item/device/mmi/posibrain/New()
|
||||
brainmob = new(src)
|
||||
brainmob.name = "[pick(fluff_names)]-[rand(100, 999)]"
|
||||
picked_fluff_name = pick(fluff_names)
|
||||
brainmob.name = "[picked_fluff_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.loc = src
|
||||
brainmob.container = src
|
||||
ping_ghosts("created", TRUE)
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
..()
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/brain/say(message)
|
||||
/mob/living/brain/say(message)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))
|
||||
return //No MMI, can't speak, bucko./N
|
||||
else
|
||||
@@ -9,15 +9,16 @@
|
||||
message = Gibberish(message, (emp_damage*6))//scrambles the message, gets worse when emp_damage is higher
|
||||
..()
|
||||
|
||||
/mob/living/carbon/brain/radio(message, message_mode, list/spans)
|
||||
/mob/living/brain/radio(message, message_mode, list/spans)
|
||||
if(message_mode && istype(container, /obj/item/device/mmi))
|
||||
var/obj/item/device/mmi/R = container
|
||||
if(R.radio)
|
||||
R.radio.talk_into(src, message, , spans)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
/mob/living/carbon/brain/lingcheck()
|
||||
/mob/living/brain/lingcheck()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/treat_message(message)
|
||||
/mob/living/brain/treat_message(message)
|
||||
message = capitalize(message)
|
||||
return message
|
||||
+8
-13
@@ -4,35 +4,30 @@
|
||||
|
||||
/////////////////////////////////// EAR DAMAGE ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/adjustEarDamage()
|
||||
/mob/living/brain/adjustEarDamage()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/setEarDamage() // no ears to damage or heal
|
||||
/mob/living/brain/setEarDamage() // no ears to damage or heal
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLIND ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blind_eyes() // no eyes to damage or heal
|
||||
/mob/living/brain/blind_eyes() // no eyes to damage or heal
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blindness()
|
||||
/mob/living/brain/adjust_blindness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blindness()
|
||||
/mob/living/brain/set_blindness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// EYE_BLURRY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/blur_eyes()
|
||||
/mob/living/brain/blur_eyes()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/adjust_blurriness()
|
||||
/mob/living/brain/adjust_blurriness()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/set_blurriness()
|
||||
/mob/living/brain/set_blurriness()
|
||||
return
|
||||
|
||||
/////////////////////////////////// BLIND DISABILITY ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/brain/become_blind()
|
||||
return
|
||||
@@ -7,10 +7,10 @@
|
||||
name = "alien"
|
||||
voice_name = "alien"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
gender = FEMALE
|
||||
gender = FEMALE //All xenos are girls!!
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = 2
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
languages_spoken = ALIEN
|
||||
languages_understood = ALIEN
|
||||
sight = SEE_MOBS
|
||||
@@ -19,7 +19,7 @@
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
var/deathNotified = 0
|
||||
devourable = 1
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
@@ -38,35 +38,22 @@
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
create_bodyparts() //initialize bodyparts
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
create_internal_organs()
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/nightvisiontoggle(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums
|
||||
return -10
|
||||
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire
|
||||
if(amount > 0)
|
||||
..(amount * 2)
|
||||
else
|
||||
..(amount)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/check_eye_prot()
|
||||
return ..() + 2
|
||||
|
||||
/mob/living/carbon/alien/getToxLoss()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
@@ -101,35 +88,6 @@
|
||||
else
|
||||
clear_alert("alien_fire")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target)
|
||||
..()
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
adjustEarDamage(30,120)
|
||||
|
||||
if(3)
|
||||
adjustBruteLoss(30)
|
||||
if (prob(50))
|
||||
Paralyse(1)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
|
||||
if(..())
|
||||
return
|
||||
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/reagent_check(datum/reagent/R) //can metabolize all reagents
|
||||
return 0
|
||||
|
||||
@@ -229,3 +187,5 @@ Des: Removes all infected images from the alien.
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
|
||||
/mob/living/carbon/alien/can_hold_items()
|
||||
return has_fine_manipulation
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
|
||||
/mob/living/carbon/alien/get_eye_protection()
|
||||
return ..() + 2 //potential cyber implants + natural eye protection
|
||||
|
||||
/mob/living/carbon/alien/get_ear_protection()
|
||||
return 2 //no ears
|
||||
|
||||
/mob/living/carbon/alien/hitby(atom/movable/AM, skipcatch, hitpush)
|
||||
..(AM, skipcatch = 1, hitpush = 0)
|
||||
|
||||
@@ -7,11 +14,7 @@ As such, they can either help or harm other aliens. Help works like the human he
|
||||
In all, this is a lot like the monkey code. /N
|
||||
*/
|
||||
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
|
||||
if(!ticker || !ticker.mode)
|
||||
M << "You cannot attack people before the game has started."
|
||||
return
|
||||
|
||||
if (istype(loc, /turf) && istype(loc.loc, /area/start))
|
||||
if(isturf(loc) && istype(loc.loc, /area/start))
|
||||
M << "No attacking people at spawn, you jackass."
|
||||
return
|
||||
|
||||
@@ -23,24 +26,22 @@ In all, this is a lot like the monkey code. /N
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake it up!</span>")
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
|
||||
|
||||
if ("grab")
|
||||
grabbedby(M)
|
||||
|
||||
else
|
||||
if (health > 0)
|
||||
M.do_attack_animation(src)
|
||||
if(health > 0)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
|
||||
var/damage = 1
|
||||
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
adjustBruteLoss(1)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
M << "<span class='warning'>[name] is too injured for that.</span>"
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
@@ -56,8 +57,11 @@ In all, this is a lot like the monkey code. /N
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if ("harm", "disarm")
|
||||
M.do_attack_animation(src)
|
||||
if ("harm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
return 1
|
||||
if("disarm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
@@ -65,9 +69,8 @@ In all, this is a lot like the monkey code. /N
|
||||
/mob/living/carbon/alien/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(..())
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(rand(1, 3))
|
||||
updatehealth()
|
||||
return
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(rand(1, 3), BRUTE, affecting)
|
||||
|
||||
|
||||
/mob/living/carbon/alien/attack_animal(mob/living/simple_animal/M)
|
||||
@@ -96,3 +99,28 @@ In all, this is a lot like the monkey code. /N
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/alien/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
take_overall_damage(60, 60)
|
||||
adjustEarDamage(30,120)
|
||||
|
||||
if(3)
|
||||
take_overall_damage(30,0)
|
||||
if(prob(50))
|
||||
Paralyse(1)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
|
||||
return 0//aliens are immune to acid.
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/getToxLoss()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE) //alien immune to tox damage
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/alien/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE) // Weak to Fire
|
||||
if(amount > 0)
|
||||
amount *= 2
|
||||
. = ..()
|
||||
|
||||
|
||||
|
||||
//aliens are immune to stamina damage.
|
||||
/mob/living/carbon/alien/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return
|
||||
@@ -1,25 +1,14 @@
|
||||
/mob/living/carbon/alien/spawn_gibs()
|
||||
xgibs(loc, viruses)
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/xeno(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/xenobodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/gib_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-a"))
|
||||
new /obj/effect/overlay/temp/gib_animation(loc, "gibbed-a")
|
||||
|
||||
/mob/living/carbon/alien/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-a"))
|
||||
|
||||
/mob/living/carbon/alien/proc/deathNotice(var/area/AR, var/turf/T)
|
||||
if(src.z == 2) //Admin fuckery can continue without giving false death rattles to aliens on station or elsewhere.
|
||||
return
|
||||
src.deathNotified = 1
|
||||
T = get_turf(src)
|
||||
var/mob/living/carbon/alien/A
|
||||
for(A in world)
|
||||
A << "<span class='userdanger'>[src.name] has died at [T.loc.name]! </span>"
|
||||
|
||||
/mob/living/carbon/alien/death(gibbed)
|
||||
if(!deathNotified)
|
||||
deathNotice()
|
||||
..()
|
||||
new /obj/effect/overlay/temp/dust_animation(loc, "dust-a")
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/datum/emote/living/alien
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/alien)
|
||||
|
||||
/datum/emote/living/alien/gnarl
|
||||
key = "gnarl"
|
||||
key_third_person = "gnarls"
|
||||
message = "gnarls and shows its teeth..."
|
||||
|
||||
/datum/emote/living/alien/hiss
|
||||
key = "hiss"
|
||||
key_third_person = "hisses"
|
||||
message_alien = "hisses."
|
||||
message_larva = "hisses softly."
|
||||
|
||||
/datum/emote/living/alien/hiss/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(. && isalienadult(user))
|
||||
playsound(user.loc, "hiss", 40, 1, 1)
|
||||
|
||||
/datum/emote/living/alien/roar
|
||||
key = "roar"
|
||||
key_third_person = "roars"
|
||||
message_alien = "roars"
|
||||
message_larva = "sofly roars"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
/datum/emote/living/alien/roar/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(. && isalienadult(user))
|
||||
playsound(user.loc, 'sound/voice/hiss5.ogg', 40, 1, 1)
|
||||
@@ -11,7 +11,6 @@ Doesn't work on other aliens/AI.*/
|
||||
panel = "Alien"
|
||||
var/plasma_cost = 0
|
||||
var/check_turf = 0
|
||||
|
||||
var/has_action = 1
|
||||
var/datum/action/spell_action/alien/action = null
|
||||
var/action_icon = 'icons/mob/actions.dmi'
|
||||
@@ -49,7 +48,7 @@ Doesn't work on other aliens/AI.*/
|
||||
if(!silent)
|
||||
user << "<span class='noticealien'>Not enough plasma stored.</span>"
|
||||
return 0
|
||||
if(check_turf && (!isturf(user.loc) || istype(user.loc, /turf/open/space)))
|
||||
if(check_turf && (!isturf(user.loc) || isspaceturf(user.loc)))
|
||||
if(!silent)
|
||||
user << "<span class='noticealien'>Bad place for a garden!</span>"
|
||||
return 0
|
||||
@@ -64,7 +63,7 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/plant/fire(mob/living/carbon/user)
|
||||
if(locate(/obj/structure/alien/weeds/node) in get_turf(user))
|
||||
src << "There's already a weed node here."
|
||||
user << "There's already a weed node here."
|
||||
return 0
|
||||
user.visible_message("<span class='alertalien'>[user] has planted some alien weeds!</span>")
|
||||
new/obj/structure/alien/weeds/node(user.loc)
|
||||
@@ -123,14 +122,14 @@ Doesn't work on other aliens/AI.*/
|
||||
if (get_dist(user,M) <= 1)
|
||||
M.adjustPlasma(amount)
|
||||
user.adjustPlasma(-amount)
|
||||
M << "<span class='noticealien'>[user] has transfered [amount] plasma to you.</span>"
|
||||
user << "<span class='noticealien'>You trasfer [amount] plasma to [M]</span>"
|
||||
M << "<span class='noticealien'>[user] has transferred [amount] plasma to you.</span>"
|
||||
user << "<span class='noticealien'>You transfer [amount] plasma to [M]</span>"
|
||||
else
|
||||
user << "<span class='noticealien'>You need to be closer!</span>"
|
||||
return
|
||||
|
||||
/obj/effect/proc_holder/alien/acid
|
||||
name = "Corrossive Acid"
|
||||
name = "Corrosive Acid"
|
||||
desc = "Drench an object in acid, destroying it over time."
|
||||
plasma_cost = 200
|
||||
action_icon_state = "alien_acid"
|
||||
@@ -141,30 +140,16 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/acid/on_lose(mob/living/carbon/user)
|
||||
user.verbs.Remove(/mob/living/carbon/proc/corrosive_acid)
|
||||
|
||||
/obj/effect/proc_holder/alien/acid/proc/corrode(target,mob/living/carbon/user = usr)
|
||||
/obj/effect/proc_holder/alien/acid/proc/corrode(atom/target,mob/living/carbon/user = usr)
|
||||
if(target in oview(1,user))
|
||||
// OBJ CHECK
|
||||
if(isobj(target))
|
||||
var/obj/I = target
|
||||
if(I.unacidable) //So the aliens don't destroy energy fields/singularies/other aliens/etc with their acid.
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
// TURF CHECK
|
||||
else if(istype(target, /turf))
|
||||
var/turf/T = target
|
||||
// R WALL
|
||||
if(istype(T, /turf/closed/wall/r_wall))
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
// R FLOOR
|
||||
if(istype(T, /turf/open/floor/engine))
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
return 0
|
||||
else// Not a type we can acid.
|
||||
if(target.acid_act(200, 100))
|
||||
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
|
||||
return 1
|
||||
else
|
||||
user << "<span class='noticealien'>You cannot dissolve this object.</span>"
|
||||
|
||||
|
||||
return 0
|
||||
new /obj/effect/acid(get_turf(target), target)
|
||||
user.visible_message("<span class='alertalien'>[user] vomits globs of vile stuff all over [target]. It begins to sizzle and melt under the bubbling mess of acid!</span>")
|
||||
return 1
|
||||
else
|
||||
src << "<span class='noticealien'>Target is too far away.</span>"
|
||||
return 0
|
||||
@@ -172,8 +157,10 @@ Doesn't work on other aliens/AI.*/
|
||||
|
||||
/obj/effect/proc_holder/alien/acid/fire(mob/living/carbon/alien/user)
|
||||
var/O = input("Select what to dissolve:","Dissolve",null) as obj|turf in oview(1,user)
|
||||
if(!O) return 0
|
||||
return corrode(O,user)
|
||||
if(!O || user.incapacitated())
|
||||
return 0
|
||||
else
|
||||
return corrode(O,user)
|
||||
|
||||
/mob/living/carbon/proc/corrosive_acid(O as obj|turf in oview(1)) // right click menu verb ugh
|
||||
set name = "Corrossive Acid"
|
||||
@@ -191,39 +178,40 @@ Doesn't work on other aliens/AI.*/
|
||||
name = "Spit Neurotoxin"
|
||||
desc = "Spits neurotoxin at someone, paralyzing them for a short time."
|
||||
action_icon_state = "alien_neurotoxin_0"
|
||||
var/active = 0
|
||||
active = FALSE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/fire(mob/living/carbon/user)
|
||||
var/message
|
||||
if(active)
|
||||
user.ranged_ability = null
|
||||
user << "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
active = 0
|
||||
else if(user.ranged_ability && user.ranged_ability != src)
|
||||
user << "<span class='warning'>You already have another aimed ability readied! Cancel it first."
|
||||
return
|
||||
message = "<span class='notice'>You empty your neurotoxin gland.</span>"
|
||||
remove_ranged_ability(message)
|
||||
else
|
||||
user.ranged_ability = src
|
||||
active = 1
|
||||
user << "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
message = "<span class='notice'>You prepare your neurotoxin gland. <B>Left-click to fire at a target!</B></span>"
|
||||
add_ranged_ability(user, message, TRUE)
|
||||
|
||||
user.client.click_intercept = user.ranged_ability
|
||||
/obj/effect/proc_holder/alien/neurotoxin/update_icon()
|
||||
action.button_icon_state = "alien_neurotoxin_[active]"
|
||||
action.UpdateButtonIcon()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/carbon/user, params, atom/target)
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(user) || user.lying || user.stat)
|
||||
/obj/effect/proc_holder/alien/neurotoxin/InterceptClickOn(mob/living/caller, params, atom/target)
|
||||
if(..())
|
||||
return
|
||||
user.next_click = world.time + 6
|
||||
user.face_atom(target)
|
||||
var/p_cost = 50
|
||||
if(!iscarbon(ranged_ability_user) || ranged_ability_user.lying || ranged_ability_user.stat)
|
||||
remove_ranged_ability(ranged_ability_user)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/user = ranged_ability_user
|
||||
|
||||
if(user.getPlasma() < p_cost)
|
||||
user << "<span class='warning'>You need at least [p_cost] plasma to spit.</span>"
|
||||
remove_ranged_ability()
|
||||
return
|
||||
|
||||
var/turf/T = user.loc
|
||||
var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction
|
||||
if(!isturf(U) || !isturf(T))
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
user.visible_message("<span class='danger'>[user] spits neurotoxin!", "<span class='alertalien'>You spit neurotoxin.</span>")
|
||||
var/obj/item/projectile/bullet/neurotoxin/A = new /obj/item/projectile/bullet/neurotoxin(user.loc)
|
||||
@@ -233,12 +221,25 @@ Doesn't work on other aliens/AI.*/
|
||||
user.newtonian_move(get_dir(U, T))
|
||||
user.adjustPlasma(-p_cost)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/on_lose(mob/living/carbon/user)
|
||||
if(user.ranged_ability == src)
|
||||
user.ranged_ability = null
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/add_ranged_ability(mob/living/user, msg)
|
||||
..()
|
||||
if(isalienadult(user))
|
||||
var/mob/living/carbon/alien/humanoid/A = user
|
||||
A.drooling = 1
|
||||
A.update_icons()
|
||||
|
||||
/obj/effect/proc_holder/alien/neurotoxin/remove_ranged_ability(mob/living/user, msg)
|
||||
..()
|
||||
if(isalienadult(user))
|
||||
var/mob/living/carbon/alien/humanoid/A = user
|
||||
A.drooling = 0
|
||||
A.update_icons()
|
||||
|
||||
/obj/effect/proc_holder/alien/resin
|
||||
name = "Secrete Resin"
|
||||
@@ -308,7 +309,7 @@ Doesn't work on other aliens/AI.*/
|
||||
/obj/effect/proc_holder/alien/sneak
|
||||
name = "Sneak"
|
||||
desc = "Blend into the shadows to stalk your prey."
|
||||
var/active = 0
|
||||
active = 0
|
||||
|
||||
action_icon_state = "alien_sneak"
|
||||
|
||||
|
||||
@@ -3,15 +3,18 @@
|
||||
caste = "d"
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
icon_state = "aliend_s"
|
||||
icon_state = "aliend"
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/New()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/evolve(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/drone/movement_delay()
|
||||
@@ -36,7 +39,7 @@
|
||||
if(!isturf(user.loc))
|
||||
user << "<span class='notice'>You can't evolve here!</span>"
|
||||
return 0
|
||||
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal))
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal))
|
||||
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
return 1
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
caste = "h"
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
icon_state = "alienh_s"
|
||||
icon_state = "alienh"
|
||||
var/obj/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/New()
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small
|
||||
..()
|
||||
|
||||
@@ -45,17 +45,21 @@
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity(src) || !has_gravity(A))
|
||||
if(!has_gravity() || !A.has_gravity())
|
||||
src << "<span class='alertalien'>It is unsafe to leap without gravity!</span>"
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
update_icons()
|
||||
throw_at(A,MAX_ALIEN_LEAP_DIST,1, spin=0, diagonals_first = 1)
|
||||
leaping = 0
|
||||
update_icons()
|
||||
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin=0, diagonals_first = 1, callback = CALLBACK(src, .leap_end))
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
|
||||
leaping = 0
|
||||
weather_immunities -= "lava"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
|
||||
|
||||
@@ -63,18 +67,20 @@
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(istype(A, /mob/living))
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.check_shields(90, "the [name]", src, attack_type = THROWN_PROJECTILE_ATTACK))
|
||||
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
blocked = 1
|
||||
if(!blocked)
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Weaken(5)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
@@ -82,7 +88,7 @@
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
|
||||
weakened = 2
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
|
||||
@@ -11,14 +11,18 @@
|
||||
|
||||
real_name = name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/praetorian/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new /obj/effect/proc_holder/alien/royal/praetorian/evolve())
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/praetorian/movement_delay()
|
||||
. = ..()
|
||||
. += 1
|
||||
@@ -38,7 +42,7 @@
|
||||
if(node.recent_queen_death)
|
||||
user << "<span class='danger'>You are still too burdened with guilt to evolve into a queen.</span>"
|
||||
return 0
|
||||
if(!alien_type_present(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
if(new_xeno.client.prefs.unlock_content)
|
||||
|
||||
@@ -3,15 +3,19 @@
|
||||
caste = "s"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
icon_state = "aliens_s"
|
||||
icon_state = "aliens"
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/New()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
AddAbility(new /obj/effect/proc_holder/alien/sneak)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/sentinel/movement_delay()
|
||||
. = ..()
|
||||
|
||||
@@ -1,24 +1,12 @@
|
||||
/mob/living/carbon/alien/humanoid/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
|
||||
if(!deathNotified) //Did we message the other aliens that we died?
|
||||
deathNotice() //If not, do so now. This proc will change the deathNotified var to 1 so it never happens again.
|
||||
. = ..()
|
||||
|
||||
if(!gibbed)
|
||||
playsound(loc, 'sound/voice/hiss6.ogg', 80, 1, 1)
|
||||
visible_message("<span class='name'>[src]</span> lets out a waning guttural screech, green blood bubbling from its maw...")
|
||||
update_canmove()
|
||||
update_icons()
|
||||
status_flags |= CANPUSH
|
||||
if(fireloss >= (maxHealth/2))
|
||||
spawn(10)
|
||||
visible_message("<span class='warning'>[src] starts shaking...</span>")
|
||||
spawn(30)
|
||||
src.gib()
|
||||
|
||||
return ..()
|
||||
update_canmove()
|
||||
update_icons()
|
||||
status_flags |= CANPUSH
|
||||
|
||||
//When the alien queen dies, all others must pay the price for letting her die.
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/death(gibbed)
|
||||
@@ -32,20 +20,4 @@
|
||||
if(istype(node)) // just in case someone would ever add a diffirent node to hivenode slot
|
||||
node.queen_death()
|
||||
|
||||
return ..(gibbed)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/gib()
|
||||
visible_message("<span class='danger'>[src] explodes in a shower of acid blood and gibs!</span>")
|
||||
for(var/mob/living/M in viewers(2, src))
|
||||
if(ishuman(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
M.reagents.add_reagent("xblood",5)
|
||||
else if(ismonkey(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
M.reagents.add_reagent("xblood",5)
|
||||
else if(!isalien(M))
|
||||
M << "<span class='userdanger'>You're sprayed with acid blood!</span>"
|
||||
M.adjustFireLoss(15)
|
||||
..()
|
||||
return ..()
|
||||
@@ -1,8 +1,10 @@
|
||||
/mob/living/carbon/alien/humanoid
|
||||
name = "alien"
|
||||
icon_state = "alien_s"
|
||||
icon_state = "alien"
|
||||
pass_flags = PASSTABLE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 5, /obj/item/stack/sheet/animalhide/xeno = 1)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
limb_destroyer = 1
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
var/caste = ""
|
||||
@@ -13,89 +15,35 @@
|
||||
var/custom_pixel_x_offset = 0 //for admin fuckery.
|
||||
var/custom_pixel_y_offset = 0
|
||||
var/sneaking = 0 //For sneaky-sneaky mode and appropriate slowdown
|
||||
var/drooling = 0 //For Neruotoxic spit overlays
|
||||
bodyparts = list(/obj/item/bodypart/chest/alien, /obj/item/bodypart/head/alien, /obj/item/bodypart/l_arm/alien,
|
||||
/obj/item/bodypart/r_arm/alien, /obj/item/bodypart/r_leg/alien, /obj/item/bodypart/l_leg/alien)
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/humanoid/New()
|
||||
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
. = ..()
|
||||
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
|
||||
|
||||
/mob/living/carbon/alien/humanoid/emp_act(severity)
|
||||
if(r_store) r_store.emp_act(severity)
|
||||
if(l_store) l_store.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
adjustBruteLoss(15)
|
||||
var/hitverb = "punched"
|
||||
if(mob_size < MOB_SIZE_LARGE)
|
||||
Paralyse(1)
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
hitverb = "slammed"
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
switch(M.a_intent)
|
||||
if ("harm")
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>")
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
|
||||
Paralyse(2)
|
||||
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has weakened [src]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [src]!</span>")
|
||||
|
||||
if ("disarm")
|
||||
if (!lying)
|
||||
if (prob(5))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if (prob(50))
|
||||
drop_item()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to disarm [src]!</span>")
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
. = handcuffed
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/dat = {"
|
||||
var/list/dat = list()
|
||||
dat += {"
|
||||
<HR>
|
||||
<B><FONT size=3>[name]</FONT></B>
|
||||
<HR>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [l_hand ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [r_hand ? r_hand : "Nothing"]</A>
|
||||
<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"}
|
||||
<HR>"}
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a>"
|
||||
dat += "<BR><A href='?src=\ref[src];pouches=1'>Empty Pouches</A>"
|
||||
|
||||
if(handcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_handcuffed]'>Handcuffed</A>"
|
||||
@@ -106,7 +54,7 @@
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
user << browse(dat.Join(), "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
@@ -118,8 +66,8 @@
|
||||
visible_message("<span class='danger'>[usr] tries to empty [src]'s pouches.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pouches.</span>")
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY * 0.5))
|
||||
unEquip(r_store)
|
||||
unEquip(l_store)
|
||||
dropItemToGround(r_store)
|
||||
dropItemToGround(l_store)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I)
|
||||
playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free
|
||||
@@ -147,39 +95,29 @@
|
||||
else
|
||||
return initial(pixel_x)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/get_permeability_protection()
|
||||
return 0.8
|
||||
|
||||
/mob/living/carbon/alien/humanoid/alien_evolve(mob/living/carbon/alien/humanoid/new_xeno)
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
drop_all_held_items()
|
||||
for(var/atom/movable/A in stomach_contents)
|
||||
stomach_contents.Remove(A)
|
||||
new_xeno.stomach_contents.Add(A)
|
||||
A.loc = new_xeno
|
||||
..()
|
||||
|
||||
//For alien evolution/promotion procs. Checks for
|
||||
proc/alien_type_present(var/alienpath)
|
||||
//For alien evolution/promotion/queen finder procs. Checks for an active alien of that type
|
||||
/proc/get_alien_type(var/alienpath)
|
||||
for(var/mob/living/carbon/alien/humanoid/A in living_mob_list)
|
||||
if(!istype(A, alienpath))
|
||||
continue
|
||||
if(!A.key || A.stat == DEAD) //Only living aliens with a ckey are valid.
|
||||
continue
|
||||
return 1
|
||||
return 0
|
||||
return A
|
||||
return FALSE
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/check_breath(datum/gas_mixture/breath)
|
||||
if(breath && breath.total_moles() > 0 && !sneaking)
|
||||
playsound(get_turf(src), pick('sound/voice/lowHiss2.ogg', 'sound/voice/lowHiss3.ogg', 'sound/voice/lowHiss4.ogg'), 50, 0, -5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
|
||||
devour_mob(pulling, devour_time = 60)
|
||||
else
|
||||
..()
|
||||
@@ -0,0 +1,68 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/grabbedby(mob/living/carbon/user, supress_message = 0)
|
||||
if(user == src && pulling && grab_state >= GRAB_AGGRESSIVE && !pulling.anchored && iscarbon(pulling))
|
||||
devour_mob(pulling, devour_time = 60)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
adjustBruteLoss(15)
|
||||
var/hitverb = "punched"
|
||||
if(mob_size < MOB_SIZE_LARGE)
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
hitverb = "slammed"
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[user] has [hitverb] [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hitverb] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/humanoid/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
switch(M.a_intent)
|
||||
if ("harm")
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
|
||||
Paralyse(2)
|
||||
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has weakened [src]!</span>")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
add_logs(M, src, "attacked")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has attempted to punch [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
if ("disarm")
|
||||
if (!lying)
|
||||
if (prob(5))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if (prob(50))
|
||||
drop_item()
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='userdanger'>[M] has attempted to disarm [src]!</span>",\
|
||||
"<span class='userdanger'>[M] has attempted to disarm [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(!no_effect && !visual_effect_icon)
|
||||
visual_effect_icon = ATTACK_EFFECT_CLAW
|
||||
..()
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/alien/humanoid/unEquip(obj/item/I)
|
||||
/mob/living/carbon/alien/humanoid/doUnEquip(obj/item/I)
|
||||
. = ..()
|
||||
if(!. || !I)
|
||||
return
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/proc/adjust_body_temperature(current, loc_temp, boost)
|
||||
var/temperature = current
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
//Common stuffs for Praetorian and Queen
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
status_flags = 0
|
||||
ventcrawler = 0 //pull over that ass too fat
|
||||
ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
|
||||
unique_name = 0
|
||||
pixel_x = -16
|
||||
bubble_icon = "alienroyal"
|
||||
@@ -22,7 +22,27 @@
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
icon_state = "alienq"
|
||||
var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite()
|
||||
|
||||
/datum/action/small_sprite
|
||||
name = "Toggle Giant Sprite - Others will always see you as giant"
|
||||
button_icon_state = "smallqueen"
|
||||
background_icon_state = "bg_alien"
|
||||
var/small = 0
|
||||
|
||||
/datum/action/small_sprite/Trigger()
|
||||
..()
|
||||
if(!small)
|
||||
var/image/I = image(icon = 'icons/mob/alien.dmi' , icon_state = "alienq_running", loc = owner)
|
||||
I.override = 1
|
||||
I.pixel_x -= owner.pixel_x
|
||||
I.pixel_y -= owner.pixel_y
|
||||
owner.add_alt_appearance("smallqueen", I, list(owner))
|
||||
|
||||
small = 1
|
||||
else
|
||||
owner.remove_alt_appearance("smallqueen")
|
||||
small = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/New()
|
||||
//there should only be one queen
|
||||
@@ -37,18 +57,22 @@
|
||||
|
||||
real_name = src.name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
smallsprite.Grant(src)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
internal_organs += new /obj/item/organ/alien/eggsac
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
|
||||
. = ..()
|
||||
. += 5
|
||||
. += 3
|
||||
|
||||
//Queen verbs
|
||||
/obj/effect/proc_holder/alien/lay_egg
|
||||
@@ -78,7 +102,7 @@
|
||||
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
|
||||
var/obj/item/queenpromote/prom
|
||||
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
user << "<span class='noticealien'>You already have a Praetorian!</span>"
|
||||
return 0
|
||||
else
|
||||
@@ -99,14 +123,14 @@
|
||||
name = "\improper royal parasite"
|
||||
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
|
||||
icon_state = "alien_medal"
|
||||
flags = ABSTRACT|NODROP
|
||||
flags = ABSTRACT|NODROP|DROPDEL
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
|
||||
if(!isalienadult(M) || istype(M, /mob/living/carbon/alien/humanoid/royal))
|
||||
user << "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>"
|
||||
return
|
||||
if(alien_type_present(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
user << "<span class='noticealien'>You already have a Praetorian!</span>"
|
||||
return
|
||||
|
||||
@@ -161,4 +185,4 @@
|
||||
desc = ""
|
||||
icon_state = "alienq"
|
||||
caste = "q"
|
||||
update_icons()
|
||||
update_icons()
|
||||
|
||||
@@ -20,8 +20,12 @@
|
||||
icon_state = "alien[caste]_sleep"
|
||||
else if(mob_size == MOB_SIZE_LARGE)
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit_[caste]")
|
||||
else
|
||||
icon_state = "alien[caste]_s"
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit")
|
||||
|
||||
if(leaping)
|
||||
if(alt_icon == initial(alt_icon))
|
||||
@@ -38,6 +42,8 @@
|
||||
alt_icon = old_icon
|
||||
pixel_x = get_standard_pixel_x_offset(lying)
|
||||
pixel_y = get_standard_pixel_y_offset(lying)
|
||||
update_inv_hands()
|
||||
update_inv_handcuffed()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/regenerate_icons()
|
||||
if(!..())
|
||||
@@ -50,28 +56,40 @@
|
||||
..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
var/cuff_icon = "aliencuff"
|
||||
var/dmi_file = 'icons/mob/alien.dmi'
|
||||
|
||||
if(mob_size == MOB_SIZE_LARGE)
|
||||
cuff_icon = "aliencuff_[caste]"
|
||||
dmi_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image(dmi_file,icon_state= cuff_icon, layer =-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
//Royals have bigger sprites, so inhand things must be handled differently.
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_r_hand()
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_hands()
|
||||
..()
|
||||
remove_overlay(R_HAND_LAYER)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
remove_overlay(HANDS_LAYER)
|
||||
var/list/hands = list()
|
||||
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-R_HAND_LAYER)
|
||||
overlays_standing[R_HAND_LAYER] = I
|
||||
|
||||
apply_overlay(R_HAND_LAYER)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_l_hand()
|
||||
..()
|
||||
remove_overlay(L_HAND_LAYER)
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
if(l_hand)
|
||||
var/itm_state = l_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = l_hand.icon_state
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-HANDS_LAYER)
|
||||
hands += I
|
||||
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_l", "layer"=-L_HAND_LAYER)
|
||||
overlays_standing[L_HAND_LAYER] = I
|
||||
apply_overlay(L_HAND_LAYER)
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
var/image/I = image("icon" = alt_inhands_file , "icon_state"="[itm_state][caste]_r", "layer"=-HANDS_LAYER)
|
||||
hands += I
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
@@ -1,10 +1,22 @@
|
||||
/mob/living/carbon/alien/larva/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
icon_state = "larva_dead"
|
||||
|
||||
if(!gibbed)
|
||||
visible_message("<span class='name'>[src]</span> lets out a waning high-pitched cry.")
|
||||
. = ..()
|
||||
|
||||
return ..(gibbed)
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/larva(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/larvabodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/larva/gib_animation()
|
||||
new /obj/effect/overlay/temp/gib_animation(loc, "gibbed-l")
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/larva/dust_animation()
|
||||
new /obj/effect/overlay/temp/dust_animation(loc, "dust-l")
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
//can't unequip since it can't equip anything
|
||||
/mob/living/carbon/alien/larva/unEquip(obj/item/W)
|
||||
/mob/living/carbon/alien/larva/doUnEquip(obj/item/W)
|
||||
return
|
||||
@@ -14,16 +14,20 @@
|
||||
var/time_of_birth
|
||||
|
||||
rotate_on_lying = 0
|
||||
bodyparts = list(/obj/item/bodypart/chest/larva, /obj/item/bodypart/head/larva)
|
||||
|
||||
|
||||
//This is fine right now, if we're adding organ specific damage this needs to be updated
|
||||
/mob/living/carbon/alien/larva/New()
|
||||
regenerate_icons()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
|
||||
|
||||
AddAbility(new/obj/effect/proc_holder/alien/hide(null))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/larva_evolve(null))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/larva/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small/tiny
|
||||
..()
|
||||
|
||||
//This needs to be fixed
|
||||
/mob/living/carbon/alien/larva/Stat()
|
||||
..()
|
||||
@@ -39,37 +43,6 @@
|
||||
/mob/living/carbon/alien/larva/attack_ui(slot_id)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
adjustBruteLoss(5 + rand(1,9))
|
||||
Paralyse(1)
|
||||
spawn()
|
||||
step_away(src,user,15)
|
||||
sleep(1)
|
||||
step_away(src,user,15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
add_logs(M, src, "attacked")
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>")
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
Paralyse(rand(5,10))
|
||||
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to kick [src]!</span>")
|
||||
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/larva/restrained(ignore_grab)
|
||||
. = 0
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hand(mob/living/carbon/human/M)
|
||||
if(..())
|
||||
var/damage = rand(1, 9)
|
||||
if (prob(90))
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
add_logs(M, src, "attacked")
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
Paralyse(rand(5,10))
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to kick [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to kick [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/alien/larva/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
..(user, 1)
|
||||
adjustBruteLoss(5 + rand(1,9))
|
||||
new /datum/forced_movement(src, get_step_away(user,src, 30), 1)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/larva/do_attack_animation(atom/A, visual_effect_icon, obj/item/used_item, no_effect, end_pixel_y)
|
||||
if(!no_effect && !visual_effect_icon)
|
||||
visual_effect_icon = ATTACK_EFFECT_BITE
|
||||
..()
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/alien/larva/Life()
|
||||
set invisibility = 0
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(..())
|
||||
if(..()) //not dead
|
||||
// GROW!
|
||||
if(amount_grown < max_grown)
|
||||
amount_grown++
|
||||
@@ -20,7 +20,7 @@
|
||||
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
|
||||
death()
|
||||
return
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/obj/effect/proc_holder/alien/hide
|
||||
name = "Hide"
|
||||
desc = "Allows to hide beneath tables or certain items. Toggled on or off."
|
||||
desc = "Allows aliens to hide beneath tables or certain items. Toggled on or off."
|
||||
plasma_cost = 0
|
||||
|
||||
action_icon_state = "alien_hide"
|
||||
@@ -15,14 +15,14 @@
|
||||
"<span class='noticealien'>You are now hiding.</span>")
|
||||
else
|
||||
user.layer = MOB_LAYER
|
||||
user.visible_message("[user.] slowly peaks up from the ground...", \
|
||||
user.visible_message("[user.] slowly peeks up from the ground...", \
|
||||
"<span class='noticealien'>You stop hiding.</span>")
|
||||
return 1
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/larva_evolve
|
||||
name = "Evolve"
|
||||
desc = "Evolve into a fully grown Alien."
|
||||
desc = "Evolve into a higher alien caste."
|
||||
plasma_cost = 0
|
||||
|
||||
action_icon_state = "alien_evolve_larva"
|
||||
@@ -38,9 +38,9 @@
|
||||
if(L.amount_grown >= L.max_grown) //TODO ~Carn
|
||||
L << "<span class='name'>You are growing into a beautiful alien! It is time to choose a caste.</span>"
|
||||
L << "<span class='info'>There are three to choose from:"
|
||||
L << "<span class='name'>Hunters</span> <span class='info'>are the most agile caste tasked with hunting for hosts. They are faster than a human and can even pounce, but are not much tougher than a drone.</span>"
|
||||
L << "<span class='name'>Hunters</span> <span class='info'>are the most agile caste, tasked with hunting for hosts. They are faster than a human and can even pounce, but are not much tougher than a drone.</span>"
|
||||
L << "<span class='name'>Sentinels</span> <span class='info'>are tasked with protecting the hive. With their ranged spit, invisibility, and high health, they make formidable guardians and acceptable secondhand hunters.</span>"
|
||||
L << "<span class='name'>Drones</span> <span class='info'>are the weakest and slowest of the castes, but can grow into the queen if there is none, and are vital to maintaining a hive with their resin secretion abilities.</span>"
|
||||
L << "<span class='name'>Drones</span> <span class='info'>are the weakest and slowest of the castes, but can grow into a praetorian and then queen if no queen exists, and are vital to maintaining a hive with their resin secretion abilities.</span>"
|
||||
var/alien_caste = alert(L, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
|
||||
|
||||
if(user.incapacitated()) //something happened to us while we were choosing.
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
/mob/living/carbon/alien/larva/update_icons()
|
||||
var/state = 0
|
||||
if(amount_grown > 150)
|
||||
if(amount_grown > 80)
|
||||
state = 2
|
||||
else if(amount_grown > 50)
|
||||
state = 1
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/mob/living/carbon/alien/Life()
|
||||
findQueen()
|
||||
return..()
|
||||
|
||||
/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
|
||||
if(status_flags & GODMODE)
|
||||
@@ -42,4 +45,10 @@
|
||||
move_delay_add = max(0, move_delay_add - rand(1, 2))
|
||||
|
||||
/mob/living/carbon/alien/handle_changeling()
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/handle_fire()//Aliens on fire code
|
||||
if(..())
|
||||
return
|
||||
bodytemperature += BODYTEMP_HEATING_MAX //If you're on fire, you heat up!
|
||||
return
|
||||
@@ -31,7 +31,7 @@
|
||||
name = "plasma vessel"
|
||||
icon_state = "plasma"
|
||||
origin_tech = "biotech=5;plasmatech=4"
|
||||
w_class = 3
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
zone = "chest"
|
||||
slot = "plasmavessel"
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/plant, /obj/effect/proc_holder/alien/transfer)
|
||||
@@ -49,7 +49,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/large
|
||||
name = "large plasma vessel"
|
||||
icon_state = "plasma_large"
|
||||
w_class = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
storedPlasma = 200
|
||||
max_plasma = 500
|
||||
plasma_rate = 15
|
||||
@@ -61,7 +61,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/small
|
||||
name = "small plasma vessel"
|
||||
icon_state = "plasma_small"
|
||||
w_class = 2
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
storedPlasma = 100
|
||||
max_plasma = 150
|
||||
plasma_rate = 5
|
||||
@@ -69,7 +69,7 @@
|
||||
/obj/item/organ/alien/plasmavessel/small/tiny
|
||||
name = "tiny plasma vessel"
|
||||
icon_state = "plasma_tiny"
|
||||
w_class = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
max_plasma = 100
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/transfer)
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
zone = "head"
|
||||
slot = "hivenode"
|
||||
origin_tech = "biotech=5;magnets=4;bluespace=3"
|
||||
w_class = 1
|
||||
w_class = WEIGHT_CLASS_TINY
|
||||
var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active.
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/whisper)
|
||||
|
||||
@@ -182,6 +182,6 @@
|
||||
icon_state = "eggsac"
|
||||
zone = "groin"
|
||||
slot = "eggsac"
|
||||
w_class = 4
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
origin_tech = "biotech=6"
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/lay_egg)
|
||||
|
||||
@@ -4,4 +4,31 @@
|
||||
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
|
||||
|
||||
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
|
||||
return
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/proc/findQueen()
|
||||
if(hud_used)
|
||||
hud_used.alien_queen_finder.cut_overlays()
|
||||
var/mob/queen = get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen)
|
||||
if(!queen)
|
||||
return
|
||||
var/turf/Q = get_turf(queen)
|
||||
var/turf/A = get_turf(src)
|
||||
if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far.
|
||||
return
|
||||
var/Qdir = get_dir(src, Q)
|
||||
var/Qdist = get_dist(src, Q)
|
||||
image(icon,loc,icon_state,layer,dir)
|
||||
var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen!
|
||||
switch(Qdist)
|
||||
if(2 to 7)
|
||||
finder_icon = "finder_near"
|
||||
if(8 to 20)
|
||||
finder_icon = "finder_med"
|
||||
if(21 to INFINITY)
|
||||
finder_icon = "finder_far"
|
||||
var/image/finder_eye = image('icons/mob/screen_alien.dmi', icon_state = finder_icon, dir = Qdir)
|
||||
hud_used.alien_queen_finder.add_overlay(finder_eye)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/findQueen()
|
||||
return //Queen already knows where she is. Hopefully.
|
||||
@@ -41,7 +41,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
if(prob(4))
|
||||
owner << "<span class='danger'>Your muscles ache.</span>"
|
||||
if(prob(20))
|
||||
owner.take_organ_damage(1)
|
||||
owner.take_bodypart_damage(1)
|
||||
if(prob(4))
|
||||
owner << "<span class='danger'>Your stomach hurts.</span>"
|
||||
if(prob(20))
|
||||
@@ -99,7 +99,7 @@ var/const/ALIEN_AFK_BRACKET = 450 // 45 seconds
|
||||
new_xeno.notransform = 0
|
||||
new_xeno.invisibility = 0
|
||||
if(gib_on_success)
|
||||
owner.gib()
|
||||
owner.gib(TRUE)
|
||||
else
|
||||
owner.adjustBruteLoss(40)
|
||||
owner.overlays -= overlay
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
@@ -14,7 +14,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = 1 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
w_class = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKINTERNALS
|
||||
throw_range = 5
|
||||
tint = 3
|
||||
@@ -23,8 +23,8 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
var/sterile = 0
|
||||
var/real = 1 //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/sterile = FALSE
|
||||
var/real = TRUE //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/strength = 5
|
||||
|
||||
var/attached = 0
|
||||
@@ -33,6 +33,16 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
name = "Lamarr"
|
||||
sterile = 1
|
||||
|
||||
/obj/item/clothing/mask/facehugger/dead
|
||||
icon_state = "facehugger_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/impregnated
|
||||
icon_state = "facehugger_impregnated"
|
||||
item_state = "facehugger_impregnated"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
|
||||
attack_hand(user)
|
||||
return
|
||||
@@ -45,8 +55,8 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
user.unEquip(src)
|
||||
Attach(M)
|
||||
if(user.temporarilyRemoveItemFromInventory(src))
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/examine(mob/user)
|
||||
..()
|
||||
@@ -68,7 +78,6 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
/obj/item/clothing/mask/facehugger/bullet_act(obj/item/projectile/P)
|
||||
if(P.damage)
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
@@ -92,7 +101,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
return Attach(AM)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin)
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
if(!..())
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
@@ -107,62 +116,82 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon_state = "[initial(icon_state)]"
|
||||
Attach(hit_atom)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
|
||||
if(!isliving(M))
|
||||
return 0
|
||||
if((!iscorgi(M) && !iscarbon(M)) || isalien(M))
|
||||
return 0
|
||||
if(attached)
|
||||
return 0
|
||||
else
|
||||
attached++
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
if(M.getorgan(/obj/item/organ/alien/hivenode))
|
||||
return 0
|
||||
if(M.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return 0
|
||||
/obj/item/clothing/mask/facehugger/proc/valid_to_attach(mob/living/M)
|
||||
// valid targets: corgis, carbons except aliens and devils
|
||||
// facehugger state early exit checks
|
||||
if(stat != CONSCIOUS)
|
||||
return 0
|
||||
if(!sterile) M.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
|
||||
return FALSE
|
||||
if(attached)
|
||||
return FALSE
|
||||
if(!iscorgi(M) && !iscarbon(M))
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
// disallowed carbons
|
||||
if(isalien(M) || isdevil(M))
|
||||
return FALSE
|
||||
var/mob/living/carbon/target = M
|
||||
// gotta have a head to be implanted (no changelings or sentient plants)
|
||||
if(!target.get_bodypart("head"))
|
||||
return FALSE
|
||||
|
||||
if(target.getorgan(/obj/item/organ/alien/hivenode) || target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return FALSE
|
||||
// carbon, has head, not alien or devil, has no hivenode or embryo: valid
|
||||
return TRUE
|
||||
else if(iscorgi(M))
|
||||
// corgi: valid
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
|
||||
if(!valid_to_attach(M))
|
||||
return FALSE
|
||||
// passed initial checks - time to leap!
|
||||
M.visible_message("<span class='danger'>[src] leaps at [M]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return 0
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
|
||||
// probiscis-blocker handling
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
if(target.wear_mask)
|
||||
if(prob(20))
|
||||
return 0
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(W.flags & NODROP)
|
||||
return 0
|
||||
target.unEquip(W)
|
||||
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
return FALSE
|
||||
if(!istype(W,/obj/item/clothing/mask/facehugger))
|
||||
target.dropItemToGround(W)
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
|
||||
src.loc = target
|
||||
target.equip_to_slot(src, slot_wear_mask,,0)
|
||||
if(!sterile)
|
||||
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
else if (iscorgi(M))
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return FALSE
|
||||
forceMove(target)
|
||||
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
|
||||
// early returns and validity checks done: attach.
|
||||
attached++
|
||||
//ensure we detach once we no longer need to be attached
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
|
||||
if (iscorgi(M))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = M
|
||||
loc = C
|
||||
C.facehugger = src
|
||||
C.regenerate_icons()
|
||||
|
||||
if(!sterile)
|
||||
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
|
||||
M.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
|
||||
GoIdle() //so it doesn't jump the people that tear it off
|
||||
|
||||
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
|
||||
Impregnate(M)
|
||||
|
||||
return 1
|
||||
return TRUE // time for a smoke
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target)
|
||||
if(!target || target.stat == DEAD) //was taken off or something
|
||||
@@ -182,7 +211,7 @@ var/const/MAX_ACTIVE_TIME = 400
|
||||
icon_state = "[initial(icon_state)]_impregnated"
|
||||
|
||||
var/obj/item/bodypart/chest/LC = target.get_bodypart("chest")
|
||||
if((!LC || LC.status != ORGAN_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
new /obj/item/organ/body_egg/alien_embryo(target)
|
||||
|
||||
if(iscorgi(target))
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/alien/update_damage_overlays() //aliens don't have damage overlays.
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/update_body() // we don't use the bodyparts or body layers for aliens.
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/update_body_parts()//we don't use the bodyparts layer for aliens.
|
||||
return
|
||||
@@ -1,63 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
/mob/living/carbon/brain
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
var/obj/item/device/mmi/container = null
|
||||
var/timeofhostdeath = 0
|
||||
var/emp_damage = 0//Handles a type of MMI damage
|
||||
has_limbs = 0
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
|
||||
/mob/living/carbon/brain/New(loc)
|
||||
..()
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
src.loc = OB
|
||||
OB.brainmob = src
|
||||
|
||||
|
||||
/mob/living/carbon/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
if(stat!=DEAD) //If not dead.
|
||||
death(1) //Brains can die again. AND THEY SHOULD AHA HA HA HA HA HA
|
||||
ghostize() //Ghostize checks for key so nothing else is necessary.
|
||||
container = null
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/brain/update_canmove()
|
||||
if(in_contents_of(/obj/mecha))
|
||||
canmove = 1
|
||||
else
|
||||
canmove = 0
|
||||
return canmove
|
||||
|
||||
/mob/living/carbon/brain/toggle_throw_mode()
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/blob_act(obj/effect/blob/B)
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/UnarmedAttack(atom/A)//Stops runtimes due to attack_animal being the default
|
||||
return
|
||||
|
||||
/mob/living/carbon/brain/check_ear_prot()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/brain/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0)
|
||||
return // no eyes, no flashing
|
||||
|
||||
/mob/living/carbon/brain/update_damage_hud()
|
||||
return //no red circles for brain
|
||||
|
||||
/mob/living/carbon/brain/can_be_revived()
|
||||
. = 1
|
||||
if(!container || health <= config.health_threshold_dead)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/brain/update_sight()
|
||||
return
|
||||
@@ -1,71 +0,0 @@
|
||||
/mob/living/carbon/brain/emote(act,m_type=1,message = null)
|
||||
if(!(container && istype(container, /obj/item/device/mmi)))//No MMI, no emotes
|
||||
return
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
|
||||
if(src.stat == DEAD)
|
||||
return
|
||||
switch(act)
|
||||
if ("alarm")
|
||||
src << "You sound an alarm."
|
||||
message = "<B>[src]</B> sounds an alarm."
|
||||
m_type = 2
|
||||
|
||||
if ("alert")
|
||||
src << "You let out a distressed noise."
|
||||
message = "<B>[src]</B> lets out a distressed noise."
|
||||
m_type = 2
|
||||
|
||||
if ("beep","beeps")
|
||||
src << "You beep."
|
||||
message = "<B>[src]</B> beeps."
|
||||
m_type = 2
|
||||
|
||||
if ("blink","blinks")
|
||||
message = "<B>[src]</B> blinks."
|
||||
m_type = 1
|
||||
|
||||
if ("boop","boops")
|
||||
src << "You boop."
|
||||
message = "<B>[src]</B> boops."
|
||||
m_type = 2
|
||||
|
||||
if ("flash")
|
||||
message = "The lights on <B>[src]</B> flash quickly."
|
||||
m_type = 1
|
||||
|
||||
if ("notice")
|
||||
src << "You play a loud tone."
|
||||
message = "<B>[src]</B> plays a loud tone."
|
||||
m_type = 2
|
||||
|
||||
if ("whistle","whistles")
|
||||
src << "You whistle."
|
||||
message = "<B>[src]</B> whistles."
|
||||
m_type = 2
|
||||
|
||||
if ("help")
|
||||
src << "Help for MMI emotes. You can use these emotes with say \"*emote\":\nalarm, alert, beep, blink, boop, flash, notice, whistle"
|
||||
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
return
|
||||
|
||||
if (message)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if (!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers, and new_players
|
||||
if(M.stat == DEAD && (M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT)) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else if (m_type & 2)
|
||||
audible_message(message)
|
||||
@@ -3,15 +3,18 @@
|
||||
|
||||
/mob/living/carbon/New()
|
||||
create_reagents(1000)
|
||||
update_body_parts() //to update the carbon's new bodyparts appearance
|
||||
..()
|
||||
|
||||
/mob/living/carbon/Destroy()
|
||||
for(var/atom/movable/guts in internal_organs)
|
||||
for(var/guts in internal_organs)
|
||||
qdel(guts)
|
||||
for(var/atom/movable/food in stomach_contents)
|
||||
qdel(food)
|
||||
for(var/BP in bodyparts)
|
||||
qdel(BP)
|
||||
for(var/imp in implants)
|
||||
qdel(imp)
|
||||
bodyparts = list()
|
||||
remove_from_all_data_huds()
|
||||
if(dna)
|
||||
@@ -25,19 +28,12 @@
|
||||
audible_message("<span class='warning'>You hear something rumbling inside [src]'s stomach...</span>", \
|
||||
"<span class='warning'>You hear something rumbling.</span>", 4,\
|
||||
"<span class='userdanger'>Something is rumbling inside your stomach!</span>")
|
||||
var/obj/item/I = user.get_active_hand()
|
||||
var/obj/item/I = user.get_active_held_item()
|
||||
if(I && I.force)
|
||||
var/d = rand(round(I.force / 4), I.force)
|
||||
if(istype(src, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/organ = H.get_bodypart("chest")
|
||||
if (istype(organ, /obj/item/bodypart))
|
||||
var/obj/item/bodypart/temp = organ
|
||||
if(temp.take_damage(d, 0))
|
||||
H.update_damage_overlays(0)
|
||||
H.updatehealth()
|
||||
else
|
||||
src.take_organ_damage(d)
|
||||
var/obj/item/bodypart/BP = get_bodypart("chest")
|
||||
if(BP.receive_damage(d, 0))
|
||||
update_damage_overlays()
|
||||
visible_message("<span class='danger'>[user] attacks [src]'s stomach wall with the [I.name]!</span>", \
|
||||
"<span class='userdanger'>[user] attacks your stomach wall with the [I.name]!</span>")
|
||||
playsound(user.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
@@ -49,140 +45,67 @@
|
||||
src.gib()
|
||||
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, override = 0, tesla_shock = 0)
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
return 0
|
||||
if(reagents.has_reagent("teslium"))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
take_overall_damage(0,shock_damage)
|
||||
//src.adjustFireLoss(shock_damage)
|
||||
//src.updatehealth()
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(2)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(3)
|
||||
Weaken(3)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
/mob/living/carbon/swap_hand(held_index)
|
||||
if(!held_index)
|
||||
held_index = (active_hand_index % held_items.len)+1
|
||||
|
||||
|
||||
/mob/living/carbon/swap_hand()
|
||||
var/obj/item/item_in_hand = src.get_active_hand()
|
||||
var/obj/item/item_in_hand = src.get_active_held_item()
|
||||
if(item_in_hand) //this segment checks if the item in your hand is twohanded.
|
||||
if(istype(item_in_hand,/obj/item/weapon/twohanded))
|
||||
if(item_in_hand:wielded == 1)
|
||||
usr << "<span class='warning'>Your other hand is too busy holding the [item_in_hand.name]</span>"
|
||||
return
|
||||
src.hand = !( src.hand )
|
||||
if(hud_used && hud_used.inv_slots[slot_l_hand] && hud_used.inv_slots[slot_r_hand])
|
||||
var/oindex = active_hand_index
|
||||
active_hand_index = held_index
|
||||
if(hud_used)
|
||||
var/obj/screen/inventory/hand/H
|
||||
H = hud_used.inv_slots[slot_l_hand]
|
||||
H.update_icon()
|
||||
H = hud_used.inv_slots[slot_r_hand]
|
||||
H.update_icon()
|
||||
/*if (!( src.hand ))
|
||||
src.hands.setDir(NORTH)
|
||||
else
|
||||
src.hands.setDir(SOUTH)*/
|
||||
return
|
||||
H = hud_used.hand_slots["[oindex]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
H = hud_used.hand_slots["[held_index]"]
|
||||
if(H)
|
||||
H.update_icon()
|
||||
|
||||
/mob/living/carbon/activate_hand(selhand) //0 or "r" or "right" for right hand; 1 or "l" or "left" for left hand.
|
||||
|
||||
/mob/living/carbon/activate_hand(selhand) //l/r OR 1-held_items.len
|
||||
if(!selhand)
|
||||
selhand = (active_hand_index % held_items.len)+1
|
||||
|
||||
if(istext(selhand))
|
||||
selhand = lowertext(selhand)
|
||||
|
||||
if(selhand == "right" || selhand == "r")
|
||||
selhand = 0
|
||||
selhand = 2
|
||||
if(selhand == "left" || selhand == "l")
|
||||
selhand = 1
|
||||
|
||||
if(selhand != src.hand)
|
||||
swap_hand()
|
||||
if(selhand != active_hand_index)
|
||||
swap_hand(selhand)
|
||||
else
|
||||
mode() // Activate held item
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
M << "<span class='warning'>You can't put them out with just your bare hands!"
|
||||
return
|
||||
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
|
||||
if(lying && surgeries.len)
|
||||
if(user != src && user.a_intent == INTENT_HELP)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user))
|
||||
return 1
|
||||
return ..()
|
||||
|
||||
if(health >= 0 && !(status_flags & FAKEDEATH))
|
||||
|
||||
if(lying)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get them up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get them up!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make them feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make them feel better!</span>")
|
||||
AdjustSleeping(-5)
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
if(resting)
|
||||
resting = 0
|
||||
update_canmove()
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
|
||||
var/damage = intensity - check_eye_prot()
|
||||
if(.) // we've been flashed
|
||||
if(visual)
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
Weaken(1)
|
||||
take_bodypart_damage(10)
|
||||
if(iscarbon(hit_atom) && hit_atom != src)
|
||||
var/mob/living/carbon/victim = hit_atom
|
||||
if(victim.movement_type & FLYING)
|
||||
return
|
||||
if(weakeyes)
|
||||
Stun(2)
|
||||
|
||||
if (damage == 1)
|
||||
src << "<span class='warning'>Your eyes sting a little.</span>"
|
||||
if(prob(40))
|
||||
adjust_eye_damage(1)
|
||||
|
||||
else if (damage == 2)
|
||||
src << "<span class='warning'>Your eyes burn.</span>"
|
||||
adjust_eye_damage(rand(2, 4))
|
||||
|
||||
else if( damage > 3)
|
||||
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
|
||||
adjust_eye_damage(rand(12, 16))
|
||||
|
||||
if(eye_damage > 10)
|
||||
blind_eyes(damage)
|
||||
blur_eyes(damage * rand(3, 6))
|
||||
|
||||
if(eye_damage > 20)
|
||||
if(prob(eye_damage - 20))
|
||||
if(become_nearsighted())
|
||||
src << "<span class='warning'>Your eyes start to burn badly!</span>"
|
||||
else if(prob(eye_damage - 25))
|
||||
if(become_blind())
|
||||
src << "<span class='warning'>You can't see anything!</span>"
|
||||
else
|
||||
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(-500)
|
||||
return 1
|
||||
else if(damage == 0) // just enough protection
|
||||
if(prob(20))
|
||||
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(0)
|
||||
victim.Weaken(1)
|
||||
Weaken(1)
|
||||
victim.take_bodypart_damage(10)
|
||||
take_bodypart_damage(10)
|
||||
visible_message("<span class='danger'>[src] crashes into [victim], knocking them both over!</span>", "<span class='userdanger'>You violently crash into [victim]!</span>")
|
||||
playsound(src,'sound/weapons/punch1.ogg',50,1)
|
||||
|
||||
|
||||
//Throwing stuff
|
||||
@@ -217,7 +140,7 @@
|
||||
return
|
||||
|
||||
var/atom/movable/thrown_thing
|
||||
var/obj/item/I = src.get_active_hand()
|
||||
var/obj/item/I = src.get_active_held_item()
|
||||
|
||||
if(!I)
|
||||
if(pulling && isliving(pulling) && grab_state >= GRAB_AGGRESSIVE)
|
||||
@@ -234,7 +157,7 @@
|
||||
|
||||
else if(!(I.flags & (NODROP|ABSTRACT)))
|
||||
thrown_thing = I
|
||||
unEquip(I)
|
||||
dropItemToGround(I)
|
||||
|
||||
if(thrown_thing)
|
||||
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
|
||||
@@ -256,8 +179,11 @@
|
||||
<HR>
|
||||
<BR><B>Head:</B> <A href='?src=\ref[src];item=[slot_head]'> [(head && !(head.flags&ABSTRACT)) ? head : "Nothing"]</A>
|
||||
<BR><B>Mask:</B> <A href='?src=\ref[src];item=[slot_wear_mask]'> [(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "Nothing"]</A>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "Nothing"]</A>"}
|
||||
<BR><B>Neck:</B> <A href='?src=\ref[src];item=[slot_neck]'> [(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "Nothing"]</A>"}
|
||||
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<BR><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "Nothing"]</a>"
|
||||
|
||||
dat += "<BR><B>Back:</B> <A href='?src=\ref[src];item=[slot_back]'>[back ? back : "Nothing"]</A>"
|
||||
|
||||
@@ -305,13 +231,6 @@
|
||||
/mob/living/carbon/is_muzzled()
|
||||
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
|
||||
/mob/living/carbon/blob_act(obj/effect/blob/B)
|
||||
if (stat == DEAD)
|
||||
return
|
||||
else
|
||||
show_message("<span class='userdanger'>The blob attacks!</span>")
|
||||
adjustBruteLoss(10)
|
||||
|
||||
/mob/living/carbon/proc/spin(spintime, speed)
|
||||
set waitfor = 0
|
||||
var/D = dir
|
||||
@@ -347,7 +266,7 @@
|
||||
|
||||
/mob/living/carbon/resist_fire()
|
||||
fire_stacks -= 5
|
||||
Weaken(3,1)
|
||||
Weaken(3, 1, 1)
|
||||
spin(32,2)
|
||||
visible_message("<span class='danger'>[src] rolls on the floor, trying to put themselves out!</span>", \
|
||||
"<span class='notice'>You stop, drop, and roll!</span>")
|
||||
@@ -360,13 +279,20 @@
|
||||
|
||||
/mob/living/carbon/resist_restraints()
|
||||
var/obj/item/I = null
|
||||
var/type = 0
|
||||
if(handcuffed)
|
||||
I = handcuffed
|
||||
type = 1
|
||||
else if(legcuffed)
|
||||
I = legcuffed
|
||||
type = 2
|
||||
if(I)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(type == 1)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
if(type == 2)
|
||||
changeNext_move(CLICK_CD_RANGE)
|
||||
last_special = world.time + CLICK_CD_RANGE
|
||||
cuff_resist(I)
|
||||
|
||||
|
||||
@@ -407,6 +333,7 @@
|
||||
W.dropped(src)
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
if (legcuffed)
|
||||
var/obj/item/weapon/W = legcuffed
|
||||
legcuffed = null
|
||||
@@ -418,6 +345,7 @@
|
||||
W.dropped(src)
|
||||
if (W)
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
|
||||
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
|
||||
if(!I.loc || buckled)
|
||||
@@ -452,6 +380,9 @@
|
||||
legcuffed = null
|
||||
update_inv_legcuffed()
|
||||
return
|
||||
else
|
||||
dropItemToGround(I)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/is_mouth_covered(head_only = 0, mask_only = 0)
|
||||
@@ -464,15 +395,11 @@
|
||||
else
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/check_ear_prot()
|
||||
if(head && (head.flags & HEADBANGPROTECT))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/accident(obj/item/I)
|
||||
if(!I || (I.flags & (NODROP|ABSTRACT)))
|
||||
return
|
||||
|
||||
unEquip(I)
|
||||
dropItemToGround(I)
|
||||
|
||||
var/modifier = 0
|
||||
if(disabilities & CLUMSY)
|
||||
@@ -496,17 +423,6 @@
|
||||
var/turf/target = get_turf(loc)
|
||||
I.throw_at(target,I.throw_range,I.throw_speed,src)
|
||||
|
||||
/mob/living/carbon/emp_act(severity)
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/check_eye_prot()
|
||||
var/number = ..()
|
||||
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
|
||||
number += EFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/proc/AddAbility(obj/effect/proc_holder/alien/A)
|
||||
abilities.Add(A)
|
||||
A.on_gain(src)
|
||||
@@ -535,11 +451,19 @@
|
||||
|
||||
add_abilities_to_panel()
|
||||
|
||||
/mob/living/carbon/attack_ui(slot)
|
||||
if(!has_hand_for_held_index(active_hand_index))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/proc/vomit(var/lost_nutrition = 10, var/blood = 0, var/stun = 1, var/distance = 0, var/message = 1, var/toxic = 0)
|
||||
if(dna && dna.species && NOHUNGER in dna.species.species_traits)
|
||||
return 1
|
||||
|
||||
if(nutrition < 100 && !blood)
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing your stomach!</span>")
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
Weaken(10)
|
||||
return 1
|
||||
@@ -575,12 +499,27 @@
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/fully_replace_character_name(oldname,newname)
|
||||
..()
|
||||
if(dna)
|
||||
dna.real_name = real_name
|
||||
|
||||
//Updates the mob's health from bodyparts and mob damage variables
|
||||
/mob/living/carbon/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/X in bodyparts) //hardcoded to streamline things a bit
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += BP.brute_dam
|
||||
total_burn += BP.burn_dam
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < HEALTH_THRESHOLD_DEAD) && stat == DEAD )
|
||||
become_husk()
|
||||
med_hud_set_health()
|
||||
|
||||
/mob/living/carbon/update_sight()
|
||||
if(!client)
|
||||
return
|
||||
@@ -636,7 +575,7 @@
|
||||
if(!client)
|
||||
return
|
||||
|
||||
if(stat == UNCONSCIOUS && health <= config.health_threshold_crit)
|
||||
if(stat == UNCONSCIOUS && health <= HEALTH_THRESHOLD_CRIT)
|
||||
var/severity = 0
|
||||
switch(health)
|
||||
if(-20 to -10) severity = 1
|
||||
@@ -714,10 +653,10 @@
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
if(stat != DEAD)
|
||||
if(health<= config.health_threshold_dead || !getorgan(/obj/item/organ/brain))
|
||||
if(health<= HEALTH_THRESHOLD_DEAD || !getorgan(/obj/item/organ/brain))
|
||||
death()
|
||||
return
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= config.health_threshold_crit)
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
@@ -735,8 +674,7 @@
|
||||
//called when we get cuffed/uncuffed
|
||||
/mob/living/carbon/proc/update_handcuffed()
|
||||
if(handcuffed)
|
||||
drop_r_hand()
|
||||
drop_l_hand()
|
||||
drop_all_held_items()
|
||||
stop_pulling()
|
||||
throw_alert("handcuffed", /obj/screen/alert/restrained/handcuffed, new_master = src.handcuffed)
|
||||
else
|
||||
@@ -752,8 +690,11 @@
|
||||
if(B)
|
||||
B.damaged_brain = 0
|
||||
for(var/datum/disease/D in viruses)
|
||||
D.cure(0)
|
||||
if (D.severity != NONTHREAT)
|
||||
D.cure(0)
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
regenerate_organs()
|
||||
handcuffed = initial(handcuffed)
|
||||
for(var/obj/item/weapon/restraints/R in contents) //actually remove cuffs from inventory
|
||||
qdel(R)
|
||||
@@ -771,7 +712,8 @@
|
||||
if(qdeleted(src))
|
||||
return
|
||||
var/organs_amt = 0
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
if(prob(50))
|
||||
organs_amt++
|
||||
O.Remove(src)
|
||||
@@ -781,12 +723,61 @@
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health=1)
|
||||
if(has_dna() && TOXINLOVER in dna.species.specflags) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
else
|
||||
blood_volume -= amount
|
||||
return ..()
|
||||
/mob/living/carbon/ExtinguishMob()
|
||||
for(var/X in get_equipped_items())
|
||||
var/obj/item/I = X
|
||||
I.acid_level = 0 //washes off the acid on our clothes
|
||||
I.extinguish() //extinguishes our clothes
|
||||
..()
|
||||
|
||||
/mob/living/carbon/fakefire(var/fire_icon = "Generic_mob_burning")
|
||||
var/image/new_fire_overlay = image("icon"='icons/mob/OnFire.dmi', "icon_state"= fire_icon, "layer"=-FIRE_LAYER)
|
||||
new_fire_overlay.appearance_flags = RESET_COLOR
|
||||
overlays_standing[FIRE_LAYER] = new_fire_overlay
|
||||
apply_overlay(FIRE_LAYER)
|
||||
|
||||
/mob/living/carbon/fakefireextinguish()
|
||||
remove_overlay(FIRE_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
|
||||
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
|
||||
"<span class='userdanger'>[src] is attempting to devour you!</span>")
|
||||
if(!do_mob(src, C, devour_time))
|
||||
return
|
||||
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == INTENT_GRAB)
|
||||
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
|
||||
"<span class='userdanger'>[src] devours you!</span>")
|
||||
C.forceMove(src)
|
||||
stomach_contents.Add(C)
|
||||
add_logs(src, C, "devoured")
|
||||
|
||||
/mob/living/carbon/proc/create_bodyparts()
|
||||
var/l_arm_index_next = -1
|
||||
var/r_arm_index_next = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = new X()
|
||||
O.owner = src
|
||||
bodyparts.Remove(X)
|
||||
bodyparts.Add(O)
|
||||
if(O.body_part == ARM_LEFT)
|
||||
l_arm_index_next += 2
|
||||
O.held_index = l_arm_index_next //1, 3, 5, 7...
|
||||
hand_bodyparts += O
|
||||
else if(O.body_part == ARM_RIGHT)
|
||||
r_arm_index_next += 2
|
||||
O.held_index = r_arm_index_next //2, 4, 6, 8...
|
||||
hand_bodyparts += O
|
||||
|
||||
|
||||
/mob/living/carbon/proc/create_internal_organs()
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
I.Insert(src)
|
||||
|
||||
/mob/living/carbon/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make AI"] = "?_src_=vars;makeai=\ref[src]"
|
||||
.["Modify bodypart"] = "?_src_=vars;editbodypart=\ref[src]"
|
||||
.["Modify organs"] = "?_src_=vars;editorgans=\ref[src]"
|
||||
|
||||
@@ -1,6 +1,22 @@
|
||||
|
||||
/mob/living/carbon/get_eye_protection()
|
||||
var/number = ..()
|
||||
for(var/obj/item/organ/cyberimp/eyes/EFP in internal_organs)
|
||||
number += EFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/get_ear_protection()
|
||||
if(head && (head.flags & HEADBANGPROTECT))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/check_projectile_dismemberment(obj/item/projectile/P, def_zone)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(def_zone)
|
||||
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
|
||||
affecting.dismember(P.damtype)
|
||||
|
||||
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = 1, blocked = 0)
|
||||
if(!skipcatch) //ugly, but easy
|
||||
if(in_throw_mode && !get_active_hand()) //empty active hand and we're in throw mode
|
||||
if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode
|
||||
if(canmove && !restrained())
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
@@ -11,25 +27,46 @@
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/throw_impact(atom/hit_atom)
|
||||
. = ..()
|
||||
if(hit_atom.density && isturf(hit_atom))
|
||||
Weaken(1)
|
||||
take_organ_damage(10)
|
||||
|
||||
/mob/living/carbon/attackby(obj/item/I, mob/user, params)
|
||||
if(lying)
|
||||
if(surgeries.len)
|
||||
if(user != src && user.a_intent == "help")
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user, src))
|
||||
return 1
|
||||
return ..()
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
|
||||
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
|
||||
affecting = bodyparts[1]
|
||||
send_item_attack_message(I, user, affecting.name)
|
||||
if(I.force)
|
||||
apply_damage(I.force, I.damtype, affecting)
|
||||
damage_clothes(I.force, I.damtype, "melee", affecting.body_zone)
|
||||
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
|
||||
if(prob(33))
|
||||
I.add_mob_blood(src)
|
||||
var/turf/location = get_turf(src)
|
||||
add_splatter_floor(location)
|
||||
if(get_dist(user, src) <= 1) //people with TK won't get smeared with blood
|
||||
user.add_mob_blood(src)
|
||||
|
||||
if(affecting.body_zone == "head")
|
||||
if(wear_mask)
|
||||
wear_mask.add_mob_blood(src)
|
||||
update_inv_wear_mask()
|
||||
if(wear_neck)
|
||||
wear_neck.add_mob_blood(src)
|
||||
update_inv_neck()
|
||||
if(head)
|
||||
head.add_mob_blood(src)
|
||||
update_inv_head()
|
||||
|
||||
//dismemberment
|
||||
var/probability = I.get_dismemberment_chance(affecting)
|
||||
if(prob(probability))
|
||||
if(affecting.dismember(I.damtype))
|
||||
I.add_mob_blood(src)
|
||||
playsound(get_turf(src), I.get_dismember_sound(), 80, 1)
|
||||
return TRUE //successful attack
|
||||
|
||||
/mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user)
|
||||
return //so we don't call the carbon's attack_hand().
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
|
||||
if(!iscarbon(user))
|
||||
return
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
@@ -39,19 +76,15 @@
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
|
||||
if(lying)
|
||||
if(user.a_intent == "help")
|
||||
if(surgeries.len)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user, src))
|
||||
return 1
|
||||
if(lying && surgeries.len)
|
||||
if(user.a_intent == INTENT_HELP)
|
||||
for(var/datum/surgery/S in surgeries)
|
||||
if(S.next_step(user))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
|
||||
if(!istype(M, /mob/living/carbon))
|
||||
return 0
|
||||
|
||||
for(var/datum/disease/D in viruses)
|
||||
if(D.IsSpreadByTouch())
|
||||
M.ContractDisease(D)
|
||||
@@ -60,7 +93,7 @@
|
||||
if(D.IsSpreadByTouch())
|
||||
ContractDisease(D)
|
||||
|
||||
if(M.a_intent == "help")
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
help_shake_act(M)
|
||||
return 0
|
||||
|
||||
@@ -95,14 +128,175 @@
|
||||
updatehealth()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/devour_mob(mob/living/carbon/C, devour_time = 130)
|
||||
C.visible_message("<span class='danger'>[src] is attempting to devour [C]!</span>", \
|
||||
"<span class='userdanger'>[src] is attempting to devour you!</span>")
|
||||
if(!do_mob(src, C, devour_time))
|
||||
/mob/living/carbon/proc/dismembering_strike(mob/living/attacker, dam_zone)
|
||||
if(!attacker.limb_destroyer)
|
||||
return dam_zone
|
||||
var/obj/item/bodypart/affecting
|
||||
if(dam_zone && attacker.client)
|
||||
affecting = get_bodypart(ran_zone(dam_zone))
|
||||
else
|
||||
var/list/things_to_ruin = shuffle(bodyparts.Copy())
|
||||
for(var/B in things_to_ruin)
|
||||
var/obj/item/bodypart/bodypart = B
|
||||
if(bodypart.body_zone == "head" || bodypart.body_zone == "chest")
|
||||
continue
|
||||
if(!affecting || ((affecting.get_damage() / affecting.max_damage) < (bodypart.get_damage() / bodypart.max_damage)))
|
||||
affecting = bodypart
|
||||
if(affecting)
|
||||
dam_zone = affecting.body_zone
|
||||
if(affecting.get_damage() >= affecting.max_damage)
|
||||
affecting.dismember()
|
||||
return null
|
||||
return affecting.body_zone
|
||||
return dam_zone
|
||||
|
||||
|
||||
/mob/living/carbon/blob_act(obj/structure/blob/B)
|
||||
if (stat == DEAD)
|
||||
return
|
||||
if(pulling && pulling == C && grab_state >= GRAB_AGGRESSIVE && a_intent == "grab")
|
||||
C.visible_message("<span class='danger'>[src] devours [C]!</span>", \
|
||||
"<span class='userdanger'>[src] devours you!</span>")
|
||||
C.forceMove(src)
|
||||
stomach_contents.Add(C)
|
||||
add_logs(src, C, "devoured")
|
||||
else
|
||||
show_message("<span class='userdanger'>The blob attacks!</span>")
|
||||
adjustBruteLoss(10)
|
||||
|
||||
/mob/living/carbon/emp_act(severity)
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
O.emp_act(severity)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
return 0
|
||||
if(reagents.has_reagent("teslium"))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
if(illusion)
|
||||
adjustStaminaLoss(shock_damage)
|
||||
else
|
||||
take_overall_damage(0,shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
|
||||
"<span class='italics'>You hear a heavy electrical crack.</span>" \
|
||||
)
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(2)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if(!tesla_shock || (tesla_shock && siemens_coeff > 0.5))
|
||||
Stun(3)
|
||||
Weaken(3)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
M << "<span class='warning'>You can't put them out with just your bare hands!"
|
||||
return
|
||||
|
||||
if(health >= 0 && !(status_flags & FAKEDEATH))
|
||||
|
||||
if(lying)
|
||||
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
|
||||
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
|
||||
else
|
||||
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
AdjustSleeping(-5)
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
if(resting)
|
||||
resting = 0
|
||||
update_canmove()
|
||||
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
|
||||
/mob/living/carbon/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0)
|
||||
. = ..()
|
||||
|
||||
var/damage = intensity - get_eye_protection()
|
||||
if(.) // we've been flashed
|
||||
if(visual)
|
||||
return
|
||||
|
||||
if (damage == 1)
|
||||
src << "<span class='warning'>Your eyes sting a little.</span>"
|
||||
if(prob(40))
|
||||
adjust_eye_damage(1)
|
||||
|
||||
else if (damage == 2)
|
||||
src << "<span class='warning'>Your eyes burn.</span>"
|
||||
adjust_eye_damage(rand(2, 4))
|
||||
|
||||
else if( damage > 3)
|
||||
src << "<span class='warning'>Your eyes itch and burn severely!</span>"
|
||||
adjust_eye_damage(rand(12, 16))
|
||||
|
||||
if(eye_damage > 10)
|
||||
blind_eyes(damage)
|
||||
blur_eyes(damage * rand(3, 6))
|
||||
|
||||
if(eye_damage > 20)
|
||||
if(prob(eye_damage - 20))
|
||||
if(become_nearsighted())
|
||||
src << "<span class='warning'>Your eyes start to burn badly!</span>"
|
||||
else if(prob(eye_damage - 25))
|
||||
if(become_blind())
|
||||
src << "<span class='warning'>You can't see anything!</span>"
|
||||
else
|
||||
src << "<span class='warning'>Your eyes are really starting to hurt. This can't be good for you!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(-500)
|
||||
return 1
|
||||
else if(damage == 0) // just enough protection
|
||||
if(prob(20))
|
||||
src << "<span class='notice'>Something bright flashes in the corner of your vision!</span>"
|
||||
if(has_bane(BANE_LIGHT))
|
||||
mind.disrupt_spells(0)
|
||||
|
||||
|
||||
/mob/living/carbon/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
|
||||
var/ear_safety = get_ear_protection()
|
||||
if(ear_safety < 2) //has ears
|
||||
var/effect_amount = intensity - ear_safety
|
||||
if(effect_amount > 0)
|
||||
if(stun_pwr)
|
||||
Stun(stun_pwr*effect_amount)
|
||||
Weaken(stun_pwr*effect_amount)
|
||||
if(deafen_pwr || damage_pwr)
|
||||
setEarDamage(ear_damage + damage_pwr*effect_amount, max(ear_deaf, deafen_pwr*effect_amount))
|
||||
if (ear_damage >= 15)
|
||||
src << "<span class='warning'>Your ears start to ring badly!</span>"
|
||||
if(prob(ear_damage - 5))
|
||||
src << "<span class='warning'>You can't hear anything!</span>"
|
||||
disabilities |= DEAF
|
||||
else if(ear_damage >= 5)
|
||||
src << "<span class='warning'>Your ears start to ring!</span>"
|
||||
src << sound('sound/weapons/flash_ring.ogg',0,1,0,250)
|
||||
return effect_amount //how soundbanged we are
|
||||
|
||||
|
||||
/mob/living/carbon/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
if(damage_type != BRUTE && damage_type != BURN)
|
||||
return
|
||||
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
|
||||
if(!def_zone || def_zone == "head")
|
||||
var/obj/item/clothing/hit_clothes
|
||||
if(wear_mask)
|
||||
hit_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
hit_clothes = wear_neck
|
||||
if(head)
|
||||
hit_clothes = head
|
||||
if(hit_clothes)
|
||||
hit_clothes.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/mob/living/
|
||||
var/list/stomach_contents = list()
|
||||
|
||||
/mob/living/carbon
|
||||
gender = MALE
|
||||
//var/list/stomach_contents = list()
|
||||
pressure_resistance = 15
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
|
||||
var/list/stomach_contents = list()
|
||||
var/list/internal_organs = list() //List of /obj/item/organ in the mob. They don't go in the contents for some reason I don't want to know.
|
||||
var/list/internal_organs_slot = list() //Same as above, but stores "slot ID" - "organ" pairs for easy access.
|
||||
|
||||
@@ -15,17 +14,24 @@
|
||||
//inventory slots
|
||||
var/obj/item/back = null
|
||||
var/obj/item/clothing/mask/wear_mask = null
|
||||
var/obj/item/clothing/neck/wear_neck = null
|
||||
var/obj/item/weapon/tank/internal = null
|
||||
var/obj/item/head = null
|
||||
|
||||
var/obj/item/gloves = null //only used by humans
|
||||
var/obj/item/shoes = null //only used by humans.
|
||||
var/obj/item/clothing/glasses/glasses = null //only used by humans.
|
||||
var/obj/item/ears = null //only used by humans.
|
||||
|
||||
var/datum/dna/dna = null//Carbon
|
||||
var/datum/mind/last_mind = null //last mind to control this mob, for blood-based cloning
|
||||
|
||||
var/failed_last_breath = 0 //This is used to determine if the mob failed a breath. If they did fail a brath, they will attempt to breathe each tick, otherwise just once per 4 ticks.
|
||||
|
||||
var/co2overloadtime = null
|
||||
var/temperature_resistance = T0C+75
|
||||
has_limbs = 1
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/
|
||||
var/obj/item/weapon/reagent_containers/food/snacks/meat/slab/type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab
|
||||
|
||||
var/list/obj/effect/proc_holder/alien/abilities = list()
|
||||
var/gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
@@ -34,4 +40,8 @@
|
||||
|
||||
var/tinttotal = 0 // Total level of visualy impairing items
|
||||
|
||||
var/list/bodyparts = list() //Gets filled up in the constructor (New() proc in human.dm and monkey.dm)
|
||||
var/list/bodyparts = list(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
//Gets filled up in create_bodyparts()
|
||||
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
@@ -1,16 +1,35 @@
|
||||
/mob/living/carbon/movement_delay()
|
||||
. = ..()
|
||||
. += grab_state * 3
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
var/FP
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
var/obj/item/device/flightpack/F = C.get_flightpack()
|
||||
if(istype(F) && F.flight)
|
||||
FP = 1
|
||||
. = ..(FP)
|
||||
if(!FP)
|
||||
. += grab_state * 1 //Flightpacks are too powerful to be slowed too much by the weight of a corpse.
|
||||
else
|
||||
. += grab_state * 3 //can't go fast while grabbing something.
|
||||
|
||||
if(!get_leg_ignore()) //ignore the fact we lack legs
|
||||
var/leg_amount = get_num_legs()
|
||||
. += 6 - 3*leg_amount //the fewer the legs, the slower the mob
|
||||
if(!leg_amount)
|
||||
. += 6 - 3*get_num_arms() //crawling is harder with fewer arms
|
||||
if(legcuffed)
|
||||
. += legcuffed.slowdown
|
||||
|
||||
|
||||
var/const/NO_SLIP_WHEN_WALKING = 1
|
||||
var/const/SLIDE = 2
|
||||
var/const/GALOSHES_DONT_HELP = 4
|
||||
var/const/SLIDE_ICE = 8
|
||||
|
||||
/mob/living/carbon/slip(s_amount, w_amount, obj/O, lube)
|
||||
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
|
||||
if(movement_type & FLYING)
|
||||
return 0
|
||||
if(!(lube&SLIDE_ICE))
|
||||
add_logs(src,, "slipped",, "on [O ? O.name : "floor"]")
|
||||
return loc.handle_slip(src, s_amount, w_amount, O, lube)
|
||||
|
||||
|
||||
@@ -20,6 +39,10 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
if(!isturf(loc))
|
||||
return 0
|
||||
|
||||
var/obj/item/device/flightpack/F = get_flightpack()
|
||||
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
// Do we have a jetpack implant (and is it on)?
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = getorganslot("thrusters")
|
||||
if(istype(T) && movement_dir && T.allow_thrust(0.01))
|
||||
@@ -29,14 +52,14 @@ var/const/GALOSHES_DONT_HELP = 4
|
||||
if(istype(J) && (movement_dir || J.stabilizers) && J.allow_thrust(0.01, src))
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
if(src.nutrition && src.stat != 2)
|
||||
src.nutrition -= HUNGER_FACTOR/10
|
||||
if(src.m_intent == "run")
|
||||
src.nutrition -= HUNGER_FACTOR/10
|
||||
if((src.disabilities & FAT) && src.m_intent == "run" && src.bodytemperature <= 360)
|
||||
src.bodytemperature += 2
|
||||
if(. && mob_has_gravity()) //floating is easy
|
||||
if(dna && dna.species && (NOHUNGER in dna.species.species_traits))
|
||||
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
if(m_intent == MOVE_INTENT_RUN)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
if((disabilities & FAT) && m_intent == MOVE_INTENT_RUN && bodytemperature <= 360)
|
||||
bodytemperature += 2
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
|
||||
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || hit_percent <= 0)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
if(islimb(def_zone)) //we specified a bodypart object
|
||||
BP = def_zone
|
||||
else
|
||||
if(!def_zone)
|
||||
def_zone = ran_zone(def_zone)
|
||||
BP = get_bodypart(check_zone(def_zone))
|
||||
if(!BP)
|
||||
BP = bodyparts[1]
|
||||
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
if(BP)
|
||||
if(BP.receive_damage(damage * hit_percent, 0))
|
||||
update_damage_overlays()
|
||||
else //no bodypart, we deal damage with a more general method.
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
if(BURN)
|
||||
if(BP)
|
||||
if(BP.receive_damage(0, damage * hit_percent))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * hit_percent)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0, updating_health)
|
||||
else
|
||||
heal_overall_damage(-amount, 0, 0, 1, updating_health)
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && (status_flags & GODMODE))
|
||||
return FALSE
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount, updating_health)
|
||||
else
|
||||
heal_overall_damage(0, -amount, 0, 1, updating_health)
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && has_dna() && TOXINLOVER in dna.species.species_traits) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
else
|
||||
blood_volume -= amount
|
||||
return ..()
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/proc/get_damaged_bodyparts(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable bodyparts
|
||||
/mob/living/carbon/proc/get_damageable_bodyparts()
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Heals ONE bodypart randomly selected from damaged ones.
|
||||
//It automatically updates damage overlays if necessary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/heal_bodypart_damage(brute, burn, only_robotic = 0, only_organic = 1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.heal_damage(brute, burn, only_robotic, only_organic))
|
||||
update_damage_overlays()
|
||||
|
||||
//Damages ONE bodypart randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necessary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/take_bodypart_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.receive_damage(brute,burn))
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
/mob/living/carbon/heal_overall_damage(brute, burn, only_robotic = 0, only_organic = 1, updating_health = 1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
update |= picked.heal_damage(brute,burn, only_robotic, only_organic, 0)
|
||||
|
||||
brute -= (brute_was-picked.brute_dam)
|
||||
burn -= (burn_was-picked.burn_dam)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/take_overall_damage(brute, burn, updating_health = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return //godmode
|
||||
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
var/brute_per_part = round(brute/parts.len, 0.01)
|
||||
var/burn_per_part = round(burn/parts.len, 0.01)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
|
||||
update |= picked.receive_damage(brute_per_part,burn_per_part, 0)
|
||||
|
||||
brute -= (picked.brute_dam - brute_was)
|
||||
burn -= (picked.burn_dam - burn_was)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/adjustStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = Clamp(staminaloss + amount, 0, maxHealth*2)
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
|
||||
|
||||
/mob/living/carbon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
staminaloss = amount
|
||||
if(updating_stamina)
|
||||
update_stamina()
|
||||
@@ -1,21 +1,54 @@
|
||||
/mob/living/carbon/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
silent = 0
|
||||
losebreath = 0
|
||||
..()
|
||||
|
||||
/mob/living/carbon/gib(no_brain, no_organs)
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
|
||||
. = ..()
|
||||
if(ticker && ticker.mode)
|
||||
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
|
||||
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
|
||||
for(var/mob/M in src)
|
||||
if(M in stomach_contents)
|
||||
stomach_contents.Remove(M)
|
||||
M.loc = loc
|
||||
M.forceMove(loc)
|
||||
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
|
||||
..()
|
||||
|
||||
/mob/living/carbon/spill_organs(no_brain)
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
if(no_brain && istype(I, /obj/item/organ/brain))
|
||||
continue
|
||||
if(I)
|
||||
/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts)
|
||||
if(!no_bodyparts)
|
||||
if(no_organs)//so the organs don't get transfered inside the bodyparts we'll drop.
|
||||
for(var/X in internal_organs)
|
||||
qdel(X)
|
||||
else //we're going to drop all bodyparts except chest, so the only organs that needs spilling are those inside it.
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/O = X
|
||||
if(no_brain && istype(O, /obj/item/organ/brain))
|
||||
qdel(O) //so the brain isn't transfered to the head when the head drops.
|
||||
continue
|
||||
var/org_zone = check_zone(O.zone) //both groin and chest organs.
|
||||
if(org_zone == "chest")
|
||||
O.Remove(src)
|
||||
O.forceMove(get_turf(src))
|
||||
O.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
else
|
||||
for(var/X in internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
if(no_brain && istype(I, /obj/item/organ/brain))
|
||||
qdel(I)
|
||||
continue
|
||||
I.Remove(src)
|
||||
I.loc = get_turf(src)
|
||||
I.throw_at_fast(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
I.forceMove(get_turf(src))
|
||||
I.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
|
||||
|
||||
/mob/living/carbon/spread_bodyparts()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.drop_limb()
|
||||
BP.throw_at(get_edge_target_turf(src,pick(alldirs)),rand(1,3),5)
|
||||
@@ -1,200 +1,86 @@
|
||||
//This only assumes that the mob has a body and face with at least one eye, and one mouth.
|
||||
//Things like airguitar can be done without arms, and the flap thing makes so little sense it's a keeper.
|
||||
//Intended to be called by a higher up emote proc if the requested emote isn't in the custom emotes.
|
||||
/datum/emote/living/carbon
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon)
|
||||
|
||||
/mob/living/carbon/emote(act,m_type=1,message = null)
|
||||
var/param = null
|
||||
/datum/emote/living/carbon/airguitar
|
||||
key = "airguitar"
|
||||
message = "is strumming the air and headbanging like a safari chimp."
|
||||
restraint_check = TRUE
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
/datum/emote/living/carbon/blink
|
||||
key = "blink"
|
||||
key_third_person = "blinks"
|
||||
message = "blinks."
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
//var/m_type = 1
|
||||
/datum/emote/living/carbon/blink_r
|
||||
key = "blink_r"
|
||||
message = "blinks rapidly."
|
||||
|
||||
switch(act)//Even carbon organisms want it alphabetically ordered..
|
||||
if ("aflap")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings ANGRILY!"
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/clap
|
||||
key = "clap"
|
||||
key_third_person = "claps"
|
||||
message = "claps."
|
||||
muzzle_ignore = TRUE
|
||||
restraint_check = TRUE
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
if ("airguitar")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> is strumming the air and headbanging like a safari chimp."
|
||||
m_type = 1
|
||||
/datum/emote/living/carbon/gnarl
|
||||
key = "gnarl"
|
||||
key_third_person = "gnarls"
|
||||
message = "gnarls and shows its teeth..."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
|
||||
if ("blink","blinks")
|
||||
message = "<B>[src]</B> blinks."
|
||||
m_type = 1
|
||||
/datum/emote/living/carbon/moan
|
||||
key = "moan"
|
||||
key_third_person = "moans"
|
||||
message = "moans!"
|
||||
message_mime = "appears to moan!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
if ("blink_r")
|
||||
message = "<B>[src]</B> blinks rapidly."
|
||||
m_type = 1
|
||||
/datum/emote/living/carbon/roll
|
||||
key = "roll"
|
||||
key_third_person = "rolls"
|
||||
message = "rolls."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("blush","blushes")
|
||||
message = "<B>[src]</B> blushes."
|
||||
m_type = 1
|
||||
/datum/emote/living/carbon/scratch
|
||||
key = "scratch"
|
||||
key_third_person = "scratches"
|
||||
message = "scratches."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("bow","bows")
|
||||
if (!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
param = null
|
||||
if (param)
|
||||
message = "<B>[src]</B> bows to [param]."
|
||||
else
|
||||
message = "<B>[src]</B> bows."
|
||||
m_type = 1
|
||||
/datum/emote/living/carbon/screech
|
||||
key = "screech"
|
||||
key_third_person = "screeches"
|
||||
message = "screeches."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
|
||||
if ("burp","burps")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
/datum/emote/living/carbon/sign
|
||||
key = "sign"
|
||||
key_third_person = "signs"
|
||||
message_param = "signs the number %t."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("choke","chokes")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a strong noise."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/sign/select_param(mob/user, params)
|
||||
. = ..()
|
||||
if(!isnum(text2num(params)))
|
||||
return message
|
||||
|
||||
if ("chuckle","chuckles")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/sign/signal
|
||||
key = "signal"
|
||||
key_third_person = "signals"
|
||||
message_param = "raises %t fingers."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("clap","claps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> claps."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/tail
|
||||
key = "tail"
|
||||
message = "waves their tail."
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/monkey, /mob/living/carbon/alien)
|
||||
|
||||
if ("cough","coughs")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a strong noise."
|
||||
m_type = 2
|
||||
|
||||
if ("deathgasp","deathgasps")
|
||||
message = "<B>[src]</B> seizes up and falls limp, \his eyes dead and lifeless..."
|
||||
m_type = 1
|
||||
|
||||
if ("flap","flaps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings."
|
||||
m_type = 2
|
||||
|
||||
if ("gasp","gasps")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a weak noise."
|
||||
m_type = 2
|
||||
|
||||
if ("giggle","giggles")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("laugh","laughs")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
|
||||
if ("me")
|
||||
if(!silent)
|
||||
..()
|
||||
return
|
||||
|
||||
if ("nod","nods")
|
||||
message = "<B>[src]</B> nods."
|
||||
m_type = 1
|
||||
|
||||
if ("scream","screams")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a very loud noise."
|
||||
m_type = 2
|
||||
|
||||
if ("shake","shakes")
|
||||
message = "<B>[src]</B> shakes \his head."
|
||||
m_type = 1
|
||||
|
||||
if ("sneeze","sneezes")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a strange noise."
|
||||
m_type = 2
|
||||
|
||||
if ("sigh","sighs")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> sighs."
|
||||
m_type = 2
|
||||
|
||||
if ("sniff","sniffs")
|
||||
message = "<B>[src]</B> sniffs."
|
||||
m_type = 2
|
||||
|
||||
if ("snore","snores")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("whimper","whimpers")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
else
|
||||
message = "<B>[src]</B> makes a weak noise."
|
||||
m_type = 2
|
||||
|
||||
if ("wink","winks")
|
||||
message = "<B>[src]</B> winks."
|
||||
m_type = 1
|
||||
|
||||
if ("yawn","yawns")
|
||||
if (!muzzled)
|
||||
..(act)
|
||||
|
||||
if ("help")
|
||||
src << "Help for emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, giggle, glare-(none)/mob, grin, jump, laugh, look, me, nod, point-atom, scream, shake, sigh, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, yawn"
|
||||
|
||||
else
|
||||
..(act)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (message)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
|
||||
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else if (m_type & 2)
|
||||
audible_message(message)
|
||||
/datum/emote/living/carbon/wink
|
||||
key = "wink"
|
||||
key_third_person = "winks"
|
||||
message = "winks."
|
||||
|
||||
@@ -1,64 +1,90 @@
|
||||
/mob/living/carbon/examine(mob/user)
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
var/t_his = p_their()
|
||||
var/t_him = p_them()
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is \icon[src] \a <EM>[src]</EM>!\n"
|
||||
|
||||
if (handcuffed)
|
||||
msg += "It is \icon[src.handcuffed] handcuffed!\n"
|
||||
msg += "<span class='warning'>[t_He] [t_is] \icon[src.handcuffed] handcuffed!</span>\n"
|
||||
if (head)
|
||||
msg += "It has \icon[src.head] \a [src.head] on its head. \n"
|
||||
msg += "[t_He] [t_is] wearing \icon[src.head] \a [src.head] on [t_his] head. \n"
|
||||
if (wear_mask)
|
||||
msg += "It has \icon[src.wear_mask] \a [src.wear_mask] on its face.\n"
|
||||
if (l_hand)
|
||||
msg += "It has \icon[src.l_hand] \a [src.l_hand] in its left hand.\n"
|
||||
if (r_hand)
|
||||
msg += "It has \icon[src.r_hand] \a [src.r_hand] in its right hand.\n"
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_mask] \a [src.wear_mask] on [t_his] face.\n"
|
||||
if (wear_neck)
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
|
||||
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
if (back)
|
||||
msg += "It has \icon[src.back] \a [src.back] on its back.\n"
|
||||
msg += "[t_He] [t_has] \icon[src.back] \a [src.back] on [t_his] back.\n"
|
||||
var/appears_dead = 0
|
||||
if (stat == DEAD)
|
||||
msg += "<span class='deadsay'>It is limp and unresponsive, with no signs of life.</span>\n"
|
||||
else
|
||||
msg += "<span class='warning'>"
|
||||
var/temp = getBruteLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor bruising.\n"
|
||||
else
|
||||
msg += "<B>It has severe bruising!</B>\n"
|
||||
appears_dead = 1
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive, with no signs of life.</span>\n"
|
||||
else if(get_bodypart("head"))
|
||||
msg += "<span class='deadsay'>[t_He] appears that [t_his] brain is missing...</span>\n"
|
||||
|
||||
temp = getFireLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "It has minor burns.\n"
|
||||
else
|
||||
msg += "<B>It has severe burns!</B>\n"
|
||||
var/list/missing = get_missing_limbs()
|
||||
for(var/t in missing)
|
||||
if(t=="head")
|
||||
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
|
||||
continue
|
||||
msg += "<span class='warning'><B>[t_His] [parse_zone(t)] is missing!</B></span>\n"
|
||||
|
||||
temp = getCloneLoss()
|
||||
if(temp)
|
||||
if(getCloneLoss() < 30)
|
||||
msg += "It is slightly deformed.\n"
|
||||
else
|
||||
msg += "<b>It is severely deformed.</b>\n"
|
||||
msg += "<span class='warning'>"
|
||||
var/temp = getBruteLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "[t_He] [t_has] minor bruising.\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] severe bruising!</B>\n"
|
||||
|
||||
if(getBrainLoss() > 60)
|
||||
msg += "It seems to be clumsy and unable to think.\n"
|
||||
temp = getFireLoss()
|
||||
if(temp)
|
||||
if (temp < 30)
|
||||
msg += "[t_He] [t_has] minor burns.\n"
|
||||
else
|
||||
msg += "<B>[t_He] [t_has] severe burns!</B>\n"
|
||||
|
||||
if(fire_stacks > 0)
|
||||
msg += "It's covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "It's soaked in water.\n"
|
||||
temp = getCloneLoss()
|
||||
if(temp)
|
||||
if(getCloneLoss() < 30)
|
||||
msg += "[t_He] [t_is] slightly deformed.\n"
|
||||
else
|
||||
msg += "<b>[t_He] [t_is] severely deformed.</b>\n"
|
||||
|
||||
if(pulledby && pulledby.grab_state)
|
||||
msg += "It's restrained by [pulledby]'s grip.\n"
|
||||
if(getBrainLoss() > 60)
|
||||
msg += "[t_He] seems to be clumsy and unable to think.\n"
|
||||
|
||||
if(fire_stacks > 0)
|
||||
msg += "[t_He] [t_is] covered in something flammable.\n"
|
||||
if(fire_stacks < 0)
|
||||
msg += "[t_He] [t_is] looks a little soaked.\n"
|
||||
|
||||
if(pulledby && pulledby.grab_state)
|
||||
msg += "[t_He] [t_is] restrained by [pulledby]'s grip.\n"
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
if(!appears_dead)
|
||||
if(stat == UNCONSCIOUS)
|
||||
msg += "It isn't responding to anything around it; it seems to be asleep.\n"
|
||||
msg += "</span>"
|
||||
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seems to be asleep.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
if(digitalcamo)
|
||||
msg += "It is moving its body in an unnatural and blatantly unsimian manner.\n"
|
||||
|
||||
if(!getorgan(/obj/item/organ/brain))
|
||||
msg += "<span class='deadsay'>It appears that it's brain is missing...</span>\n"
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
user << msg
|
||||
user << msg
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
@@ -1,11 +1,14 @@
|
||||
/mob/living/carbon/human/gib_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-h"))
|
||||
new /obj/effect/overlay/temp/gib_animation(loc, "gibbed-h")
|
||||
|
||||
/mob/living/carbon/human/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-h"))
|
||||
new /obj/effect/overlay/temp/dust_animation(loc, "dust-h")
|
||||
|
||||
/mob/living/carbon/human/spawn_gibs()
|
||||
hgibs(loc, viruses, dna)
|
||||
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/human(loc, viruses, dna)
|
||||
else
|
||||
new /obj/effect/gibspawner/humanbodypartless(loc, viruses, dna)
|
||||
|
||||
/mob/living/carbon/human/spawn_dust()
|
||||
new /obj/effect/decal/remains/human(loc)
|
||||
@@ -13,7 +16,9 @@
|
||||
/mob/living/carbon/human/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
stat = DEAD
|
||||
|
||||
. = ..()
|
||||
|
||||
dizziness = 0
|
||||
jitteriness = 0
|
||||
heart_attack = 0
|
||||
@@ -23,39 +28,21 @@
|
||||
if(M.occupant == src)
|
||||
M.go_out()
|
||||
|
||||
if(!gibbed)
|
||||
emote("deathgasp") //let the world KNOW WE ARE DEAD
|
||||
|
||||
dna.species.spec_death(gibbed, src)
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
sql_report_death(src)
|
||||
ticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
|
||||
. = ..(gibbed)
|
||||
if(mind && mind.devilinfo)
|
||||
spawn(0)
|
||||
mind.devilinfo.beginResurrectionCheck(src)
|
||||
INVOKE_ASYNC(mind.devilinfo, /datum/devilinfo.proc/beginResurrectionCheck, src)
|
||||
|
||||
/mob/living/carbon/human/proc/makeSkeleton()
|
||||
status_flags |= DISFIGURED
|
||||
set_species(/datum/species/skeleton)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/proc/ChangeToHusk()
|
||||
if(disabilities & HUSK)
|
||||
return
|
||||
disabilities |= HUSK
|
||||
status_flags |= DISFIGURED //makes them unknown without fucking up other stuff like admintools
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/ChangeToHusk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/proc/Drain()
|
||||
ChangeToHusk()
|
||||
become_husk()
|
||||
disabilities |= NOCLONE
|
||||
blood_volume = 0
|
||||
return 1
|
||||
|
||||
@@ -1,414 +1,126 @@
|
||||
/mob/living/carbon/human/emote(act,m_type=1,message = null)
|
||||
if(stat == DEAD && (act != "deathgasp") || (status_flags & FAKEDEATH)) //if we're faking, don't emote at all
|
||||
return
|
||||
/datum/emote/living/carbon/human
|
||||
mob_type_allowed_typecache = list(/mob/living/carbon/human)
|
||||
|
||||
var/param = null
|
||||
/datum/emote/living/carbon/human/cry
|
||||
key = "cry"
|
||||
key_third_person = "cries"
|
||||
message = "cries."
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
/datum/emote/living/carbon/human/dap
|
||||
key = "dap"
|
||||
key_third_person = "daps"
|
||||
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
|
||||
message_param = "give daps to %t."
|
||||
restraint_check = TRUE
|
||||
|
||||
/datum/emote/living/carbon/human/eyebrow
|
||||
key = "eyebrow"
|
||||
message = "raises an eyebrow."
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
//var/m_type = 1
|
||||
/datum/emote/living/carbon/human/grumble
|
||||
key = "grumble"
|
||||
key_third_person = "grumbles"
|
||||
message = "grumbles!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
for (var/obj/item/weapon/implant/I in src)
|
||||
if (I.implanted)
|
||||
I.trigger(act, src)
|
||||
/datum/emote/living/carbon/human/handshake
|
||||
key = "handshake"
|
||||
message = "shakes their own hands."
|
||||
message_param = "shakes hands with %t."
|
||||
restraint_check = TRUE
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
var/miming=0
|
||||
if(mind)
|
||||
miming=mind.miming
|
||||
/datum/emote/living/carbon/human/hug
|
||||
key = "hug"
|
||||
key_third_person = "hugs"
|
||||
message = "hugs themself."
|
||||
message_param = "hugs %t."
|
||||
restraint_check = TRUE
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
switch(act) //Please keep this alphabetically ordered when adding or changing emotes.
|
||||
if ("aflap") //Any emote on human that uses miming must be left in, oh well.
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings ANGRILY!"
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/human/mumble
|
||||
key = "mumble"
|
||||
key_third_person = "mumbles"
|
||||
message = "mumbles!"
|
||||
emote_type = EMOTE_AUDIBLE
|
||||
|
||||
if ("choke","chokes")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> clutches \his throat desperately!"
|
||||
else
|
||||
..(act)
|
||||
/datum/emote/living/carbon/human/pale
|
||||
key = "pale"
|
||||
message = "goes pale for a second."
|
||||
|
||||
if ("chuckle","chuckles")
|
||||
if(miming)
|
||||
message = "<B>[src]</B> appears to chuckle."
|
||||
else
|
||||
..(act)
|
||||
/datum/emote/living/carbon/human/raise
|
||||
key = "raise"
|
||||
key_third_person = "raises"
|
||||
message = "raises a hand."
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("clap","claps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> claps."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/human/salute
|
||||
key = "salute"
|
||||
key_third_person = "salutes"
|
||||
message = "salutes."
|
||||
message_param = "salutes to %t."
|
||||
restraint_check = TRUE
|
||||
|
||||
if ("collapse","collapses")
|
||||
Paralyse(2)
|
||||
adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option.
|
||||
message = "<B>[src]</B> collapses!"
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/human/shrug
|
||||
key = "shrug"
|
||||
key_third_person = "shrugs"
|
||||
message = "shrugs."
|
||||
|
||||
if ("cough","coughs")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears to cough!"
|
||||
else
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> coughs!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> makes a strong noise."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/human/wag
|
||||
key = "wag"
|
||||
key_third_person = "wags"
|
||||
message = "wags their tail."
|
||||
|
||||
if ("cry","crys","cries") //I feel bad if people put s at the end of cry. -Sum99
|
||||
if (miming)
|
||||
message = "<B>[src]</B> cries."
|
||||
else
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> cries."
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> makes a weak noise. \He frowns."
|
||||
m_type = 2
|
||||
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(.)
|
||||
H.startTailWag()
|
||||
else
|
||||
H.endTailWag()
|
||||
|
||||
if ("custom")
|
||||
if(jobban_isbanned(src, "emote"))
|
||||
src << "You cannot send custom emotes (banned)"
|
||||
return
|
||||
if(src.client)
|
||||
if(client.prefs.muted & MUTE_IC)
|
||||
src << "You cannot send IC messages (muted)."
|
||||
return
|
||||
var/input = copytext(sanitize(input("Choose an emote to display.") as text|null),1,MAX_MESSAGE_LEN)
|
||||
if (!input)
|
||||
return
|
||||
if(copytext(input,1,5) == "says")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(input,1,9) == "exclaims")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(input,1,6) == "yells")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(input,1,5) == "asks")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else
|
||||
var/input2 = input("Is this a visible or hearable emote?") in list("Visible","Hearable")
|
||||
if (input2 == "Visible")
|
||||
m_type = 1
|
||||
else if (input2 == "Hearable")
|
||||
if(miming)
|
||||
return
|
||||
m_type = 2
|
||||
else
|
||||
alert("Unable to use this emote, must be either hearable or visible.")
|
||||
return
|
||||
message = "<B>[src]</B> [input]"
|
||||
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna && H.dna.species && (("tail_lizard" in H.dna.species.mutant_bodyparts) || (H.dna.features["tail_human"] != "None")))
|
||||
return TRUE
|
||||
|
||||
if ("dap","daps")
|
||||
m_type = 1
|
||||
if (!src.restrained())
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M)
|
||||
message = "<B>[src]</B> gives daps to [M]."
|
||||
else
|
||||
message = "<B>[src]</B> sadly can't find anybody to give daps to, and daps \himself. Shameful."
|
||||
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts))
|
||||
. = null
|
||||
|
||||
if ("eyebrow")
|
||||
message = "<B>[src]</B> raises an eyebrow."
|
||||
m_type = 1
|
||||
|
||||
if ("flap","flaps")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flaps \his wings."
|
||||
m_type = 2
|
||||
if(((dna.features["wings"] != "None") && !("wings" in dna.species.mutant_bodyparts)))
|
||||
OpenWings()
|
||||
addtimer(src, "CloseWings", 20)
|
||||
|
||||
if ("wings")
|
||||
if (!src.restrained())
|
||||
if(dna && dna.species &&((dna.features["wings"] != "None") && ("wings" in dna.species.mutant_bodyparts)))
|
||||
message = "<B>[src]</B> opens \his wings."
|
||||
OpenWings()
|
||||
else if(dna && dna.species &&((dna.features["wings"] != "None") && ("wingsopen" in dna.species.mutant_bodyparts)))
|
||||
message = "<B>[src]</B> closes \his wings."
|
||||
CloseWings()
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
|
||||
if ("gasp","gasps")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears to be gasping!"
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("giggle","giggles")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> giggles silently!"
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("groan","groans")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears to groan!"
|
||||
else
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> groans!"
|
||||
m_type = 2
|
||||
else
|
||||
message = "<B>[src]</B> makes a loud noise."
|
||||
m_type = 2
|
||||
|
||||
if ("grumble","grumbles")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> grumbles!"
|
||||
else
|
||||
message = "<B>[src]</B> makes a noise."
|
||||
m_type = 2
|
||||
|
||||
if ("handshake")
|
||||
m_type = 1
|
||||
if (!src.restrained() && !src.r_hand)
|
||||
var/mob/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M == src)
|
||||
M = null
|
||||
if (M)
|
||||
if (M.canmove && !M.r_hand && !M.restrained())
|
||||
message = "<B>[src]</B> shakes hands with [M]."
|
||||
else
|
||||
message = "<B>[src]</B> holds out \his hand to [M]."
|
||||
|
||||
if ("hug","hugs")
|
||||
m_type = 1
|
||||
if (!src.restrained())
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (M == src)
|
||||
M = null
|
||||
if (M)
|
||||
message = "<B>[src]</B> hugs [M]."
|
||||
else
|
||||
message = "<B>[src]</B> hugs \himself."
|
||||
|
||||
if ("me")
|
||||
if(silent)
|
||||
return
|
||||
if(jobban_isbanned(src, "emote"))
|
||||
src << "You cannot send custom emotes (banned)"
|
||||
return
|
||||
if (src.client)
|
||||
if (client.prefs.muted & MUTE_IC)
|
||||
src << "<span class='danger'>You cannot send IC messages (muted).</span>"
|
||||
return
|
||||
if (src.client.handle_spam_prevention(message,MUTE_IC))
|
||||
return
|
||||
if (stat)
|
||||
return
|
||||
if(!(message))
|
||||
return
|
||||
if(copytext(message,1,5) == "says")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(message,1,9) == "exclaims")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(message,1,6) == "yells")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else if(copytext(message,1,5) == "asks")
|
||||
src << "<span class='danger'>Invalid emote.</span>"
|
||||
return
|
||||
else
|
||||
message = "<B>[src]</B> [message]"
|
||||
|
||||
if ("moan","moans")
|
||||
if(miming)
|
||||
message = "<B>[src]</B> appears to moan!"
|
||||
else
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
|
||||
if ("mumble","mumbles")
|
||||
message = "<B>[src]</B> mumbles!"
|
||||
m_type = 2
|
||||
|
||||
if ("pale")
|
||||
message = "<B>[src]</B> goes pale for a second."
|
||||
m_type = 1
|
||||
|
||||
if ("raise")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> raises a hand."
|
||||
m_type = 1
|
||||
|
||||
if ("roar","roars")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears to roar!"
|
||||
else
|
||||
if(!muzzled && has_dna())
|
||||
m_type = 2
|
||||
message = "<B>[src]</B> roars!"
|
||||
switch(dna.species.id)
|
||||
if("pred")
|
||||
playsound(get_turf(src), "predroar", 50, 0, 5)
|
||||
if("xeno")
|
||||
playsound(get_turf(src), "alienscreech", 50, 0, 5)
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("salute","salutes")
|
||||
if (!src.buckled)
|
||||
var/M = null
|
||||
if (param)
|
||||
for (var/mob/A in view(1, src))
|
||||
if (param == A.name)
|
||||
M = A
|
||||
break
|
||||
if (!M)
|
||||
param = null
|
||||
if (param)
|
||||
message = "<B>[src]</B> salutes to [param]."
|
||||
else
|
||||
message = "<B>[src]</b> salutes."
|
||||
m_type = 1
|
||||
|
||||
if ("scream","screams")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> acts out a scream!"
|
||||
else
|
||||
if(has_dna())
|
||||
switch(dna.species.id) //Visit sound.dm to see and add more 'soundin' options. (alienscreech, malescream, femscream, etc)
|
||||
if("xeno")
|
||||
playsound(get_turf(src), "alienscreech", 50, 0, 5)
|
||||
if("pred")
|
||||
playsound(get_turf(src), "predroar", 50, 0, 5)
|
||||
if("moth")
|
||||
playsound(get_turf(src), "mothscream", 50, 1, 5)
|
||||
if("lizard" || "drake")
|
||||
playsound(get_turf(src), "drakescream", 50, 0, 5)
|
||||
if("avian")
|
||||
playsound(get_turf(src), "birdscream", 50, 0, 5)
|
||||
else
|
||||
if(gender == MALE)
|
||||
playsound(get_turf(src), "malescream", 50, 0, 5)
|
||||
if(gender == FEMALE)
|
||||
playsound(get_turf(src), "femscream", 50, 0, 5)
|
||||
..(act)
|
||||
|
||||
if ("shiver","shivers")
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 1
|
||||
|
||||
if ("shrug","shrugs")
|
||||
message = "<B>[src]</B> shrugs."
|
||||
m_type = 1
|
||||
|
||||
if ("sigh","sighs")
|
||||
if(miming)
|
||||
message = "<B>[src]</B> sighs."
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("signal","signals")
|
||||
if (!src.restrained())
|
||||
var/t1 = round(text2num(param))
|
||||
if (isnum(t1))
|
||||
if (t1 <= 5 && (!src.r_hand || !src.l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
else if (t1 <= 10 && (!src.r_hand && !src.l_hand))
|
||||
message = "<B>[src]</B> raises [t1] finger\s."
|
||||
m_type = 1
|
||||
|
||||
if ("sneeze","sneezes")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> sneezes."
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("sniff","sniffs")
|
||||
message = "<B>[src]</B> sniffs."
|
||||
m_type = 2
|
||||
|
||||
if ("snore","snores")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> sleeps soundly."
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("whimper","whimpers")
|
||||
if (miming)
|
||||
message = "<B>[src]</B> appears hurt."
|
||||
else
|
||||
..(act)
|
||||
|
||||
if ("yawn","yawns")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> yawns."
|
||||
m_type = 2
|
||||
|
||||
if("wag","wags")
|
||||
if(dna && dna.species && (("tail_lizard" in dna.species.mutant_bodyparts) || ((dna.features["mam_tail"] != "None") && !("mam_waggingtail" in dna.species.mutant_bodyparts)) || ((dna.features["tail_human"] != "None") && !("waggingtail_human" in dna.species.mutant_bodyparts))))
|
||||
message = "<B>[src]</B> wags \his tail."
|
||||
startTailWag()
|
||||
else if(dna && dna.species && (("waggingtail_lizard" in dna.species.mutant_bodyparts) || ("mam_waggingtail" in dna.species.mutant_bodyparts) || ("waggingtail_human" in dna.species.mutant_bodyparts)))
|
||||
endTailWag()
|
||||
else
|
||||
src << "<span class='notice'>Unusable emote '[act]'. Say *help for a list.</span>"
|
||||
|
||||
if ("help") //This can stay at the bottom.
|
||||
if(has_dna(src))
|
||||
switch(dna.species.id)//Set lists of emotes for specific species. Not the best way to do this, but the easiest considering they'll share most emotes.
|
||||
if("pred")
|
||||
src << "Help for yautja emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, <b>roar</b>, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
|
||||
|
||||
else
|
||||
src << "Help for human emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, cry, custom, dance, dap, deathgasp, drool, eyebrow, faint, flap, frown, gasp, giggle, glare-(none)/mob, grin, groan, grumble, handshake, hug-(none)/mob, jump, laugh, look-(none)/mob, me, moan, mumble, nod, pale, point-(atom), raise, salute, scream, shake, shiver, shrug, sigh, signal-#1-10, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tremble, twitch, twitch_s, wave, whimper, wink, wings, wag, yawn"
|
||||
/datum/emote/living/carbon/human/wing
|
||||
key = "wing"
|
||||
key_third_person = "wings"
|
||||
message = "their wings."
|
||||
|
||||
/datum/emote/living/carbon/human/wing/run_emote(mob/user, params)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(findtext(select_message_type(user), "open"))
|
||||
H.OpenWings()
|
||||
else
|
||||
..(act)
|
||||
|
||||
if(miming)
|
||||
m_type = 1
|
||||
|
||||
|
||||
|
||||
if (message)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
|
||||
//Hearing gasp and such every five seconds is not good emotes were not global for a reason.
|
||||
// Maybe some people are okay with that.
|
||||
|
||||
for(var/mob/M in dead_mob_list)
|
||||
if(!M.client || istype(M, /mob/new_player))
|
||||
continue //skip monkeys, leavers and new players
|
||||
if(M.stat == DEAD && M.client && (M.client.prefs.chat_toggles & CHAT_GHOSTSIGHT) && !(M in viewers(src,null)))
|
||||
M.show_message(message)
|
||||
|
||||
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else if (m_type & 2)
|
||||
audible_message(message)
|
||||
H.CloseWings()
|
||||
|
||||
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if("wings" in H.dna.species.mutant_bodyparts)
|
||||
. = "opens " + message
|
||||
else
|
||||
. = "closes " + message
|
||||
|
||||
/datum/emote/living/carbon/human/wing/can_run_emote(mob/user)
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = user
|
||||
if(H.dna && H.dna.species && (H.dna.features["wings"] != "None"))
|
||||
return TRUE
|
||||
|
||||
//Don't know where else to put this, it's basically an emote
|
||||
/mob/living/carbon/human/proc/startTailWag()
|
||||
@@ -422,9 +134,6 @@
|
||||
if("tail_human" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "tail_human"
|
||||
dna.species.mutant_bodyparts |= "waggingtail_human"
|
||||
if("mam_tail" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "mam_tail"
|
||||
dna.species.mutant_bodyparts |= "mam_waggingtail"
|
||||
update_body()
|
||||
|
||||
|
||||
@@ -439,9 +148,6 @@
|
||||
if("waggingtail_human" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "waggingtail_human"
|
||||
dna.species.mutant_bodyparts |= "tail_human"
|
||||
if("mam_waggingtail" in dna.species.mutant_bodyparts)
|
||||
dna.species.mutant_bodyparts -= "mam_waggingtail"
|
||||
dna.species.mutant_bodyparts |= "mam_tail"
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/human/proc/OpenWings()
|
||||
@@ -460,9 +166,4 @@
|
||||
dna.species.mutant_bodyparts |= "wings"
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/human/verb/set_flavor()
|
||||
set name = "Set Flavor Text"
|
||||
set desc = "Sets an extended description of your character's features."
|
||||
set category = "IC"
|
||||
|
||||
flavor_text = copytext(sanitize(input(usr, "Please enter your new flavor text.", "Flavor text", null) as text), 1)
|
||||
//Ayy lmao
|
||||
|
||||
@@ -1,36 +1,17 @@
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
var/t_his = p_their()
|
||||
var/t_him = p_them()
|
||||
var/t_has = p_have()
|
||||
var/t_is = p_are()
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is <EM>[src.name]</EM>!\n"
|
||||
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
|
||||
|
||||
// crappy hacks because you can't do \his[src] etc. I'm sorry this proc is so unreadable, blame the text macros :<
|
||||
var/t_He = "It" //capitalised for use at the start of each line.
|
||||
var/t_his = "its"
|
||||
var/t_him = "it"
|
||||
var/t_has = "has"
|
||||
var/t_is = "is"
|
||||
|
||||
var/msg = "<span class='info'>*---------*\nThis is "
|
||||
|
||||
if( (slot_w_uniform in obscured) && skipface ) //big suits/masks/helmets make it hard to tell their gender
|
||||
t_He = "They"
|
||||
t_his = "their"
|
||||
t_him = "them"
|
||||
t_has = "have"
|
||||
t_is = "are"
|
||||
else
|
||||
switch(gender)
|
||||
if(MALE)
|
||||
t_He = "He"
|
||||
t_his = "his"
|
||||
t_him = "him"
|
||||
if(FEMALE)
|
||||
t_He = "She"
|
||||
t_his = "her"
|
||||
t_him = "her"
|
||||
|
||||
msg += "<EM>[src.name]</EM>!\n"
|
||||
|
||||
//uniform
|
||||
if(w_uniform && !(slot_w_uniform in obscured))
|
||||
//Ties
|
||||
@@ -73,19 +54,13 @@
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[back] \a [back] on [t_his] back.\n"
|
||||
|
||||
//left hand
|
||||
if(l_hand && !(l_hand.flags&ABSTRACT))
|
||||
if(l_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[l_hand] [l_hand.gender==PLURAL?"some":"a"] blood-stained [l_hand.name] in [t_his] left hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[l_hand] \a [l_hand] in [t_his] left hand.\n"
|
||||
|
||||
//right hand
|
||||
if(r_hand && !(r_hand.flags&ABSTRACT))
|
||||
if(r_hand.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[r_hand] [r_hand.gender==PLURAL?"some":"a"] blood-stained [r_hand.name] in [t_his] right hand!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[r_hand] \a [r_hand] in [t_his] right hand.\n"
|
||||
//Hands
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & ABSTRACT))
|
||||
if(I.blood_DNA)
|
||||
msg += "<span class='warning'>[t_He] [t_is] holding \icon[I] [I.gender==PLURAL?"some":"a"] blood-stained [I.name] in [t_his] [get_held_index_name(get_held_index_of_item(I))]!</span>\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] holding \icon[I] \a [I] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
//gloves
|
||||
if(gloves && !(slot_gloves in obscured))
|
||||
@@ -128,6 +103,9 @@
|
||||
else
|
||||
msg += "[t_He] [t_has] \icon[wear_mask] \a [wear_mask] on [t_his] face.\n"
|
||||
|
||||
if (wear_neck && !(slot_neck in obscured))
|
||||
msg += "[t_He] [t_is] wearing \icon[src.wear_neck] \a [src.wear_neck] around [t_his] neck.\n"
|
||||
|
||||
//eyes
|
||||
if(glasses && !(slot_glasses in obscured))
|
||||
if(glasses.blood_DNA)
|
||||
@@ -141,16 +119,6 @@
|
||||
|
||||
//ID
|
||||
if(wear_id)
|
||||
/*var/id
|
||||
if(istype(wear_id, /obj/item/device/pda))
|
||||
var/obj/item/device/pda/pda = wear_id
|
||||
id = pda.owner
|
||||
else if(istype(wear_id, /obj/item/weapon/card/id)) //just in case something other than a PDA/ID card somehow gets in the ID slot :[
|
||||
var/obj/item/weapon/card/id/idcard = wear_id
|
||||
id = idcard.registered_name
|
||||
if(id && (id != real_name) && (get_dist(src, user) <= 1) && prob(10))
|
||||
msg += "<span class='warning'>[t_He] [t_is] wearing \icon[wear_id] \a [wear_id] yet something doesn't seem right...</span>\n"
|
||||
else*/
|
||||
msg += "[t_He] [t_is] wearing \icon[wear_id] \a [wear_id].\n"
|
||||
|
||||
//Jitters
|
||||
@@ -162,20 +130,14 @@
|
||||
if(100 to 200)
|
||||
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
|
||||
|
||||
if(gender_ambiguous) //someone fucked up a gender reassignment surgery
|
||||
if (gender == MALE)
|
||||
msg += "[t_He] has a strange feminine quality to [t_him].\n"
|
||||
else
|
||||
msg += "[t_He] has a strange masculine quality to [t_him].\n"
|
||||
|
||||
var/appears_dead = 0
|
||||
if(stat == DEAD || (status_flags & FAKEDEATH))
|
||||
appears_dead = 1
|
||||
if(getorgan(/obj/item/organ/brain))//Only perform these checks if there is no brain
|
||||
if(suiciding)
|
||||
msg += "<span class='warning'>[t_He] appears to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
msg += "<span class='warning'>[t_He] appear[p_s()] to have commited suicide... there is no hope of recovery.</span>\n"
|
||||
if(hellbound)
|
||||
msg += "<span class='warning'>[t_his] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
|
||||
msg += "<span class='warning'>[t_His] soul seems to have been ripped out of [t_his] body. Revival is impossible.</span>\n"
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] limp and unresponsive; there are no signs of life"
|
||||
if(!key)
|
||||
var/foundghost = 0
|
||||
@@ -203,12 +165,27 @@
|
||||
for(var/obj/item/I in BP.embedded_objects)
|
||||
msg += "<B>[t_He] [t_has] \a \icon[I] [I] embedded in [t_his] [BP.name]!</B>\n"
|
||||
|
||||
//stores missing limbs
|
||||
var/l_limbs_missing = 0
|
||||
var/r_limbs_missing = 0
|
||||
for(var/t in missing)
|
||||
if(t=="head")
|
||||
msg += "<span class='deadsay'><B>[capitalize(t_his)] [parse_zone(t)] is missing!</B><span class='warning'>\n"
|
||||
msg += "<span class='deadsay'><B>[t_His] [parse_zone(t)] is missing!</B><span class='warning'>\n"
|
||||
continue
|
||||
if(t == "l_arm" || t == "l_leg")
|
||||
l_limbs_missing++
|
||||
else if(t == "r_arm" || t == "r_leg")
|
||||
r_limbs_missing++
|
||||
|
||||
msg += "<B>[capitalize(t_his)] [parse_zone(t)] is missing!</B>\n"
|
||||
|
||||
if(l_limbs_missing >= 2 && r_limbs_missing == 0)
|
||||
msg += "[t_He] looks all right now.\n"
|
||||
else if(l_limbs_missing == 0 && r_limbs_missing >= 2)
|
||||
msg += "[t_He] really keeps to the left.\n"
|
||||
else if(l_limbs_missing >= 2 && r_limbs_missing >= 2)
|
||||
msg += "[t_He] doesn't seem all there.\n"
|
||||
|
||||
if(temp)
|
||||
if(temp < 30)
|
||||
msg += "[t_He] [t_has] minor bruising.\n"
|
||||
@@ -246,28 +223,13 @@
|
||||
msg += "[t_He] [t_is] plump and delicious looking - Like a fat little piggy. A tasty piggy.\n"
|
||||
else
|
||||
msg += "[t_He] [t_is] quite chubby.\n"
|
||||
/*
|
||||
if( (vore_womb_datum.has_people()||vore_stomach_datum.has_people()) && !(slot_w_uniform in obscured) )
|
||||
msg += "It seems [t_his] belly is shifting around slighty.\n"
|
||||
if( (vore_breast_datum.has_people()||vore_breast_datum.digestion_count) && !(slot_w_uniform in obscured) )
|
||||
msg += "It seems [t_his] breasts are heavy with milk.\n"
|
||||
if( !(slot_w_uniform in obscured) && (!w_uniform||!(w_uniform.body_parts_covered&GROIN)) )
|
||||
if(vore_cock_datum.has_people()||vore_cock_datum.digestion_count)
|
||||
msg += "It looks like [t_his] cock is full.\n"
|
||||
if(vore_balls_datum.has_people()||vore_balls_datum.digestion_count)
|
||||
msg += "It looks like [t_his] balls are full.\n"
|
||||
if(vore_tail_datum.has_people())
|
||||
msg += "[t_He] has a bulge in [t_his] tail."
|
||||
if(vore_tail_datum.transfer_factor)
|
||||
msg += " It moves slowly toward the base."
|
||||
msg += "\n"
|
||||
*/
|
||||
|
||||
if(blood_volume < BLOOD_VOLUME_SAFE)
|
||||
msg += "[t_He] [t_has] pale skin.\n"
|
||||
|
||||
if(bleedsuppress)
|
||||
msg += "[t_He] [t_is] bandaged with something.\n"
|
||||
if(bleed_rate)
|
||||
else if(bleed_rate)
|
||||
if(reagents.has_reagent("heparin"))
|
||||
msg += "<b>[t_He] [t_is] bleeding uncontrollably!</b>\n"
|
||||
else
|
||||
@@ -276,10 +238,12 @@
|
||||
if(reagents.has_reagent("teslium"))
|
||||
msg += "[t_He] is emitting a gentle blue glow!\n"
|
||||
|
||||
if(stun_absorption)
|
||||
msg += "[t_He] is radiating with a soft yellow light!\n" //Used by Vanguard
|
||||
if(islist(stun_absorption))
|
||||
for(var/i in stun_absorption)
|
||||
if(stun_absorption[i]["end_time"] > world.time && stun_absorption[i]["examine_message"])
|
||||
msg += "[t_He] [t_is][stun_absorption[i]["examine_message"]]\n"
|
||||
|
||||
if(drunkenness && !skipface && stat != DEAD) //Drunkenness
|
||||
if(drunkenness && !skipface && !appears_dead) //Drunkenness
|
||||
switch(drunkenness)
|
||||
if(11 to 21)
|
||||
msg += "[t_He] [t_is] slightly flushed.\n"
|
||||
@@ -292,7 +256,11 @@
|
||||
if(61.01 to 91)
|
||||
msg += "[t_He] looks like a drunken mess.\n"
|
||||
if(91.01 to INFINITY)
|
||||
msg += "[t_He] is a shitfaced, slobbering wreck.\n"
|
||||
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
|
||||
|
||||
for (var/I in src.vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
msg += B.get_examine_msg()
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
@@ -304,7 +272,13 @@
|
||||
|
||||
if(getorgan(/obj/item/organ/brain))
|
||||
if(istype(src,/mob/living/carbon/human/interactive))
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
|
||||
var/mob/living/carbon/human/interactive/auto = src
|
||||
if(auto.showexaminetext)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be some sort of sick automaton, [t_his] eyes are glazed over and [t_his] mouth is slightly agape.</span>\n"
|
||||
if(auto.debugexamine)
|
||||
var/dodebug = auto.doing2string(auto.doing)
|
||||
var/interestdebug = auto.interest2string(auto.interest)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] appears to be [interestdebug] and [dodebug].</span>\n"
|
||||
else if(!key)
|
||||
msg += "<span class='deadsay'>[t_He] [t_is] totally catatonic. The stresses of life in deep-space must have been too much for [t_him]. Any recovery is unlikely.</span>\n"
|
||||
else if(!client)
|
||||
@@ -313,7 +287,7 @@
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
|
||||
|
||||
if(istype(user, /mob/living/carbon/human))
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud)
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || CIH)
|
||||
@@ -325,18 +299,18 @@
|
||||
msg += "<a href='?src=\ref[src];hud=1;photo_front=1'>\[Front photo\]</a> "
|
||||
msg += "<a href='?src=\ref[src];hud=1;photo_side=1'>\[Side photo\]</a><br>"
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(CIH,/obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
var/implant_detect
|
||||
var/cyberimp_detect
|
||||
for(var/obj/item/organ/cyberimp/CI in internal_organs)
|
||||
if(CI.status == ORGAN_ROBOTIC)
|
||||
implant_detect += "[name] is modified with a [CI.name].<br>"
|
||||
if(implant_detect)
|
||||
cyberimp_detect += "[name] is modified with a [CI.name].<br>"
|
||||
if(cyberimp_detect)
|
||||
msg += "Detected cybernetic modifications:<br>"
|
||||
msg += implant_detect
|
||||
msg += cyberimp_detect
|
||||
if(R)
|
||||
var/health = R.fields["p_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health]\]</a>"
|
||||
health = R.fields["m_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health]\]</a><br>"
|
||||
var/health_r = R.fields["p_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;p_stat=1'>\[[health_r]\]</a>"
|
||||
health_r = R.fields["m_stat"]
|
||||
msg += "<a href='?src=\ref[src];hud=m;m_stat=1'>\[[health_r]\]</a><br>"
|
||||
R = find_record("name", perpname, data_core.medical)
|
||||
if(R)
|
||||
msg += "<a href='?src=\ref[src];hud=m;evaluation=1'>\[Medical evaluation\]</a><br>"
|
||||
@@ -357,6 +331,7 @@
|
||||
msg += "<a href='?src=\ref[src];hud=s;view_comment=1'>\[View comment log\]</a> "
|
||||
msg += "<a href='?src=\ref[src];hud=s;add_comment=1'>\[Add comment\]</a>\n"
|
||||
|
||||
|
||||
if(print_flavor_text() && get_visible_name() != "Unknown")//Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
|
||||
msg += "[print_flavor_text()]\n"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
real_name = "Unknown"
|
||||
voice_name = "Unknown"
|
||||
icon = 'icons/mob/human.dmi'
|
||||
icon_state = "caucasian1_m_s"
|
||||
icon_state = "caucasian_m"
|
||||
|
||||
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
//initialize limbs first
|
||||
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.owner = src
|
||||
create_bodyparts()
|
||||
|
||||
//initialize dna. for spawned humans; overwritten by other code
|
||||
create_dna(src)
|
||||
@@ -33,21 +29,7 @@
|
||||
set_species(dna.species.type)
|
||||
|
||||
//initialise organs
|
||||
if(!(NOHUNGER in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
|
||||
if(!(NOBREATH in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
|
||||
if(!(NOBLOOD in dna.species.specflags))
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
|
||||
//Note: Additional organs are generated/replaced on the dna.species level
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
create_internal_organs()
|
||||
|
||||
martial_art = default_martial_art
|
||||
|
||||
@@ -55,6 +37,19 @@
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/create_internal_organs()
|
||||
if(!(NOHUNGER in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
if(!(NOBREATH in dna.species.species_traits))
|
||||
if(dna.species.mutantlungs)
|
||||
internal_organs += new dna.species.mutantlungs()
|
||||
else
|
||||
internal_organs += new /obj/item/organ/lungs()
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/OpenCraftingMenu()
|
||||
handcrafting.ui_interact(src)
|
||||
|
||||
@@ -81,6 +76,11 @@
|
||||
stat("Internal Atmosphere Info", internal.name)
|
||||
stat("Tank Pressure", internal.air_contents.return_pressure())
|
||||
stat("Distribution Pressure", internal.distribute_pressure)
|
||||
|
||||
var/mob/living/simple_animal/borer/B = has_brain_worms()
|
||||
if(B && B.controlling)
|
||||
stat("Chemicals", B.chemicals)
|
||||
|
||||
if(mind)
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
@@ -116,94 +116,17 @@
|
||||
stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]")
|
||||
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity, ex_target)
|
||||
var/b_loss = null
|
||||
var/f_loss = null
|
||||
var/bomb_armor = getarmor(null, "bomb")
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
b_loss += 500
|
||||
if (prob(bomb_armor))
|
||||
shred_clothing(1,150)
|
||||
var/atom/target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(target, 200, 4)
|
||||
else
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
b_loss += 60
|
||||
|
||||
f_loss += 60
|
||||
if (prob(bomb_armor))
|
||||
b_loss = b_loss/1.5
|
||||
f_loss = f_loss/1.5
|
||||
shred_clothing(1,25)
|
||||
else
|
||||
shred_clothing(1,50)
|
||||
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(30, 120)
|
||||
if (prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
b_loss += 30
|
||||
if (prob(bomb_armor))
|
||||
b_loss = b_loss/2
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(10)
|
||||
|
||||
take_overall_damage(b_loss,f_loss)
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2 || !bomb_armor)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/blob_act(obj/effect/blob/B)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
show_message("<span class='userdanger'>The blob attacks you!</span>")
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/bullet_act()
|
||||
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(!prob(martial_art.deflection_chance))
|
||||
return ..()
|
||||
if(!src.lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
src.visible_message("<span class='danger'>[src] deflects the projectile; they can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
|
||||
return 0
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/attack_ui(slot)
|
||||
if(!get_bodypart(hand ? "l_arm" : "r_arm"))
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/show_inv(mob/user)
|
||||
user.set_machine(src)
|
||||
var/has_breathable_mask = istype(wear_mask, /obj/item/clothing/mask)
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/list/dat = list()
|
||||
|
||||
var/dat = {"<table>
|
||||
<tr><td><B>Left Hand:</B></td><td><A href='?src=\ref[src];item=[slot_l_hand]'>[(l_hand && !(l_hand.flags&ABSTRACT)) ? l_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td><B>Right Hand:</B></td><td><A href='?src=\ref[src];item=[slot_r_hand]'>[(r_hand && !(r_hand.flags&ABSTRACT)) ? r_hand : "<font color=grey>Empty</font>"]</A></td></tr>
|
||||
<tr><td> </td></tr>"}
|
||||
dat += "<table>"
|
||||
for(var/i in 1 to held_items.len)
|
||||
var/obj/item/I = get_item_for_held_index(i)
|
||||
dat += "<tr><td><B>[get_held_index_name(i)]:</B></td><td><A href='?src=\ref[src];item=[slot_hands];hand_index=[i]'>[(I && !(I.flags & ABSTRACT)) ? I : "<font color=grey>Empty</font>"]</a></td></tr>"
|
||||
dat += "<tr><td> </td></tr>"
|
||||
|
||||
dat += "<tr><td><B>Back:</B></td><td><A href='?src=\ref[src];item=[slot_back]'>[(back && !(back.flags&ABSTRACT)) ? back : "<font color=grey>Empty</font>"]</A>"
|
||||
if(has_breathable_mask && istype(back, /obj/item/weapon/tank))
|
||||
@@ -218,6 +141,11 @@
|
||||
else
|
||||
dat += "<tr><td><B>Mask:</B></td><td><A href='?src=\ref[src];item=[slot_wear_mask]'>[(wear_mask && !(wear_mask.flags&ABSTRACT)) ? wear_mask : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_neck in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Neck:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
dat += "<tr><td><B>Neck:</B></td><td><A href='?src=\ref[src];item=[slot_neck]'>[(wear_neck && !(wear_neck.flags&ABSTRACT)) ? wear_neck : "<font color=grey>Empty</font>"]</A></td></tr>"
|
||||
|
||||
if(slot_glasses in obscured)
|
||||
dat += "<tr><td><font color=grey><B>Eyes:</B></font></td><td><font color=grey>Obscured</font></td></tr>"
|
||||
else
|
||||
@@ -277,7 +205,7 @@
|
||||
"}
|
||||
|
||||
var/datum/browser/popup = new(user, "mob\ref[src]", "[src]", 440, 510)
|
||||
popup.set_content(dat)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
// called when something steps onto a human
|
||||
@@ -289,35 +217,6 @@
|
||||
|
||||
spreadFire(AM)
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0)
|
||||
if(tesla_shock)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(G.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.5
|
||||
if(wear_suit)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
if(S.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.95
|
||||
siemens_coeff = total_coeff
|
||||
else if(!safety)
|
||||
var/gloves_siemens_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
gloves_siemens_coeff = G.siemens_coefficient
|
||||
siemens_coeff = gloves_siemens_coeff
|
||||
if(heart_attack)
|
||||
if(shock_damage * siemens_coeff >= 1 && prob(25))
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/Topic(href, href_list)
|
||||
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
|
||||
@@ -333,8 +232,8 @@
|
||||
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
|
||||
return
|
||||
L.embedded_objects -= I
|
||||
L.take_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
|
||||
I.loc = get_turf(src)
|
||||
L.receive_damage(I.embedded_unsafe_removal_pain_multiplier*I.w_class)//It hurts to rip it out, get surgery you dingus.
|
||||
I.forceMove(get_turf(src))
|
||||
usr.put_in_hands(I)
|
||||
usr.emote("scream")
|
||||
usr.visible_message("[usr] successfully rips [I] out of their [L.name]!","<span class='notice'>You successfully remove [I] from your [L.name].</span>")
|
||||
@@ -352,14 +251,14 @@
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
|
||||
var/obj/item/pocket_item = (pocket_id == slot_r_store ? r_store : l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
var/obj/item/place_item = usr.get_active_held_item() // Item to place in the pocket, if it's empty
|
||||
|
||||
var/delay_denominator = 1
|
||||
if(pocket_item && !(pocket_item.flags&ABSTRACT))
|
||||
if(pocket_item.flags & NODROP)
|
||||
usr << "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>"
|
||||
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.flags&ABSTRACT))
|
||||
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
|
||||
delay_denominator = 4
|
||||
else
|
||||
@@ -368,11 +267,13 @@
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster
|
||||
if(pocket_item)
|
||||
if(pocket_item == (pocket_id == slot_r_store ? r_store : l_store)) //item still in the pocket we search
|
||||
unEquip(pocket_item)
|
||||
dropItemToGround(pocket_item)
|
||||
else
|
||||
if(place_item)
|
||||
usr.unEquip(place_item)
|
||||
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
|
||||
if(place_item.mob_can_equip(src, usr, pocket_id, FALSE, TRUE))
|
||||
usr.temporarilyRemoveItemFromInventory(place_item, TRUE)
|
||||
equip_to_slot(place_item, pocket_id, TRUE)
|
||||
//do nothing otherwise
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
@@ -381,23 +282,21 @@
|
||||
// Display a warning if the user mocks up
|
||||
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
|
||||
|
||||
..()
|
||||
else
|
||||
..()
|
||||
..()
|
||||
|
||||
|
||||
///////HUDs///////
|
||||
if(href_list["hud"])
|
||||
if(istype(usr, /mob/living/carbon/human))
|
||||
if(ishuman(usr))
|
||||
var/mob/living/carbon/human/H = usr
|
||||
var/perpname = get_face_name(get_id_name(""))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud))
|
||||
var/datum/data/record/R = find_record("name", perpname, data_core.general)
|
||||
if(href_list["photo_front"] || href_list["photo_side"])
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
return
|
||||
var/obj/item/weapon/photo/P = null
|
||||
if(href_list["photo_front"])
|
||||
@@ -408,26 +307,26 @@
|
||||
P.show(H)
|
||||
|
||||
if(href_list["hud"] == "m")
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/health) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
if(href_list["p_stat"])
|
||||
var/health = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
|
||||
var/health_status = input(usr, "Specify a new physical status for this person.", "Medical HUD", R.fields["p_stat"]) in list("Active", "Physically Unfit", "*Unconscious*", "*Deceased*", "Cancel")
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
return
|
||||
if(health && health != "Cancel")
|
||||
R.fields["p_stat"] = health
|
||||
if(health_status && health_status != "Cancel")
|
||||
R.fields["p_stat"] = health_status
|
||||
return
|
||||
if(href_list["m_stat"])
|
||||
var/health = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
|
||||
var/health_status = input(usr, "Specify a new mental status for this person.", "Medical HUD", R.fields["m_stat"]) in list("Stable", "*Watch*", "*Unstable*", "*Insane*", "Cancel")
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/health) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/medical))
|
||||
return
|
||||
if(health && health != "Cancel")
|
||||
R.fields["m_stat"] = health
|
||||
if(health_status && health_status != "Cancel")
|
||||
R.fields["m_stat"] = health_status
|
||||
return
|
||||
if(href_list["evaluation"])
|
||||
if(!getBruteLoss() && !getFireLoss() && !getOxyLoss() && getToxLoss() < 20)
|
||||
@@ -473,7 +372,7 @@
|
||||
usr << "<span class='danger'>Gathered data is inconsistent with the analysis, possible cause: poisoning.</span>"
|
||||
|
||||
if(href_list["hud"] == "s")
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
if(usr.stat || usr == src) //|| !usr.canmove || usr.restrained()) Fluff: Sechuds have eye-tracking technology and sets 'arrest' to people that the wearer looks and blinks at.
|
||||
return //Non-fluff: This allows sec to set people to arrest as they get disarmed or beaten
|
||||
// Checks the user has security clearence before allowing them to change arrest status via hud, comment out to enable all access
|
||||
@@ -500,7 +399,7 @@
|
||||
if(setcriminal != "Cancel")
|
||||
if(R)
|
||||
if(H.canUseHUD())
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
if(istype(H.glasses, /obj/item/clothing/glasses/hud/security) || istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
investigate_log("[src.key] has been set from [R.fields["criminal"]] to [setcriminal] by [usr.name] ([usr.key]).", "records")
|
||||
R.fields["criminal"] = setcriminal
|
||||
sec_hud_set_security_status()
|
||||
@@ -510,7 +409,7 @@
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
usr << "<b>Name:</b> [R.fields["name"]] <b>Criminal Status:</b> [R.fields["criminal"]]"
|
||||
usr << "<b>Minor Crimes:</b>"
|
||||
@@ -539,7 +438,7 @@
|
||||
return
|
||||
else if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
data_core.addMinorCrime(R.fields["id"], crime)
|
||||
@@ -554,7 +453,7 @@
|
||||
return
|
||||
else if (!H.canUseHUD())
|
||||
return
|
||||
else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
var/crime = data_core.createCrimeEntry(t1, t2, allowed_access, worldtime2text())
|
||||
data_core.addMajorCrime(R.fields["id"], crime)
|
||||
@@ -565,7 +464,7 @@
|
||||
if(R)
|
||||
if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
usr << "<b>Comments/Log:</b>"
|
||||
var/counter = 1
|
||||
@@ -583,12 +482,12 @@
|
||||
return
|
||||
else if(!H.canUseHUD())
|
||||
return
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security))
|
||||
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot("eye_hud"), /obj/item/organ/cyberimp/eyes/hud/security))
|
||||
return
|
||||
var/counter = 1
|
||||
while(R.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1,)
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, worldtime2text(), time2text(world.realtime, "MMM DD"), year_integer+540, t1)
|
||||
usr << "<span class='notice'>Successfully added comment.</span>"
|
||||
return
|
||||
usr << "<span class='warning'>Unable to locate a data core entry for this person.</span>"
|
||||
@@ -600,7 +499,7 @@
|
||||
. = 1 // Default to returning true.
|
||||
if(user && !target_zone)
|
||||
target_zone = user.zone_selected
|
||||
if(dna && (PIERCEIMMUNE in dna.species.specflags))
|
||||
if(dna && (PIERCEIMMUNE in dna.species.species_traits))
|
||||
. = 0
|
||||
// If targeting the head, see if the head item is thin enough.
|
||||
// If targeting anything else, see if the wear suit is thin enough.
|
||||
@@ -612,7 +511,7 @@
|
||||
. = 0
|
||||
if(!. && error_msg && user)
|
||||
// Might need re-wording.
|
||||
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on their head" : "on their body"].</span>"
|
||||
user << "<span class='alert'>There is no exposed flesh or thin material [above_neck(target_zone) ? "on [p_their()] head" : "on [p_their()] body"].</span>"
|
||||
|
||||
/mob/living/carbon/human/proc/check_obscured_slots()
|
||||
var/list/obscured = list()
|
||||
@@ -637,7 +536,7 @@
|
||||
if(wear_mask.flags_inv & HIDEEYES)
|
||||
obscured |= slot_glasses
|
||||
|
||||
if(obscured.len > 0)
|
||||
if(obscured.len)
|
||||
return obscured
|
||||
else
|
||||
return null
|
||||
@@ -653,7 +552,7 @@
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/redtag))
|
||||
threatcount += 4
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 2
|
||||
@@ -661,7 +560,7 @@
|
||||
if(lasercolor == "r")
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/bluetag))
|
||||
threatcount += 4
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
if(istype(belt, /obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 2
|
||||
@@ -676,10 +575,9 @@
|
||||
//Check for weapons
|
||||
if(judgebot.weaponscheck)
|
||||
if(!idcard || !(access_weapons in idcard.access))
|
||||
if(judgebot.check_for_weapons(l_hand))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(r_hand))
|
||||
threatcount += 4
|
||||
for(var/obj/item/I in held_items)
|
||||
if(judgebot.check_for_weapons(I))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(belt))
|
||||
threatcount += 2
|
||||
|
||||
@@ -697,23 +595,22 @@
|
||||
threatcount += 2
|
||||
|
||||
//Check for dresscode violations
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/syndi) || istype(head, /obj/item/clothing/head/helmet/space/syndicate) || istype(head, /obj/item/clothing/head/culthood))
|
||||
threatcount += 5
|
||||
if(istype(head, /obj/item/clothing/head/wizard) || istype(head, /obj/item/clothing/head/helmet/space/hardsuit/wizard))
|
||||
threatcount += 2
|
||||
|
||||
//Check for nonhuman scum
|
||||
if(dna && dna.species.id && dna.species.id != "human")
|
||||
threatcount += 0
|
||||
threatcount += 1
|
||||
|
||||
//Loyalty implants imply trustworthyness
|
||||
if(isloyal(src))
|
||||
//mindshield implants imply trustworthyness
|
||||
if(isloyal())
|
||||
threatcount -= 1
|
||||
|
||||
//Agent cards lower threatlevel, but only just enough to avoid dresscode violations.
|
||||
//Agent cards lower threatlevel.
|
||||
if(istype(idcard, /obj/item/weapon/card/id/syndicate))
|
||||
threatcount -= 2
|
||||
threatcount -= 5
|
||||
|
||||
return threatcount
|
||||
return threatcount
|
||||
|
||||
|
||||
//Used for new human mobs created by cloning/goleming/podding
|
||||
@@ -727,22 +624,10 @@
|
||||
update_body()
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/singularity_act()
|
||||
var/gain = 20
|
||||
if(mind)
|
||||
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
|
||||
gain = 100
|
||||
if(mind.assigned_role == "Clown")
|
||||
gain = rand(-300, 300)
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/carbon/human/singularity_pull(S, current_size)
|
||||
if(current_size >= STAGE_THREE)
|
||||
var/list/handlist = list(l_hand, r_hand)
|
||||
for(var/obj/item/hand in handlist)
|
||||
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && unEquip(hand))
|
||||
for(var/obj/item/hand in held_items)
|
||||
if(prob(current_size * 5) && hand.w_class >= ((11-current_size)/2) && dropItemToGround(hand))
|
||||
step_towards(hand, src)
|
||||
src << "<span class='warning'>\The [S] pulls \the [hand] from your grip!</span>"
|
||||
rad_act(current_size * 3)
|
||||
@@ -750,71 +635,6 @@
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(health >= 0)
|
||||
if(src == M)
|
||||
visible_message( \
|
||||
"[src] examines \himself.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/LB = X
|
||||
missing -= LB.body_zone
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
if(hallucination)
|
||||
if(prob(30))
|
||||
brutedamage += rand(30,40)
|
||||
if(prob(30))
|
||||
burndamage += rand(30,40)
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
|
||||
|
||||
for(var/t in missing)
|
||||
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
|
||||
|
||||
if(bleed_rate)
|
||||
src << "<span class='danger'>You are bleeding!</span>"
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
src << "<span class='info'>You're completely exhausted.</span>"
|
||||
else
|
||||
src << "<span class='info'>You feel fatigued.</span>"
|
||||
else
|
||||
if(wear_suit)
|
||||
wear_suit.add_fingerprint(M)
|
||||
else if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
|
||||
CHECK_DNA_AND_SPECIES(C)
|
||||
|
||||
@@ -825,7 +645,7 @@
|
||||
src << "<span class='warning'>Remove your mask first!</span>"
|
||||
return 0
|
||||
if(C.is_mouth_covered())
|
||||
src << "<span class='warning'>Remove their mask first!</span>"
|
||||
src << "<span class='warning'>Remove [p_their()] mask first!</span>"
|
||||
return 0
|
||||
|
||||
if(C.cpr_time < world.time + 30)
|
||||
@@ -835,10 +655,10 @@
|
||||
src << "<span class='warning'>You fail to perform CPR on [C]!</span>"
|
||||
return 0
|
||||
|
||||
var/they_breathe = (!(NOBREATH in C.dna.species.specflags))
|
||||
var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
|
||||
var/they_lung = C.getorganslot("lungs")
|
||||
|
||||
if(C.health > config.health_threshold_crit)
|
||||
if(C.health > HEALTH_THRESHOLD_CRIT)
|
||||
return
|
||||
|
||||
src.visible_message("[src] performs CPR on [C.name]!", "<span class='notice'>You perform CPR on [C.name].</span>")
|
||||
@@ -878,10 +698,10 @@
|
||||
if(dna && dna.check_mutation(HULK))
|
||||
say(pick(";RAAAAAAAARGH!", ";HNNNNNNNNNGGGGGGH!", ";GWAAAAAAAARRRHHH!", "NNNNNNNNGGGGGGGGHH!", ";AAAAAAARRRGH!" ))
|
||||
if(..(I, cuff_break = FAST_CUFFBREAK))
|
||||
unEquip(I)
|
||||
dropItemToGround(I)
|
||||
else
|
||||
if(..())
|
||||
unEquip(I)
|
||||
dropItemToGround(I)
|
||||
|
||||
/mob/living/carbon/human/clean_blood()
|
||||
var/mob/living/carbon/human/H = src
|
||||
@@ -907,17 +727,18 @@
|
||||
/mob/living/carbon/human/proc/electrocution_animation(anim_duration)
|
||||
//Handle mutant parts if possible
|
||||
if(dna && dna.species)
|
||||
add_overlay("electrocuted_base")
|
||||
spawn(anim_duration)
|
||||
if(src)
|
||||
overlays -= "electrocuted_base"
|
||||
add_atom_colour("#000000", TEMPORARY_COLOUR_PRIORITY)
|
||||
var/static/image/electrocution_skeleton_anim = image(icon = icon, icon_state = "electrocuted_base")
|
||||
electrocution_skeleton_anim.appearance_flags = RESET_COLOR
|
||||
add_overlay(electrocution_skeleton_anim)
|
||||
addtimer(CALLBACK(src, .proc/end_electrocution_animation, electrocution_skeleton_anim), anim_duration)
|
||||
|
||||
else //or just do a generic animation
|
||||
var/list/viewing = list()
|
||||
for(var/mob/M in viewers(src))
|
||||
if(M.client)
|
||||
viewing += M.client
|
||||
flick_overlay(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), viewing, anim_duration)
|
||||
flick_overlay_view(image(icon,src,"electrocuted_generic",ABOVE_MOB_LAYER), src, anim_duration)
|
||||
|
||||
/mob/living/carbon/human/proc/end_electrocution_animation(image/I)
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
|
||||
overlays -= I
|
||||
|
||||
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close = 0)
|
||||
if(incapacitated() || lying )
|
||||
@@ -1004,32 +825,9 @@
|
||||
hud_used.healthdoll.icon_state = "healthdoll_DEAD"
|
||||
|
||||
/mob/living/carbon/human/fully_heal(admin_revive = 0)
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
|
||||
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
|
||||
var/obj/item/organ/lungs/L = new()
|
||||
L.Insert(src)
|
||||
|
||||
if(!(NOBLOOD in dna.species.specflags) && !getorganslot("heart"))
|
||||
var/obj/item/organ/heart/H = new()
|
||||
H.Insert(src)
|
||||
|
||||
if(!getorganslot("tongue"))
|
||||
var/obj/item/organ/tongue/T
|
||||
|
||||
for(var/tongue_type in dna.species.mutant_organs)
|
||||
if(ispath(tongue_type, /obj/item/organ/tongue))
|
||||
T = new tongue_type()
|
||||
T.Insert(src)
|
||||
|
||||
// if they have no mutant tongues, give them a regular one
|
||||
if(!T)
|
||||
T = new()
|
||||
T.Insert(src)
|
||||
|
||||
regenerate_organs()
|
||||
remove_all_embedded_objects()
|
||||
drunkenness = 0
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
@@ -1063,12 +861,7 @@
|
||||
O = new /datum/objective/sintouched/pride
|
||||
ticker.mode.sintouched += src.mind
|
||||
src.mind.objectives += O
|
||||
var/obj_count = 1
|
||||
src << "<span class='notice'>Your current objectives:</span>"
|
||||
for(O in src.mind.objectives)
|
||||
var/datum/objective/objective = O
|
||||
src << "<B>Objective #[obj_count]</B>: [objective.explanation_text]"
|
||||
obj_count++
|
||||
src.mind.announce_objectives()
|
||||
|
||||
/mob/living/carbon/human/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
. = ..()
|
||||
@@ -1078,6 +871,36 @@
|
||||
/mob/living/carbon/human/is_literate()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/can_hold_items()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/update_gravity(has_gravity,override = 0)
|
||||
override = dna.species.override_float
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
|
||||
if(blood && (NOBLOOD in dna.species.species_traits))
|
||||
if(message)
|
||||
visible_message("<span class='warning'>[src] dry heaves!</span>", \
|
||||
"<span class='userdanger'>You try to throw up, but there's nothing in your stomach!</span>")
|
||||
if(stun)
|
||||
Weaken(10)
|
||||
return 1
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Bump(atom/A)
|
||||
..()
|
||||
var/crashdir = get_dir(src, A)
|
||||
var/obj/item/device/flightpack/FP = get_flightpack()
|
||||
if(FP)
|
||||
FP.flight_impact(A, crashdir)
|
||||
|
||||
/mob/living/carbon/human/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make monkey"] = "?_src_=vars;makemonkey=\ref[src]"
|
||||
.["Set Species"] = "?_src_=vars;setspecies=\ref[src]"
|
||||
.["Make cyborg"] = "?_src_=vars;makerobot=\ref[src]"
|
||||
.["Make alien"] = "?_src_=vars;makealien=\ref[src]"
|
||||
.["Make slime"] = "?_src_=vars;makeslime=\ref[src]"
|
||||
.["Toggle Purrbation"] = "?_src_=vars;purrbation=\ref[src]"
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(check_shields(0, M.name))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
if(M.a_intent == "harm")
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee","","",10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
if (prob(30))
|
||||
visible_message("<span class='danger'>[M] has wounded [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [src]!</span>")
|
||||
apply_effect(4, WEAKEN, armor_block)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
|
||||
if(M.a_intent == "disarm")
|
||||
var/randn = rand(1, 100)
|
||||
if (randn <= 80)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
else
|
||||
if (randn <= 99)
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
drop_item()
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has tried to disarm [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tried to disarm [src]!</span>")
|
||||
return
|
||||
@@ -1,14 +0,0 @@
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user)
|
||||
if(user.a_intent == "harm")
|
||||
..(user, 1)
|
||||
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
visible_message("<span class='danger'>[user] has [hulk_verb]ed [src]!</span>", \
|
||||
"<span class='userdanger'>[user] has [hulk_verb]ed [src]!</span>")
|
||||
adjustBruteLoss(15)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //to allow surgery to return properly.
|
||||
return
|
||||
dna.species.spec_attack_hand(M, src)
|
||||
@@ -1,15 +0,0 @@
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
|
||||
if(M.a_intent == "help")
|
||||
..() //shaking
|
||||
return 0
|
||||
|
||||
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
updatehealth()
|
||||
return 1
|
||||
@@ -1,161 +0,0 @@
|
||||
//Updates the mob's health from bodyparts and mob damage variables
|
||||
/mob/living/carbon/human/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
return
|
||||
var/total_burn = 0
|
||||
var/total_brute = 0
|
||||
for(var/X in bodyparts) //hardcoded to streamline things a bit
|
||||
var/obj/item/bodypart/BP = X
|
||||
total_brute += BP.brute_dam
|
||||
total_burn += BP.burn_dam
|
||||
health = maxHealth - getOxyLoss() - getToxLoss() - getCloneLoss() - total_burn - total_brute
|
||||
update_stat()
|
||||
if(((maxHealth - total_burn) < config.health_threshold_dead) && stat == DEAD )
|
||||
ChangeToHusk()
|
||||
if(on_fire)
|
||||
shred_clothing()
|
||||
med_hud_set_health()
|
||||
med_hud_set_status()
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/human/getBruteLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.brute_dam
|
||||
return amount
|
||||
|
||||
/mob/living/carbon/human/getFireLoss()
|
||||
var/amount = 0
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
amount += BP.burn_dam
|
||||
return amount
|
||||
|
||||
|
||||
/mob/living/carbon/human/adjustBruteLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(amount, 0)
|
||||
else
|
||||
heal_overall_damage(-amount, 0)
|
||||
|
||||
/mob/living/carbon/human/adjustFireLoss(amount)
|
||||
if(status_flags & GODMODE)
|
||||
return 0
|
||||
if(amount > 0)
|
||||
take_overall_damage(0, amount)
|
||||
else
|
||||
heal_overall_damage(0, -amount)
|
||||
|
||||
/mob/living/carbon/human/proc/hat_fall_prob()
|
||||
var/multiplier = 1
|
||||
var/obj/item/clothing/head/H = head
|
||||
var/loose = 40
|
||||
if(stat || (status_flags & FAKEDEATH))
|
||||
multiplier = 2
|
||||
if(H.flags_cover & (HEADCOVERSEYES | HEADCOVERSMOUTH) || H.flags_inv & (HIDEEYES | HIDEFACE))
|
||||
loose = 0
|
||||
return loose * multiplier
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
/mob/living/carbon/human/proc/get_damaged_bodyparts(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if((brute && BP.brute_dam) || (burn && BP.burn_dam))
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Returns a list of damageable bodyparts
|
||||
/mob/living/carbon/human/proc/get_damageable_bodyparts()
|
||||
var/list/obj/item/bodypart/parts = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brute_dam + BP.burn_dam < BP.max_damage)
|
||||
parts += BP
|
||||
return parts
|
||||
|
||||
//Heals ONE external organ, organ gets randomly selected from damaged ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/heal_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.heal_damage(brute,burn,0))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
//Damages ONE external organ, organ gets randomly selected from damagable ones.
|
||||
//It automatically updates damage overlays if necesary
|
||||
//It automatically updates health status
|
||||
/mob/living/carbon/human/take_organ_damage(brute, burn)
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
if(!parts.len)
|
||||
return
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
if(picked.take_damage(brute,burn))
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
|
||||
//Heal MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/heal_overall_damage(brute, burn, updating_health=1)
|
||||
var/list/obj/item/bodypart/parts = get_damaged_bodyparts(brute,burn)
|
||||
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
update |= picked.heal_damage(brute,burn,0)
|
||||
|
||||
brute -= (brute_was-picked.brute_dam)
|
||||
burn -= (burn_was-picked.burn_dam)
|
||||
|
||||
parts -= picked
|
||||
if(updating_health)
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
// damage MANY bodyparts, in random order
|
||||
/mob/living/carbon/human/take_overall_damage(brute, burn)
|
||||
if(status_flags & GODMODE)
|
||||
return //godmode
|
||||
|
||||
var/list/obj/item/bodypart/parts = get_damageable_bodyparts()
|
||||
var/update = 0
|
||||
while(parts.len && (brute>0 || burn>0) )
|
||||
var/obj/item/bodypart/picked = pick(parts)
|
||||
var/brute_per_part = brute/parts.len
|
||||
var/burn_per_part = burn/parts.len
|
||||
|
||||
var/brute_was = picked.brute_dam
|
||||
var/burn_was = picked.burn_dam
|
||||
|
||||
|
||||
update |= picked.take_damage(brute_per_part,burn_per_part)
|
||||
|
||||
brute -= (picked.brute_dam - brute_was)
|
||||
burn -= (picked.burn_dam - burn_was)
|
||||
|
||||
parts -= picked
|
||||
updatehealth()
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = 0)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
@@ -17,8 +17,8 @@
|
||||
return (armorval/max(organnum, 1))
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, type)
|
||||
if(!type)
|
||||
/mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type)
|
||||
if(!d_type)
|
||||
return 0
|
||||
var/protection = 0
|
||||
var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor)
|
||||
@@ -28,13 +28,44 @@
|
||||
if(bp && istype(bp ,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = bp
|
||||
if(C.body_parts_covered & def_zone.body_part)
|
||||
protection += C.armor[type]
|
||||
protection += C.armor[d_type]
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/human/on_hit(proj_type)
|
||||
dna.species.on_hit(proj_type, src)
|
||||
///checkeyeprot()
|
||||
///Returns a number between -1 to 2
|
||||
/mob/living/carbon/human/get_eye_protection()
|
||||
var/number = ..()
|
||||
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
|
||||
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
|
||||
number += HFP.flash_protect
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/human/get_ear_protection()
|
||||
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/on_hit(obj/item/projectile/P)
|
||||
dna.species.on_hit(P, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/bullet_act(obj/item/projectile/P, def_zone)
|
||||
var/spec_return = dna.species.bullet_act(P, src)
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
|
||||
if(martial_art && martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(prob(martial_art.deflection_chance))
|
||||
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
playsound(src, pick("sound/weapons/bulletflyby.ogg","sound/weapons/bulletflyby2.ogg","sound/weapons/bulletflyby3.ogg"), 75, 1)
|
||||
return 0
|
||||
|
||||
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
|
||||
if(istype(P, /obj/item/projectile/energy) || istype(P, /obj/item/projectile/beam))
|
||||
if(check_reflect(def_zone)) // Checks if you've passed a reflection% check
|
||||
@@ -60,31 +91,26 @@
|
||||
if(check_shields(P.damage, "the [P.name]", P, PROJECTILE_ATTACK, P.armour_penetration))
|
||||
P.on_hit(src, 100, def_zone)
|
||||
return 2
|
||||
|
||||
return (..(P , def_zone))
|
||||
|
||||
/mob/living/carbon/human/proc/check_reflect(def_zone) //Reflection checks for anything in your l_hand, r_hand, or wear_suit based on the reflection chance of the object
|
||||
if(wear_suit)
|
||||
if(wear_suit.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
if(l_hand)
|
||||
if(l_hand.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
if(r_hand)
|
||||
if(r_hand.IsReflect(def_zone) == 1)
|
||||
for(var/obj/item/I in held_items)
|
||||
if(I.IsReflect(def_zone) == 1)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/proc/check_shields(damage = 0, attack_text = "the attack", atom/movable/AM, attack_type = MELEE_ATTACK, armour_penetration = 0)
|
||||
var/block_chance_modifier = round(damage / -3)
|
||||
|
||||
if(l_hand && !istype(l_hand, /obj/item/clothing))
|
||||
var/final_block_chance = l_hand.block_chance - (Clamp((armour_penetration-l_hand.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
if(l_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
return 1
|
||||
if(r_hand && !istype(r_hand, /obj/item/clothing))
|
||||
var/final_block_chance = r_hand.block_chance - (Clamp((armour_penetration-r_hand.armour_penetration)/2,0,100)) + block_chance_modifier //Need to reset the var so it doesn't carry over modifications between attempts
|
||||
if(r_hand.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
return 1
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!istype(I, /obj/item/clothing))
|
||||
var/final_block_chance = I.block_chance - (Clamp((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
if(I.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
return 1
|
||||
if(wear_suit)
|
||||
var/final_block_chance = wear_suit.block_chance - (Clamp((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
|
||||
if(wear_suit.hit_reaction(src, attack_text, final_block_chance, damage, attack_type))
|
||||
@@ -95,252 +121,17 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected))
|
||||
var/target_area = parse_zone(check_zone(user.zone_selected))
|
||||
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
|
||||
feedback_add_details("zone_targeted","[target_area]")
|
||||
|
||||
// the attacked_by code varies among species
|
||||
return dna.species.spec_attacked_by(I, user, affecting, a_intent, target_area, src)
|
||||
|
||||
/mob/living/carbon/human/emp_act(severity)
|
||||
var/informed = 0
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
if(L.status == ORGAN_ROBOTIC)
|
||||
if(!informed)
|
||||
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
|
||||
informed = 1
|
||||
switch(severity)
|
||||
if(1)
|
||||
L.take_damage(0,10)
|
||||
src.Stun(10)
|
||||
if(2)
|
||||
L.take_damage(0,5)
|
||||
src.Stun(5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/acid_act(acidpwr, toxpwr, acid_volume)
|
||||
var/list/damaged = list()
|
||||
var/list/inventory_items_to_kill = list()
|
||||
var/acidity = min(acidpwr*acid_volume/200, toxpwr)
|
||||
var/acid_volume_left = acid_volume
|
||||
var/acid_decay = 100/acidpwr // how much volume we lose per item we try to melt. 5 for fluoro, 10 for sulphuric
|
||||
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
if(!head_clothes.unacidable)
|
||||
head_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0) //We remove some of the acid volume.
|
||||
update_inv_glasses()
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
else
|
||||
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("head")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(ears)
|
||||
inventory_items_to_kill += ears
|
||||
|
||||
//CHEST//
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
if(!chest_clothes.unacidable)
|
||||
chest_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("chest")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(wear_id)
|
||||
inventory_items_to_kill += wear_id
|
||||
if(r_store)
|
||||
inventory_items_to_kill += r_store
|
||||
if(l_store)
|
||||
inventory_items_to_kill += l_store
|
||||
if(s_store)
|
||||
inventory_items_to_kill += s_store
|
||||
|
||||
|
||||
//ARMS & HANDS//
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && (w_uniform.body_parts_covered & HANDS) || w_uniform && (w_uniform.body_parts_covered & ARMS))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && (wear_suit.body_parts_covered & HANDS) || wear_suit && (wear_suit.body_parts_covered & ARMS))
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
if(!arm_clothes.unacidable)
|
||||
arm_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_gloves()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//LEGS & FEET//
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && (w_uniform.body_parts_covered & FEET) || w_uniform && (w_uniform.body_parts_covered & LEGS))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && (wear_suit.body_parts_covered & FEET) || wear_suit && (wear_suit.body_parts_covered & LEGS))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
if(!leg_clothes.unacidable)
|
||||
leg_clothes.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
update_inv_shoes()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//DAMAGE//
|
||||
for(var/obj/item/bodypart/affecting in damaged)
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
|
||||
if(affecting.name == "head")
|
||||
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
|
||||
affecting.take_damage(acidity, 2*acidity)
|
||||
emote("scream")
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = "Bald"
|
||||
update_hair()
|
||||
status_flags |= DISFIGURED
|
||||
|
||||
update_damage_overlays()
|
||||
|
||||
//MELTING INVENTORY ITEMS//
|
||||
//these items are all outside of armour visually, so melt regardless.
|
||||
if(back)
|
||||
inventory_items_to_kill += back
|
||||
if(belt)
|
||||
inventory_items_to_kill += belt
|
||||
if(r_hand)
|
||||
inventory_items_to_kill += r_hand
|
||||
if(l_hand)
|
||||
inventory_items_to_kill += l_hand
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr, acid_volume_left)
|
||||
acid_volume_left = max(acid_volume_left - acid_decay, 0)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
var/armor = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor, "", "", M.armour_penetration)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage, "the [L.name]"))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
|
||||
if(check_shields(damage, "the [M.name]"))
|
||||
return 0
|
||||
|
||||
var/dam_zone = pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg", "groin")
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
if(M.occupant.a_intent == "harm")
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
|
||||
if(temp)
|
||||
var/update = 0
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 20)
|
||||
Paralyse(1)
|
||||
update |= temp.take_damage(rand(M.force/2, M.force), 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
if("fire")
|
||||
update |= temp.take_damage(0, rand(M.force/2, M.force))
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
if("tox")
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
if(update)
|
||||
update_damage_overlays(0)
|
||||
updatehealth()
|
||||
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>")
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
|
||||
else
|
||||
..()
|
||||
/mob/living/carbon/human/proc/check_block()
|
||||
if(martial_art && martial_art.block_chance \
|
||||
&& prob(martial_art.block_chance) && in_throw_mode \
|
||||
&& !stat && !weakened && !stunned)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
var/spec_return = dna.species.spec_hitby(AM, src)
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
var/obj/item/I
|
||||
var/throwpower = 30
|
||||
if(istype(AM, /obj/item))
|
||||
@@ -355,13 +146,13 @@
|
||||
else if(I)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
|
||||
if(can_embed(I))
|
||||
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.specflags)))
|
||||
if(prob(I.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.species_traits)))
|
||||
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
|
||||
var/obj/item/bodypart/L = pick(bodyparts)
|
||||
L.embedded_objects |= I
|
||||
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
|
||||
I.loc = src
|
||||
L.take_damage(I.w_class*I.embedded_impact_pain_multiplier)
|
||||
L.receive_damage(I.w_class*I.embedded_impact_pain_multiplier)
|
||||
visible_message("<span class='danger'>\the [I.name] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>\the [I.name] embeds itself in your [L.name]!</span>")
|
||||
hitpush = 0
|
||||
skipcatch = 1 //can't catch the now embedded item
|
||||
@@ -379,6 +170,586 @@
|
||||
w_uniform.add_fingerprint(user)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Stun(amount, updating_canmove = 1)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/attacked_by(obj/item/I, mob/living/user)
|
||||
if(!I || !user)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(user.zone_selected)) //what we're actually ending up trying to hit.
|
||||
var/target_area = parse_zone(check_zone(user.zone_selected)) //our intended target
|
||||
feedback_add_details("item_used_for_combat","[I.type]|[I.force]")
|
||||
feedback_add_details("zone_targeted","[target_area]")
|
||||
|
||||
// the attacked_by code varies among species
|
||||
return dna.species.spec_attacked_by(I, user, affecting, a_intent, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
if(check_shields(15, "the [hulk_verb]ing"))
|
||||
return
|
||||
..(user, 1)
|
||||
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
|
||||
var/message = "[user] has [hulk_verb]ed [src]!"
|
||||
visible_message("<span class='danger'>[message]</span>", \
|
||||
"<span class='userdanger'>[message]</span>")
|
||||
adjustBruteLoss(15)
|
||||
damage_clothes(15, BRUTE, "melee")
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //to allow surgery to return properly.
|
||||
return
|
||||
dna.species.spec_attack_hand(M, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_paw(mob/living/carbon/monkey/M)
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
..() //shaking
|
||||
return 0
|
||||
|
||||
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
|
||||
if(get_active_held_item() && drop_item())
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
|
||||
if(M.limb_destroyer)
|
||||
dismembering_strike(M, affecting.body_zone)
|
||||
|
||||
if(can_inject(M, 1, affecting))//Thick suits can stop monkey bites.
|
||||
if(..()) //successful monkey bite, this handles disease contraction.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
apply_damage(damage, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(check_shields(0, M.name))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return 0
|
||||
|
||||
if(..())
|
||||
if(M.a_intent == INTENT_HARM)
|
||||
if (w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
var/damage = prob(90) ? 20 : 0
|
||||
if(!damage)
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has lunged at [src]!</span>")
|
||||
return 0
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee","","",10)
|
||||
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed at [src]!</span>")
|
||||
add_logs(M, src, "attacked")
|
||||
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
|
||||
return 1
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
if(M.a_intent == INTENT_DISARM) //Always drop item in hand, if no item, get stunned instead.
|
||||
if(get_active_held_item() && drop_item())
|
||||
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] disarmed [src]!</span>")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
Weaken(5)
|
||||
add_logs(M, src, "tackled")
|
||||
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [src]!</span>")
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(check_shields(damage, "the [L.name]"))
|
||||
return 0
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
if(check_shields(damage, "the [M.name]", null, MELEE_ATTACK, M.armour_penetration))
|
||||
return 0
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor = run_armor_check(affecting, "melee", armour_penetration = M.armour_penetration)
|
||||
apply_damage(damage, M.melee_damage_type, affecting, armor)
|
||||
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 25)
|
||||
if(M.is_adult)
|
||||
damage = rand(10, 35)
|
||||
|
||||
if(check_shields(damage, "the [M.name]"))
|
||||
return 0
|
||||
|
||||
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
var/armor_block = run_armor_check(affecting, "melee")
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
var/obj/item/bodypart/temp = get_bodypart(pick("chest", "chest", "chest", "head"))
|
||||
if(temp)
|
||||
var/update = 0
|
||||
var/dmg = rand(M.force/2, M.force)
|
||||
switch(M.damtype)
|
||||
if("brute")
|
||||
if(M.force > 20)
|
||||
Paralyse(1)
|
||||
update |= temp.receive_damage(dmg, 0)
|
||||
playsound(src, 'sound/weapons/punch4.ogg', 50, 1)
|
||||
damage_clothes(dmg, BRUTE, "melee", temp.body_zone)
|
||||
if("fire")
|
||||
update |= temp.receive_damage(0, dmg)
|
||||
playsound(src, 'sound/items/Welder.ogg', 50, 1)
|
||||
damage_clothes(dmg, BURN, "melee", temp.body_zone)
|
||||
if("tox")
|
||||
M.mech_toxin_damage(src)
|
||||
else
|
||||
return
|
||||
if(update)
|
||||
update_damage_overlays()
|
||||
updatehealth()
|
||||
|
||||
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
|
||||
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/ex_act(severity, target, origin)
|
||||
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
var/b_loss = 0
|
||||
var/f_loss = 0
|
||||
var/bomb_armor = getarmor(null, "bomb")
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
if(prob(bomb_armor))
|
||||
b_loss = 500
|
||||
var/atom/throw_target = get_edge_target_turf(src, get_dir(src, get_step_away(src, src)))
|
||||
throw_at(throw_target, 200, 4)
|
||||
damage_clothes(400 - bomb_armor, BRUTE, "bomb")
|
||||
else
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
b_loss = 60
|
||||
f_loss = 60
|
||||
if(bomb_armor)
|
||||
b_loss = 30*(2 - round(bomb_armor*0.01, 0.05))
|
||||
f_loss = b_loss
|
||||
damage_clothes(200 - bomb_armor, BRUTE, "bomb")
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(30, 120)
|
||||
if (prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
b_loss = 30
|
||||
if(bomb_armor)
|
||||
b_loss = 15*(2 - round(bomb_armor*0.01, 0.05))
|
||||
damage_clothes(max(50 - bomb_armor, 0), BRUTE, "bomb")
|
||||
if (!istype(ears, /obj/item/clothing/ears/earmuffs))
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(8)
|
||||
|
||||
take_overall_damage(b_loss,f_loss)
|
||||
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2 || !bomb_armor)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && !prob(getarmor(BP, "bomb")) && BP.body_zone != "head" && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
|
||||
|
||||
/mob/living/carbon/human/blob_act(obj/structure/blob/B)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
show_message("<span class='userdanger'>The blob attacks you!</span>")
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
|
||||
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0)
|
||||
if(tesla_shock)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
if(G.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.5
|
||||
if(wear_suit)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
if(S.siemens_coefficient <= 0)
|
||||
total_coeff -= 0.95
|
||||
siemens_coeff = total_coeff
|
||||
else if(!safety)
|
||||
var/gloves_siemens_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
gloves_siemens_coeff = G.siemens_coefficient
|
||||
siemens_coeff = gloves_siemens_coeff
|
||||
if(heart_attack && !illusion)
|
||||
if(shock_damage * siemens_coeff >= 1 && prob(25))
|
||||
heart_attack = 0
|
||||
if(stat == CONSCIOUS)
|
||||
src << "<span class='notice'>You feel your heart beating again!</span>"
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion)
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
/mob/living/carbon/human/emp_act(severity)
|
||||
var/informed = 0
|
||||
for(var/obj/item/bodypart/L in src.bodyparts)
|
||||
if(L.status == BODYPART_ROBOTIC)
|
||||
if(!informed)
|
||||
src << "<span class='userdanger'>You feel a sharp pain as your robotic limbs overload.</span>"
|
||||
informed = 1
|
||||
switch(severity)
|
||||
if(1)
|
||||
L.receive_damage(0,10)
|
||||
src.Stun(10)
|
||||
if(2)
|
||||
L.receive_damage(0,5)
|
||||
src.Stun(5)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
var/list/damaged = list()
|
||||
var/list/inventory_items_to_kill = list()
|
||||
var/acidity = acidpwr * min(acid_volume*0.005, 0.1)
|
||||
//HEAD//
|
||||
if(!bodyzone_hit || bodyzone_hit == "head") //only if we didn't specify a zone or if that zone is the head.
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
if(!(head_clothes.resistance_flags & UNACIDABLE))
|
||||
head_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_glasses()
|
||||
update_inv_wear_mask()
|
||||
update_inv_neck()
|
||||
update_inv_head()
|
||||
else
|
||||
src << "<span class='notice'>Your [head_clothes.name] protects your head and face from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("head")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(ears)
|
||||
inventory_items_to_kill += ears
|
||||
|
||||
//CHEST//
|
||||
if(!bodyzone_hit || bodyzone_hit == "chest")
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
if(!(chest_clothes.resistance_flags & UNACIDABLE))
|
||||
chest_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [chest_clothes.name] protects your body from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("chest")
|
||||
if(.)
|
||||
damaged += .
|
||||
if(wear_id)
|
||||
inventory_items_to_kill += wear_id
|
||||
if(r_store)
|
||||
inventory_items_to_kill += r_store
|
||||
if(l_store)
|
||||
inventory_items_to_kill += l_store
|
||||
if(s_store)
|
||||
inventory_items_to_kill += s_store
|
||||
|
||||
|
||||
//ARMS & HANDS//
|
||||
if(!bodyzone_hit || bodyzone_hit == "l_arm" || bodyzone_hit == "r_arm")
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
|
||||
arm_clothes = wear_suit
|
||||
|
||||
if(arm_clothes)
|
||||
if(!(arm_clothes.resistance_flags & UNACIDABLE))
|
||||
arm_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_gloves()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [arm_clothes.name] protects your arms and hands from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_arm")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//LEGS & FEET//
|
||||
if(!bodyzone_hit || bodyzone_hit == "l_leg" || bodyzone_hit == "r_leg" || bodyzone_hit == "feet")
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (w_uniform.body_parts_covered & LEGS))))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (bodyzone_hit != "feet" && (wear_suit.body_parts_covered & LEGS))))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
if(!(leg_clothes.resistance_flags & UNACIDABLE))
|
||||
leg_clothes.acid_act(acidpwr, acid_volume)
|
||||
update_inv_shoes()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_suit()
|
||||
else
|
||||
src << "<span class='notice'>Your [leg_clothes.name] protects your legs and feet from the acid!</span>"
|
||||
else
|
||||
. = get_bodypart("r_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
. = get_bodypart("l_leg")
|
||||
if(.)
|
||||
damaged += .
|
||||
|
||||
|
||||
//DAMAGE//
|
||||
for(var/obj/item/bodypart/affecting in damaged)
|
||||
affecting.receive_damage(acidity, 2*acidity)
|
||||
|
||||
if(affecting.name == "head")
|
||||
if(prob(min(acidpwr*acid_volume/10, 90))) //Applies disfigurement
|
||||
affecting.receive_damage(acidity, 2*acidity)
|
||||
emote("scream")
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = "Bald"
|
||||
update_hair()
|
||||
status_flags |= DISFIGURED
|
||||
|
||||
update_damage_overlays()
|
||||
|
||||
//MELTING INVENTORY ITEMS//
|
||||
//these items are all outside of armour visually, so melt regardless.
|
||||
if(!bodyzone_hit)
|
||||
if(back)
|
||||
inventory_items_to_kill += back
|
||||
if(belt)
|
||||
inventory_items_to_kill += belt
|
||||
|
||||
inventory_items_to_kill += held_items
|
||||
|
||||
for(var/obj/item/I in inventory_items_to_kill)
|
||||
I.acid_act(acidpwr, acid_volume)
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/singularity_act()
|
||||
var/gain = 20
|
||||
if(mind)
|
||||
if((mind.assigned_role == "Station Engineer") || (mind.assigned_role == "Chief Engineer") )
|
||||
gain = 100
|
||||
if(mind.assigned_role == "Clown")
|
||||
gain = rand(-300, 300)
|
||||
investigate_log("([key_name(src)]) has been consumed by the singularity.","singulo") //Oh that's where the clown ended up!
|
||||
gib()
|
||||
return(gain)
|
||||
|
||||
/mob/living/carbon/human/help_shake_act(mob/living/carbon/M)
|
||||
if(!istype(M))
|
||||
return
|
||||
|
||||
if(health >= 0)
|
||||
if(src == M)
|
||||
visible_message("[src] examines [p_them()]self.", \
|
||||
"<span class='notice'>You check yourself for injuries.</span>")
|
||||
|
||||
var/list/missing = list("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg")
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/LB = X
|
||||
missing -= LB.body_zone
|
||||
var/status = ""
|
||||
var/brutedamage = LB.brute_dam
|
||||
var/burndamage = LB.burn_dam
|
||||
if(hallucination)
|
||||
if(prob(30))
|
||||
brutedamage += rand(30,40)
|
||||
if(prob(30))
|
||||
burndamage += rand(30,40)
|
||||
|
||||
if(brutedamage > 0)
|
||||
status = "bruised"
|
||||
if(brutedamage > 20)
|
||||
status = "battered"
|
||||
if(brutedamage > 40)
|
||||
status = "mangled"
|
||||
if(brutedamage > 0 && burndamage > 0)
|
||||
status += " and "
|
||||
if(burndamage > 40)
|
||||
status += "peeling away"
|
||||
|
||||
else if(burndamage > 10)
|
||||
status += "blistered"
|
||||
else if(burndamage > 0)
|
||||
status += "numb"
|
||||
if(status == "")
|
||||
status = "OK"
|
||||
src << "\t [status == "OK" ? "\blue" : "\red"] Your [LB.name] is [status]."
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
src << "\t <a href='byond://?src=\ref[src];embedded_object=\ref[I];embedded_limb=\ref[LB]'>\red There is \a [I] embedded in your [LB.name]!</a>"
|
||||
|
||||
for(var/t in missing)
|
||||
src << "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>"
|
||||
|
||||
if(bleed_rate)
|
||||
src << "<span class='danger'>You are bleeding!</span>"
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
src << "<span class='info'>You're completely exhausted.</span>"
|
||||
else
|
||||
src << "<span class='info'>You feel fatigued.</span>"
|
||||
else
|
||||
if(wear_suit)
|
||||
wear_suit.add_fingerprint(M)
|
||||
else if(w_uniform)
|
||||
w_uniform.add_fingerprint(M)
|
||||
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
|
||||
if(damage_type != BRUTE && damage_type != BURN)
|
||||
return
|
||||
damage_amount *= 0.5 //0.5 multiplier for balance reason, we don't want clothes to be too easily destroyed
|
||||
var/list/torn_items = list()
|
||||
|
||||
//HEAD//
|
||||
if(!def_zone || def_zone == "head")
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(glasses)
|
||||
head_clothes = glasses
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
torn_items += head_clothes
|
||||
else if(ears)
|
||||
torn_items += ears
|
||||
|
||||
//CHEST//
|
||||
if(!def_zone || def_zone == "chest")
|
||||
var/obj/item/clothing/chest_clothes = null
|
||||
if(w_uniform)
|
||||
chest_clothes = w_uniform
|
||||
if(wear_suit)
|
||||
chest_clothes = wear_suit
|
||||
if(chest_clothes)
|
||||
torn_items += chest_clothes
|
||||
|
||||
//ARMS & HANDS//
|
||||
if(!def_zone || def_zone == "l_arm" || def_zone == "r_arm")
|
||||
var/obj/item/clothing/arm_clothes = null
|
||||
if(gloves)
|
||||
arm_clothes = gloves
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & HANDS) || (w_uniform.body_parts_covered & ARMS)))
|
||||
arm_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
|
||||
arm_clothes = wear_suit
|
||||
if(arm_clothes)
|
||||
torn_items += arm_clothes
|
||||
|
||||
//LEGS & FEET//
|
||||
if(!def_zone || def_zone == "l_leg" || def_zone == "r_leg")
|
||||
var/obj/item/clothing/leg_clothes = null
|
||||
if(shoes)
|
||||
leg_clothes = shoes
|
||||
if(w_uniform && ((w_uniform.body_parts_covered & FEET) || (w_uniform.body_parts_covered & LEGS)))
|
||||
leg_clothes = w_uniform
|
||||
if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
|
||||
leg_clothes = wear_suit
|
||||
if(leg_clothes)
|
||||
torn_items += leg_clothes
|
||||
|
||||
for(var/obj/item/I in torn_items)
|
||||
I.take_damage(damage_amount, damage_type, damage_flag, 0)
|
||||
@@ -3,6 +3,8 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
languages_spoken = HUMAN
|
||||
languages_understood = HUMAN
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
pressure_resistance = 25
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
@@ -29,11 +31,7 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
//Equipment slots
|
||||
var/obj/item/wear_suit = null
|
||||
var/obj/item/w_uniform = null
|
||||
var/obj/item/shoes = null
|
||||
var/obj/item/belt = null
|
||||
var/obj/item/gloves = null
|
||||
var/obj/item/clothing/glasses/glasses = null
|
||||
var/obj/item/ears = null
|
||||
var/obj/item/wear_id = null
|
||||
var/obj/item/r_store = null
|
||||
var/obj/item/l_store = null
|
||||
@@ -41,8 +39,6 @@ var/global/default_martial_art = new/datum/martial_art
|
||||
|
||||
var/special_voice = "" // For changing our voice. Used by a symptom.
|
||||
|
||||
var/gender_ambiguous = 0 //if something goes wrong during gender reassignment this generates a line in examine
|
||||
|
||||
var/bleed_rate = 0 //how much are we bleeding
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
|
||||
|
||||
@@ -81,41 +81,23 @@
|
||||
if(wear_id)
|
||||
return wear_id.GetID()
|
||||
|
||||
///checkeyeprot()
|
||||
///Returns a number between -1 to 2
|
||||
/mob/living/carbon/human/check_eye_prot()
|
||||
var/number = ..()
|
||||
if(istype(src.head, /obj/item/clothing/head)) //are they wearing something on their head
|
||||
var/obj/item/clothing/head/HFP = src.head //if yes gets the flash protection value from that item
|
||||
number += HFP.flash_protect
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
if(istype(src.dna.species, /datum/species/xeno)) //Xenos don't have eyes.
|
||||
number += 2 //So give them protection from flashes.
|
||||
return number
|
||||
|
||||
/mob/living/carbon/human/check_ear_prot()
|
||||
if((ears && (ears.flags & EARBANGPROTECT)) || (head && (head.flags & HEADBANGPROTECT)))
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/human/abiotic(full_body = 0)
|
||||
if(full_body && ((l_hand && !( src.l_hand.flags&ABSTRACT )) || (r_hand && !( src.r_hand.flags&ABSTRACT )) || (back && !(back.flags&ABSTRACT)) || (wear_mask && !(wear_mask.flags&ABSTRACT)) || (head && !(head.flags&ABSTRACT)) || (shoes && !(shoes.flags&ABSTRACT)) || (w_uniform && !(w_uniform.flags&ABSTRACT)) || (wear_suit && !(wear_suit.flags&ABSTRACT)) || (glasses && !(glasses.flags&ABSTRACT)) || (ears && !(ears.flags&ABSTRACT)) || (gloves && !(gloves.flags&ABSTRACT)) ) )
|
||||
return 1
|
||||
var/abiotic_hands = FALSE
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!(I.flags & NODROP))
|
||||
abiotic_hands = TRUE
|
||||
break
|
||||
if(full_body && abiotic_hands && ((back && !(back.flags&NODROP)) || (wear_mask && !(wear_mask.flags&NODROP)) || (head && !(head.flags&NODROP)) || (shoes && !(shoes.flags&NODROP)) || (w_uniform && !(w_uniform.flags&NODROP)) || (wear_suit && !(wear_suit.flags&NODROP)) || (glasses && !(glasses.flags&NODROP)) || (ears && !(ears.flags&NODROP)) || (gloves && !(gloves.flags&NODROP)) ) )
|
||||
return TRUE
|
||||
return abiotic_hands
|
||||
|
||||
if( (src.l_hand && !(src.l_hand.flags&ABSTRACT)) || (src.r_hand && !(src.r_hand.flags&ABSTRACT)) )
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/human/IsAdvancedToolUser()
|
||||
return 1//Humans can use guns and such
|
||||
|
||||
/mob/living/carbon/human/InCritical()
|
||||
return (health <= config.health_threshold_crit && stat == UNCONSCIOUS)
|
||||
return (health <= HEALTH_THRESHOLD_CRIT && stat == UNCONSCIOUS)
|
||||
|
||||
/mob/living/carbon/human/reagent_check(datum/reagent/R)
|
||||
return dna.species.handle_chemicals(R,src)
|
||||
@@ -159,11 +141,11 @@
|
||||
if(src.dna.check_mutation(HULK))
|
||||
src << "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>"
|
||||
return 0
|
||||
if(NOGUNS in src.dna.species.specflags)
|
||||
if(NOGUNS in src.dna.species.species_traits)
|
||||
src << "<span class='warning'>Your fingers don't fit in the trigger guard!</span>"
|
||||
return 0
|
||||
|
||||
if(martial_art && martial_art.name == "The Sleeping Carp") //great dishonor to famiry
|
||||
if(martial_art && martial_art.no_guns) //great dishonor to famiry
|
||||
src << "<span class='warning'>Use of ranged weaponry would bring dishonor to the clan.</span>"
|
||||
return 0
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. += dna.species.movement_delay(src)
|
||||
. = 0
|
||||
. += ..()
|
||||
. += config.human_delay
|
||||
|
||||
. += dna.species.movement_delay(src)
|
||||
|
||||
/mob/living/carbon/human/slip(s_amount, w_amount, obj/O, lube)
|
||||
if(isobj(shoes) && (shoes.flags&NOSLIP) && !(lube&GALOSHES_DONT_HELP))
|
||||
@@ -22,7 +22,7 @@
|
||||
. = 1
|
||||
|
||||
/mob/living/carbon/human/mob_negates_gravity()
|
||||
return ((shoes && shoes.negates_gravity()) || dna.species.negates_gravity())
|
||||
return ((shoes && shoes.negates_gravity()) || dna.species.negates_gravity(src))
|
||||
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
@@ -60,4 +60,4 @@
|
||||
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
|
||||
if(..())
|
||||
return 1
|
||||
return dna.species.space_move()
|
||||
return dna.species.space_move(src)
|
||||
|
||||
@@ -1,16 +1,6 @@
|
||||
/mob/living/carbon/human/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
return dna.species.can_equip(I, slot, disable_warning, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0))
|
||||
return slot
|
||||
if(qdel_on_fail)
|
||||
qdel(I)
|
||||
return null
|
||||
|
||||
|
||||
// Return the item currently in the slot ID
|
||||
/mob/living/carbon/human/get_item_by_slot(slot_id)
|
||||
switch(slot_id)
|
||||
@@ -18,14 +8,12 @@
|
||||
return back
|
||||
if(slot_wear_mask)
|
||||
return wear_mask
|
||||
if(slot_neck)
|
||||
return wear_neck
|
||||
if(slot_handcuffed)
|
||||
return handcuffed
|
||||
if(slot_legcuffed)
|
||||
return legcuffed
|
||||
if(slot_l_hand)
|
||||
return l_hand
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
if(slot_belt)
|
||||
return belt
|
||||
if(slot_wear_id)
|
||||
@@ -52,11 +40,48 @@
|
||||
return s_store
|
||||
return null
|
||||
|
||||
/mob/living/carbon/human/proc/get_all_slots()
|
||||
. = get_head_slots() | get_body_slots()
|
||||
|
||||
/mob/living/carbon/human/proc/get_body_slots()
|
||||
return list(
|
||||
back,
|
||||
s_store,
|
||||
handcuffed,
|
||||
legcuffed,
|
||||
wear_suit,
|
||||
gloves,
|
||||
shoes,
|
||||
belt,
|
||||
wear_id,
|
||||
l_store,
|
||||
r_store,
|
||||
w_uniform
|
||||
)
|
||||
|
||||
/mob/living/carbon/human/proc/get_head_slots()
|
||||
return list(
|
||||
head,
|
||||
wear_mask,
|
||||
glasses,
|
||||
ears,
|
||||
)
|
||||
|
||||
/mob/living/carbon/human/proc/get_storage_slots()
|
||||
return list(
|
||||
back,
|
||||
belt,
|
||||
l_store,
|
||||
r_store,
|
||||
s_store,
|
||||
)
|
||||
|
||||
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
|
||||
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
|
||||
if(!..()) //a check failed or the item has already found its slot
|
||||
return
|
||||
|
||||
var/not_handled = FALSE //Added in case we make this type path deeper one day
|
||||
switch(slot)
|
||||
if(slot_belt)
|
||||
belt = I
|
||||
@@ -71,6 +96,8 @@
|
||||
if(slot_glasses)
|
||||
glasses = I
|
||||
var/obj/item/clothing/glasses/G = I
|
||||
if(G.glass_colour_type)
|
||||
update_glasses_color(G, 1)
|
||||
if(G.tint)
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
@@ -108,14 +135,20 @@
|
||||
else
|
||||
src << "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>"
|
||||
|
||||
/mob/living/carbon/human/unEquip(obj/item/I)
|
||||
//Item is handled and in slot, valid to call callback, for this proc should always be true
|
||||
if(!not_handled)
|
||||
I.equipped(src, slot)
|
||||
|
||||
return not_handled //For future deeper overrides
|
||||
|
||||
/mob/living/carbon/human/doUnEquip(obj/item/I, force)
|
||||
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
|
||||
if(!. || !I)
|
||||
return
|
||||
|
||||
if(I == wear_suit)
|
||||
if(s_store)
|
||||
unEquip(s_store, 1) //It makes no sense for your suit storage to stay on you if you drop your suit.
|
||||
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
|
||||
if(wear_suit.breakouttime) //when unequipping a straightjacket
|
||||
update_action_buttons_icon() //certain action buttons may be usable again.
|
||||
wear_suit = null
|
||||
@@ -124,13 +157,13 @@
|
||||
update_inv_wear_suit()
|
||||
else if(I == w_uniform)
|
||||
if(r_store)
|
||||
unEquip(r_store, 1) //Again, makes sense for pockets to drop.
|
||||
dropItemToGround(r_store, TRUE) //Again, makes sense for pockets to drop.
|
||||
if(l_store)
|
||||
unEquip(l_store, 1)
|
||||
dropItemToGround(l_store, TRUE)
|
||||
if(wear_id)
|
||||
unEquip(wear_id)
|
||||
dropItemToGround(wear_id)
|
||||
if(belt)
|
||||
unEquip(belt)
|
||||
dropItemToGround(belt)
|
||||
w_uniform = null
|
||||
update_suit_sensors()
|
||||
update_inv_w_uniform()
|
||||
@@ -140,6 +173,8 @@
|
||||
else if(I == glasses)
|
||||
glasses = null
|
||||
var/obj/item/clothing/glasses/G = I
|
||||
if(G.glass_colour_type)
|
||||
update_glasses_color(G, 0)
|
||||
if(G.tint)
|
||||
update_tint()
|
||||
if(G.vision_correction)
|
||||
@@ -192,91 +227,6 @@
|
||||
sec_hud_set_security_status()
|
||||
..()
|
||||
|
||||
|
||||
|
||||
|
||||
//Cycles through all clothing slots and tests them for destruction
|
||||
/mob/living/carbon/human/proc/shred_clothing(bomb,shock)
|
||||
var/covered_parts = 0 //The body parts that are protected by exterior clothing/armor
|
||||
var/head_absorbed = 0 //How much of the shock the headgear absorbs when it is shredded. -1=it survives
|
||||
var/suit_absorbed = 0 //How much of the shock the exosuit absorbs when it is shredded. -1=it survives
|
||||
|
||||
//Backpacks can never be protected but are annoying as fuck to lose, so they get a lower chance to be shredded
|
||||
if(back)
|
||||
back.shred(bomb,shock-20,src)
|
||||
|
||||
if(head)
|
||||
covered_parts |= head.flags_inv
|
||||
head_absorbed = head.shred(bomb,shock,src)
|
||||
if(wear_mask)
|
||||
var/absorbed = ((covered_parts & HIDEMASK) ? head_absorbed : 0) //Check if clothing covering this part absorbed any of the shock
|
||||
if(absorbed >= 0)
|
||||
//Masks can be used to shield other parts, but are simplified to simply add their absorbsion to the head armor if it covers the face
|
||||
var/mask_absorbed = wear_mask.shred(bomb,shock-absorbed,src)
|
||||
if(wear_mask.flags_inv & HIDEFACE)
|
||||
covered_parts |= wear_mask.flags_inv
|
||||
if(mask_absorbed < 0) //If the mask didn't get shredded, everything else on the head is protected
|
||||
head_absorbed = -1
|
||||
else
|
||||
head_absorbed += mask_absorbed
|
||||
if(ears)
|
||||
var/absorbed = ((covered_parts & HIDEEARS) ? head_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
ears.shred(bomb,shock-absorbed,src)
|
||||
if(glasses)
|
||||
var/absorbed = ((covered_parts & HIDEEYES) ? head_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
glasses.shred(bomb,shock-absorbed,src)
|
||||
|
||||
if(wear_suit)
|
||||
covered_parts |= wear_suit.flags_inv
|
||||
suit_absorbed = wear_suit.shred(bomb,shock,src)
|
||||
if(gloves)
|
||||
var/absorbed = ((covered_parts & HIDEGLOVES) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
gloves.shred(bomb,shock-absorbed,src)
|
||||
if(shoes)
|
||||
var/absorbed = ((covered_parts & HIDESHOES) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
shoes.shred(bomb,shock-absorbed,src)
|
||||
if(w_uniform)
|
||||
var/absorbed = ((covered_parts & HIDEJUMPSUIT) ? suit_absorbed : 0)
|
||||
if(absorbed >= 0)
|
||||
w_uniform.shred(bomb,shock-20-absorbed,src) //Uniforms are also annoying to get shredded
|
||||
|
||||
/obj/item/proc/shred(bomb,shock,mob/living/carbon/human/Human)
|
||||
if(flags & ABSTRACT)
|
||||
return -1
|
||||
|
||||
var/shredded
|
||||
|
||||
if(!bomb)
|
||||
if(burn_state != -1)
|
||||
shredded = 1 //No heat protection, it burns
|
||||
else
|
||||
shredded = -1 //Heat protection = Fireproof
|
||||
|
||||
else if(shock > 0)
|
||||
if(prob(max(shock-armor["bomb"],0)))
|
||||
shredded = armor["bomb"] + 10 //It gets shredded, but it also absorbs the shock the clothes underneath would recieve by this amount
|
||||
else
|
||||
shredded = -1 //It survives explosion
|
||||
|
||||
if(shredded > 0)
|
||||
if(Human) //Unequip if equipped
|
||||
Human.unEquip(src)
|
||||
|
||||
if(bomb)
|
||||
empty_object_contents()
|
||||
spawn(1) //so the shreds aren't instantly deleted by the explosion
|
||||
var/obj/effect/decal/cleanable/shreds/Shreds = new(loc)
|
||||
Shreds.desc = "The sad remains of what used to be [src.name]."
|
||||
qdel(src)
|
||||
else
|
||||
burn()
|
||||
|
||||
return shredded
|
||||
|
||||
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
|
||||
var/datum/outfit/O = null
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
|
||||
|
||||
@@ -29,24 +29,32 @@
|
||||
if (notransform)
|
||||
return
|
||||
|
||||
if(..())
|
||||
if(..()) //not dead
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_life(src)
|
||||
|
||||
if(stat != DEAD)
|
||||
//heart attack stuff
|
||||
handle_heart()
|
||||
|
||||
if(stat != DEAD)
|
||||
//Stuff jammed in your limbs hurts
|
||||
handle_embedded_objects()
|
||||
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
|
||||
dna.species.spec_life(src) // for mutantraces
|
||||
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags & STOPSPRESSUREDMAGE)) && (head && (head.flags & STOPSPRESSUREDMAGE)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(ismob(loc))
|
||||
return ONE_ATMOSPHERE //hopefully won't murderficate people in your guts by going for a spacewalk
|
||||
else
|
||||
return pressure
|
||||
|
||||
@@ -85,29 +93,54 @@
|
||||
/mob/living/carbon/human/breathe()
|
||||
if(!dna.species.breathe(src))
|
||||
..()
|
||||
|
||||
#define HUMAN_MAX_OXYLOSS 3
|
||||
#define HUMAN_CRIT_MAX_OXYLOSS (SSmob.wait/30)
|
||||
/mob/living/carbon/human/check_breath(datum/gas_mixture/breath)
|
||||
dna.species.check_breath(breath, src)
|
||||
|
||||
var/L = getorganslot("lungs")
|
||||
|
||||
if(!L)
|
||||
if(health >= HEALTH_THRESHOLD_CRIT)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
|
||||
else if(!(NOCRITDAMAGE in dna.species.species_traits))
|
||||
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
|
||||
|
||||
failed_last_breath = 1
|
||||
|
||||
if(dna && dna.species)
|
||||
var/datum/species/S = dna.species
|
||||
|
||||
if(S.breathid == "o2")
|
||||
throw_alert("oxy", /obj/screen/alert/oxy)
|
||||
else if(S.breathid == "tox")
|
||||
throw_alert("not_enough_tox", /obj/screen/alert/not_enough_tox)
|
||||
else if(S.breathid == "co2")
|
||||
throw_alert("not_enough_co2", /obj/screen/alert/not_enough_co2)
|
||||
|
||||
return 0
|
||||
else
|
||||
if(istype(L,/obj/item/organ/lungs))
|
||||
var/obj/item/organ/lungs/lun = L
|
||||
lun.check_breath(breath,src)
|
||||
|
||||
#undef HUMAN_MAX_OXYLOSS
|
||||
#undef HUMAN_CRIT_MAX_OXYLOSS
|
||||
|
||||
/mob/living/carbon/human/handle_environment(datum/gas_mixture/environment)
|
||||
dna.species.handle_environment(environment, src)
|
||||
|
||||
///FIRE CODE
|
||||
/mob/living/carbon/human/handle_fire()
|
||||
if(!dna || !dna.species.handle_fire(src))
|
||||
..()
|
||||
if(on_fire)
|
||||
var/thermal_protection = get_thermal_protection()
|
||||
|
||||
if(thermal_protection >= FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT)
|
||||
return
|
||||
if(thermal_protection >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
bodytemperature += 11
|
||||
else
|
||||
bodytemperature += (BODYTEMP_HEATING_MAX + (fire_stacks * 12))
|
||||
..()
|
||||
if(dna)
|
||||
dna.species.handle_fire(src)
|
||||
|
||||
/mob/living/carbon/human/proc/get_thermal_protection()
|
||||
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
|
||||
|
||||
if(ismob(loc))
|
||||
thermal_protection = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT //because lazy
|
||||
|
||||
if(wear_suit)
|
||||
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
thermal_protection += (wear_suit.max_heat_protection_temperature*0.7)
|
||||
@@ -133,6 +166,7 @@
|
||||
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
|
||||
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
|
||||
var/thermal_protection_flags = 0
|
||||
|
||||
//Handle normal clothing
|
||||
if(head)
|
||||
if(head.max_heat_protection_temperature && head.max_heat_protection_temperature >= temperature)
|
||||
@@ -217,9 +251,12 @@
|
||||
if(dna.check_mutation(COLDRES))
|
||||
return 1 //Fully protected from the cold.
|
||||
|
||||
if(dna && (RESISTTEMP in dna.species.specflags))
|
||||
if(dna && (RESISTCOLD in dna.species.species_traits))
|
||||
return 1
|
||||
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy
|
||||
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = get_cold_protection_flags(temperature)
|
||||
|
||||
@@ -277,7 +314,7 @@
|
||||
if(head)
|
||||
if(head.flags & BLOCK_GAS_SMOKE_EFFECT)
|
||||
. = 1
|
||||
if(NOBREATH in dna.species.specflags)
|
||||
if(NOBREATH in dna.species.species_traits)
|
||||
. = 1
|
||||
return .
|
||||
|
||||
@@ -287,11 +324,11 @@
|
||||
var/obj/item/bodypart/BP = X
|
||||
for(var/obj/item/I in BP.embedded_objects)
|
||||
if(prob(I.embedded_pain_chance))
|
||||
BP.take_damage(I.w_class*I.embedded_pain_multiplier)
|
||||
BP.receive_damage(I.w_class*I.embedded_pain_multiplier)
|
||||
src << "<span class='userdanger'>\the [I] embedded in your [BP.name] hurts!</span>"
|
||||
|
||||
if(prob(I.embedded_fall_chance))
|
||||
BP.take_damage(I.w_class*I.embedded_fall_pain_multiplier)
|
||||
BP.receive_damage(I.w_class*I.embedded_fall_pain_multiplier)
|
||||
BP.embedded_objects -= I
|
||||
I.loc = get_turf(src)
|
||||
visible_message("<span class='danger'>\the [I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>\the [I] falls out of your [BP.name]!</span>")
|
||||
@@ -301,8 +338,8 @@
|
||||
|
||||
/mob/living/carbon/human/proc/handle_heart()
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
var/needs_heart = (!(NOBLOOD in dna.species.specflags))
|
||||
var/we_breath = (!(NOBREATH in dna.species.specflags))
|
||||
var/needs_heart = (!(NOBLOOD in dna.species.species_traits))
|
||||
var/we_breath = (!(NOBREATH in dna.species.species_traits))
|
||||
|
||||
if(heart_attack)
|
||||
if(!needs_heart)
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
|
||||
// how do species that don't breathe talk? magic, that's what.
|
||||
if(!(NOBREATH in dna.species.specflags) && !getorganslot("lungs"))
|
||||
if(!(NOBREATH in dna.species.species_traits) && !getorganslot("lungs"))
|
||||
return 0
|
||||
if(mind)
|
||||
return !mind.miming
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
/datum/species/abductor
|
||||
name = "Abductor"
|
||||
id = "abductor"
|
||||
darksight = 3
|
||||
say_mod = "gibbers"
|
||||
sexes = 0
|
||||
species_traits = list(NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS)
|
||||
mutant_organs = list(/obj/item/organ/tongue/abductor)
|
||||
var/scientist = 0 // vars to not pollute spieces list with castes
|
||||
var/agent = 0
|
||||
var/team = 1
|
||||
@@ -0,0 +1,21 @@
|
||||
/datum/species/android
|
||||
name = "Android"
|
||||
id = "android"
|
||||
say_mod = "states"
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT)
|
||||
meat = null
|
||||
damage_overlay_type = "synth"
|
||||
mutant_organs = list(/obj/item/organ/tongue/robot)
|
||||
limbs_id = "synth"
|
||||
|
||||
/datum/species/android/on_species_gain(mob/living/carbon/C)
|
||||
. = ..()
|
||||
for(var/X in C.bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.change_bodypart_status(BODYPART_ROBOTIC)
|
||||
|
||||
/datum/species/android/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
for(var/X in C.bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.change_bodypart_status(BODYPART_ORGANIC)
|
||||
@@ -0,0 +1,139 @@
|
||||
/datum/species/angel
|
||||
name = "Angel"
|
||||
id = "angel"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
mutant_bodyparts = list("tail_human", "ears", "wings")
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "Angel")
|
||||
use_skintones = 1
|
||||
no_equip = list(slot_back)
|
||||
blacklisted = 1
|
||||
limbs_id = "human"
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
|
||||
var/datum/action/innate/flight/fly
|
||||
|
||||
/datum/species/angel/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
..()
|
||||
if(H.dna && H.dna.species &&((H.dna.features["wings"] != "Angel") && ("wings" in H.dna.species.mutant_bodyparts)))
|
||||
H.dna.features["wings"] = "Angel"
|
||||
H.update_body()
|
||||
if(ishuman(H)&& !fly)
|
||||
fly = new
|
||||
fly.Grant(H)
|
||||
|
||||
|
||||
/datum/species/angel/on_species_loss(mob/living/carbon/human/H)
|
||||
if(fly)
|
||||
fly.Remove(H)
|
||||
if(H.movement_type & FLYING)
|
||||
H.movement_type &= ~FLYING
|
||||
ToggleFlight(H,0)
|
||||
if(H.dna && H.dna.species &&((H.dna.features["wings"] != "None") && ("wings" in H.dna.species.mutant_bodyparts)))
|
||||
H.dna.features["wings"] = "None"
|
||||
H.update_body()
|
||||
..()
|
||||
|
||||
/datum/species/angel/spec_life(mob/living/carbon/human/H)
|
||||
HandleFlight(H)
|
||||
|
||||
/datum/species/angel/proc/HandleFlight(mob/living/carbon/human/H)
|
||||
if(H.movement_type & FLYING)
|
||||
if(!CanFly(H))
|
||||
ToggleFlight(H,0)
|
||||
return 0
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
|
||||
/datum/species/angel/proc/CanFly(mob/living/carbon/human/H)
|
||||
if(H.stat || H.stunned || H.weakened)
|
||||
return 0
|
||||
if(H.wear_suit && ((H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))) //Jumpsuits have tail holes, so it makes sense they have wing holes too
|
||||
H << "Your suit blocks your wings from extending!"
|
||||
return 0
|
||||
var/turf/T = get_turf(H)
|
||||
if(!T)
|
||||
return 0
|
||||
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
if(environment && !(environment.return_pressure() > 30))
|
||||
H << "<span class='warning'>The atmosphere is too thin for you to fly!</span>"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
|
||||
/datum/action/innate/flight
|
||||
name = "Toggle Flight"
|
||||
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_STUNNED
|
||||
button_icon_state = "flight"
|
||||
|
||||
/datum/action/innate/flight/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/datum/species/angel/A = H.dna.species
|
||||
if(A.CanFly(H))
|
||||
if(H.movement_type & FLYING)
|
||||
H << "<span class='notice'>You settle gently back onto the ground...</span>"
|
||||
A.ToggleFlight(H,0)
|
||||
H.update_canmove()
|
||||
else
|
||||
H << "<span class='notice'>You beat your wings and begin to hover gently above the ground...</span>"
|
||||
H.resting = 0
|
||||
A.ToggleFlight(H,1)
|
||||
H.update_canmove()
|
||||
|
||||
/datum/species/angel/proc/flyslip(mob/living/carbon/human/H)
|
||||
var/obj/buckled_obj
|
||||
if(H.buckled)
|
||||
buckled_obj = H.buckled
|
||||
|
||||
H << "<span class='notice'>Your wings spazz out and launch you!</span>"
|
||||
|
||||
playsound(H.loc, 'sound/misc/slip.ogg', 50, 1, -3)
|
||||
|
||||
for(var/obj/item/I in H.held_items)
|
||||
H.accident(I)
|
||||
|
||||
var/olddir = H.dir
|
||||
|
||||
H.stop_pulling()
|
||||
if(buckled_obj)
|
||||
buckled_obj.unbuckle_mob(H)
|
||||
step(buckled_obj, olddir)
|
||||
else
|
||||
for(var/i=1, i<5, i++)
|
||||
spawn (i)
|
||||
step(H, olddir)
|
||||
H.spin(1,1)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/species/angel/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H.movement_type & FLYING)
|
||||
ToggleFlight(H,0)
|
||||
flyslip(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/angel/negates_gravity(mob/living/carbon/human/H)
|
||||
if(H.movement_type & FLYING)
|
||||
return 1
|
||||
|
||||
/datum/species/angel/space_move(mob/living/carbon/human/H)
|
||||
if(H.movement_type & FLYING)
|
||||
return 1
|
||||
|
||||
/datum/species/angel/proc/ToggleFlight(mob/living/carbon/human/H,flight)
|
||||
if(flight && CanFly(H))
|
||||
stunmod = 2
|
||||
speedmod = -1
|
||||
H.movement_type |= FLYING
|
||||
override_float = 1
|
||||
H.pass_flags |= PASSTABLE
|
||||
H.OpenWings()
|
||||
else
|
||||
stunmod = 1
|
||||
speedmod = 0
|
||||
H.movement_type &= ~FLYING
|
||||
override_float = 0
|
||||
H.pass_flags &= ~PASSTABLE
|
||||
H.CloseWings()
|
||||
@@ -0,0 +1,19 @@
|
||||
/datum/species/corporate
|
||||
name = "Corporate Agent"
|
||||
id = "agent"
|
||||
hair_alpha = 0
|
||||
say_mod = "declares"
|
||||
speedmod = -2//Fast
|
||||
brutemod = 0.7//Tough against firearms
|
||||
burnmod = 0.65//Tough against lasers
|
||||
coldmod = 0
|
||||
heatmod = 0.5//it's a little tough to burn them to death not as hard though.
|
||||
punchdamagelow = 20
|
||||
punchdamagehigh = 30//they are inhumanly strong
|
||||
punchstunthreshold = 25
|
||||
attack_verb = "smash"
|
||||
attack_sound = "sound/weapons/resonator_blast.ogg"
|
||||
blacklisted = 1
|
||||
use_skintones = 0
|
||||
species_traits = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER)
|
||||
sexes = 0
|
||||
@@ -0,0 +1,29 @@
|
||||
/datum/species/fly
|
||||
name = "Flyperson"
|
||||
id = "fly"
|
||||
say_mod = "buzzes"
|
||||
mutant_organs = list(/obj/item/organ/tongue/fly)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/fly
|
||||
|
||||
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "pestkiller")
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
|
||||
|
||||
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(istype(chem,/datum/reagent/consumable))
|
||||
var/datum/reagent/consumable/nutri_check = chem
|
||||
if(nutri_check.nutriment_factor > 0)
|
||||
var/turf/pos = get_turf(H)
|
||||
H.vomit(0, 0, 0, 1, 1)
|
||||
playsound(pos, 'sound/effects/splat.ogg', 50, 1)
|
||||
H.visible_message("<span class='danger'>[H] vomits on the floor!</span>", \
|
||||
"<span class='userdanger'>You throw up on the floor!</span>")
|
||||
..()
|
||||
|
||||
/datum/species/fly/check_weakness(obj/item/weapon, mob/living/attacker)
|
||||
if(istype(weapon,/obj/item/weapon/melee/flyswatter))
|
||||
return 29 //Flyswatters deal 30x damage to flypeople.
|
||||
return 0
|
||||
@@ -0,0 +1,214 @@
|
||||
datum/species/canid
|
||||
name = "Canid"
|
||||
id = "canid"
|
||||
default_color = "4B4B4B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
// subspecies = list("fox")
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "snout", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "body_markings" = "None", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "None")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1
|
||||
|
||||
/datum/species/canid/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
//FELID//
|
||||
|
||||
/datum/species/felid
|
||||
name = "Felid"
|
||||
id = "felid"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_body_markings", "mam_ears", "mam_tail", "snout", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_body_markings" = "Belly", "mam_ears" = "Big Cat", "mam_tail" = "Big Cat")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1 //no sprites yet
|
||||
|
||||
/datum/species/tajaran/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
//Mammal//
|
||||
/datum/species/ailurus
|
||||
name = "Ailurus"
|
||||
id = "ailurus"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "ailurus")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1 //no sprites yet
|
||||
|
||||
//AVIAN//
|
||||
/datum/species/avian
|
||||
name = "Avian"
|
||||
id = "avian"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("beak", "wings", "avian_tail")
|
||||
default_features = list("beak" = "None", "wings" = "None")
|
||||
attack_verb = "peck"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 0 //no sprites yet
|
||||
blacklisted = 1
|
||||
|
||||
//AQUATIC//
|
||||
/datum/species/shark
|
||||
name = "Shark"
|
||||
id = "shark"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "shark")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1 //no sprites yet
|
||||
|
||||
//INSECT//
|
||||
/datum/species/moth
|
||||
name = "Moth"
|
||||
id = "moth"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(EYECOLOR,LIPS,HAIR)
|
||||
attack_verb = "flutter" //wat?
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1 //no sprites yet
|
||||
|
||||
|
||||
//HERBIVOROUS//
|
||||
|
||||
//EXOTIC//
|
||||
//These races will likely include lots of downsides and upsides. Keep them relatively balanced.//
|
||||
/datum/species/xeno
|
||||
name = "Xenomorph"
|
||||
id = "xeno"
|
||||
say_mod = "hisses"
|
||||
eyes = "none"
|
||||
species_traits = list()
|
||||
mutant_organs = list(/obj/item/organ/tongue/alien)
|
||||
mutant_bodyparts = list("xenohead",
|
||||
"xenodorsal",
|
||||
"xenotail")
|
||||
default_features = list("xenohead"="Hunter",
|
||||
"xenodorsal"="Dorsal Tubes",
|
||||
"xenotail"="Xenomorph Tail")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
burnmod = 1.75
|
||||
heatmod = 1.75
|
||||
darksight = 4 //Just above slimes
|
||||
exotic_blood = "xblood"
|
||||
damage_overlay_type = "xeno"
|
||||
no_equip = list(slot_glasses) //MY EYES, THEY'RE GONE
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/xeno
|
||||
// safe_toxins_max = 32 //Too much of anything is bad.
|
||||
roundstart = 0
|
||||
// whitelisted = 1
|
||||
// whitelist = list("talkingcactus") //testing whitelisting
|
||||
|
||||
/datum/species/xeno/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
var/obj/effect/decal/cleanable/xenoblood/xgibs/XG
|
||||
if(istype(C.gib_type, XG))
|
||||
return
|
||||
else
|
||||
C.gib_type = XG
|
||||
|
||||
/datum/species/xeno/on_species_loss(mob/living/carbon/C)
|
||||
..()
|
||||
var/obj/effect/decal/cleanable/xenoblood/xgibs/XG
|
||||
var/obj/effect/decal/cleanable/blood/gibs/HG
|
||||
if(istype(C.gib_type, XG))
|
||||
C.gib_type = HG
|
||||
else
|
||||
return
|
||||
|
||||
/datum/reagent/toxin/acid/xenoblood
|
||||
name = "acid blood"
|
||||
id = "xblood"
|
||||
description = "A highly corrosive substance, it is capable of burning through most natural or man-made materials in short order."
|
||||
color = "#66CC00"
|
||||
toxpwr = 0
|
||||
acidpwr = 12
|
||||
|
||||
/*
|
||||
/datum/species/yautja
|
||||
name = "Yautja"
|
||||
id = "pred"
|
||||
say_mod = "clicks"
|
||||
eyes = "predeyes"
|
||||
mutant_organs = list(/obj/item/organ/tongue/yautja)
|
||||
specflags = list(EYECOLOR)
|
||||
lang_spoken = YAUTJA
|
||||
lang_understood = HUMAN|YAUTJA|ALIEN
|
||||
no_equip = list(slot_head)
|
||||
punchdamagelow = 4
|
||||
punchdamagehigh = 14
|
||||
punchstunthreshold = 13
|
||||
blacklisted = 1
|
||||
roundstart = 0
|
||||
whitelist = 1
|
||||
whitelist = list("talkingcactus")
|
||||
|
||||
/datum/outfit/yautja_basic
|
||||
name = "Yautja, Basic"
|
||||
uniform = /obj/item/clothing/under/mesh
|
||||
suit = /obj/item/clothing/suit/armor/yautja_fake
|
||||
shoes = /obj/item/clothing/shoes/yautja_fake
|
||||
mask = /obj/item/clothing/mask/gas/yautja_fake
|
||||
|
||||
/datum/species/yautja/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/datum/outfit/yautja_basic/O = new /datum/outfit/yautja_basic//Just basic gear. Doesn't include anything that gives any meaningful advantage.
|
||||
H.equipOutfit(O, visualsOnly)
|
||||
return 0*/
|
||||
|
||||
/datum/species/octopus
|
||||
blacklisted = 1
|
||||
/datum/species/carp
|
||||
blacklisted = 1
|
||||
/datum/species/horse
|
||||
blacklisted = 1
|
||||
|
||||
///////////////////
|
||||
//DONATOR SPECIES//
|
||||
///////////////////
|
||||
|
||||
//ChronoFlux: Slimecoon
|
||||
/*
|
||||
/datum/species/jelly/slime/slimecoon
|
||||
name = "Slime Raccoon"
|
||||
id = "slimecoon"
|
||||
limbs_id = "slime"
|
||||
whitelisted = 1
|
||||
whitelist = list("chronoflux")
|
||||
blacklisted = 1
|
||||
mutant_bodyparts = list("slimecoontail", "slimecoonears", "slimecoonsnout")
|
||||
default_features = list("slimecoontail" = "Slimecoon Tail", "slimecoonears" = "Slimecoon Ears", "slimecoonsnout" = "Slimecoon Snout")*/
|
||||
|
||||
|
||||
/datum/species/shark/datashark
|
||||
name = "DataShark"
|
||||
id = "datashark"
|
||||
default_color = "BCAC9B"
|
||||
species_traits = list(EYECOLOR,LIPS,HAIR)
|
||||
mutant_bodyparts = list("mam_tail")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF","mam_tail" = "datashark")
|
||||
attack_verb = "bite"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
roundstart = 1 //no sprites yet
|
||||
whitelisted = 1
|
||||
whitelist = list("rubyflamewing")
|
||||
blacklisted = 0
|
||||
@@ -0,0 +1,447 @@
|
||||
/datum/species/golem
|
||||
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
|
||||
name = "Golem"
|
||||
id = "iron"
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
|
||||
speedmod = 2
|
||||
armor = 55
|
||||
siemens_coeff = 0
|
||||
punchdamagelow = 5
|
||||
punchdamagehigh = 14
|
||||
punchstunthreshold = 11 //about 40% chance to stun
|
||||
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform)
|
||||
nojumpsuit = 1
|
||||
sexes = 1
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem
|
||||
// To prevent golem subtypes from overwhelming the odds when random species
|
||||
// changes, only the Random Golem type can be chosen
|
||||
blacklisted = TRUE
|
||||
dangerous_existence = TRUE
|
||||
limbs_id = "golem"
|
||||
fixed_mut_color = "aaa"
|
||||
var/info_text = "As an <span class='danger'>Iron Golem</span>, you don't have any special traits."
|
||||
|
||||
/datum/species/golem/random
|
||||
name = "Random Golem"
|
||||
blacklisted = FALSE
|
||||
dangerous_existence = FALSE
|
||||
|
||||
/datum/species/golem/random/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
var/list/golem_types = typesof(/datum/species/golem) - src.type
|
||||
var/datum/species/golem/golem_type = pick(golem_types)
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.set_species(golem_type)
|
||||
H << "[initial(golem_type.info_text)]"
|
||||
|
||||
/datum/species/golem/adamantine
|
||||
name = "Adamantine Golem"
|
||||
id = "adamantine"
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem/adamantine
|
||||
fixed_mut_color = "4ed"
|
||||
info_text = "As an <span class='danger'>Adamantine Golem</span>, you don't have any special traits."
|
||||
|
||||
//Explodes on death
|
||||
/datum/species/golem/plasma
|
||||
name = "Plasma Golem"
|
||||
id = "plasma"
|
||||
fixed_mut_color = "a3d"
|
||||
meat = /obj/item/weapon/ore/plasma
|
||||
//Can burn and takes damage from heat
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
|
||||
info_text = "As a <span class='danger'>Plasma Golem</span>, you explode on death!"
|
||||
burnmod = 1.5
|
||||
|
||||
/datum/species/golem/plasma/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
explosion(get_turf(H),0,1,2,flame_range = 5)
|
||||
if(H)
|
||||
H.gib()
|
||||
|
||||
//Harder to hurt
|
||||
/datum/species/golem/diamond
|
||||
name = "Diamond Golem"
|
||||
id = "diamond"
|
||||
fixed_mut_color = "0ff"
|
||||
armor = 70 //up from 55
|
||||
meat = /obj/item/weapon/ore/diamond
|
||||
info_text = "As a <span class='danger'>Diamond Golem</span>, you are more resistant than the average golem."
|
||||
|
||||
//Faster but softer and less armoured
|
||||
/datum/species/golem/gold
|
||||
name = "Gold Golem"
|
||||
id = "gold"
|
||||
fixed_mut_color = "cc0"
|
||||
speedmod = 1
|
||||
armor = 25 //down from 55
|
||||
meat = /obj/item/weapon/ore/gold
|
||||
info_text = "As a <span class='danger'>Gold Golem</span>, you are faster but less resistant than the average golem."
|
||||
|
||||
//Heavier, thus higher chance of stunning when punching
|
||||
/datum/species/golem/silver
|
||||
name = "Silver Golem"
|
||||
id = "silver"
|
||||
fixed_mut_color = "ddd"
|
||||
punchstunthreshold = 9 //60% chance, from 40%
|
||||
meat = /obj/item/weapon/ore/silver
|
||||
info_text = "As a <span class='danger'>Silver Golem</span>, your attacks are heavier and have a higher chance of stunning."
|
||||
|
||||
//Harder to stun, deals more damage, but it's even slower
|
||||
/datum/species/golem/plasteel
|
||||
name = "Plasteel Golem"
|
||||
id = "plasteel"
|
||||
fixed_mut_color = "bbb"
|
||||
stunmod = 0.40
|
||||
punchdamagelow = 12
|
||||
punchdamagehigh = 21
|
||||
punchstunthreshold = 18 //still 40% stun chance
|
||||
speedmod = 4 //pretty fucking slow
|
||||
meat = /obj/item/weapon/ore/iron
|
||||
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
|
||||
attack_verb = "smash"
|
||||
attack_sound = "sound/effects/meteorimpact.ogg" //hits pretty hard
|
||||
|
||||
//Immune to ash storms
|
||||
/datum/species/golem/titanium
|
||||
name = "Titanium Golem"
|
||||
id = "titanium"
|
||||
fixed_mut_color = "fff"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
info_text = "As a <span class='danger'>Titanium Golem</span>, you are immune to ash storms, and slightly more resistant to burn damage."
|
||||
burnmod = 0.9
|
||||
|
||||
/datum/species/golem/titanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.weather_immunities |= "ash"
|
||||
|
||||
/datum/species/golem/titanium/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.weather_immunities -= "ash"
|
||||
|
||||
//Immune to ash storms and lava
|
||||
/datum/species/golem/plastitanium
|
||||
name = "Plastitanium Golem"
|
||||
id = "plastitanium"
|
||||
fixed_mut_color = "888"
|
||||
meat = /obj/item/weapon/ore/titanium
|
||||
info_text = "As a <span class='danger'>Plastitanium Golem</span>, you are immune to both ash storms and lava, and slightly more resistant to burn damage."
|
||||
burnmod = 0.8
|
||||
|
||||
/datum/species/golem/plastitanium/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.weather_immunities |= "lava"
|
||||
C.weather_immunities |= "ash"
|
||||
|
||||
/datum/species/golem/plastitanium/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.weather_immunities -= "ash"
|
||||
C.weather_immunities -= "lava"
|
||||
|
||||
//Fast and regenerates... but can only speak like an abductor
|
||||
/datum/species/golem/alloy
|
||||
name = "Alien Alloy Golem"
|
||||
id = "alloy"
|
||||
fixed_mut_color = "333"
|
||||
meat = /obj/item/stack/sheet/mineral/abductor
|
||||
mutant_organs = list(/obj/item/organ/tongue/abductor) //abductor tongue
|
||||
speedmod = 1 //faster
|
||||
info_text = "As an <span class='danger'>Alloy Golem</span>, you are made of advanced alien materials: you are faster and regenerate over time. You are, however, only able to be heard by other alloy golems."
|
||||
|
||||
//Regenerates because self-repairing super-advanced alien tech
|
||||
/datum/species/golem/alloy/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD)
|
||||
return
|
||||
H.heal_overall_damage(2,2)
|
||||
H.adjustToxLoss(-2)
|
||||
H.adjustOxyLoss(-2)
|
||||
|
||||
//Since this will usually be created from a collaboration between podpeople and free golems, wood golems are a mix between the two races
|
||||
/datum/species/golem/wood
|
||||
name = "Wood Golem"
|
||||
id = "wood"
|
||||
fixed_mut_color = "49311c"
|
||||
meat = /obj/item/stack/sheet/mineral/wood
|
||||
//Can burn and take damage from heat
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS)
|
||||
armor = 30
|
||||
burnmod = 1.25
|
||||
heatmod = 1.5
|
||||
info_text = "As a <span class='danger'>Wooden Golem</span>, you have plant-like traits: you take damage from extreme temperatures, can be set on fire, and have lower armor than a normal golem. You regenerate when in the light and wither in the darkness."
|
||||
|
||||
/datum/species/golem/wood/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.faction |= "plants"
|
||||
C.faction |= "vines"
|
||||
|
||||
/datum/species/golem/wood/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.faction -= "plants"
|
||||
C.faction -= "vines"
|
||||
|
||||
/datum/species/golem/wood/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD)
|
||||
return
|
||||
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
|
||||
if(isturf(H.loc)) //else, there's considered to be no light
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(10,T.get_lumcount()) - 5
|
||||
H.nutrition += light_amount
|
||||
if(H.nutrition > NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL
|
||||
if(light_amount > 2) //if there's enough light, heal
|
||||
H.heal_overall_damage(1,1)
|
||||
H.adjustToxLoss(-1)
|
||||
H.adjustOxyLoss(-1)
|
||||
|
||||
if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
|
||||
H.take_overall_damage(2,0)
|
||||
|
||||
/datum/species/golem/wood/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "plantbgone")
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
|
||||
//Radioactive
|
||||
/datum/species/golem/uranium
|
||||
name = "Uranium Golem"
|
||||
id = "uranium"
|
||||
fixed_mut_color = "7f0"
|
||||
meat = /obj/item/weapon/ore/uranium
|
||||
info_text = "As an <span class='danger'>Uranium Golem</span>, you emit radiation pulses every once in a while. It won't harm fellow golems, but organic lifeforms will be affected."
|
||||
|
||||
var/last_event = 0
|
||||
var/active = null
|
||||
|
||||
/datum/species/golem/uranium/spec_life(mob/living/carbon/human/H)
|
||||
if(!active)
|
||||
if(world.time > last_event+30)
|
||||
active = 1
|
||||
radiation_pulse(get_turf(H), 3, 3, 5, 0)
|
||||
last_event = world.time
|
||||
active = null
|
||||
..()
|
||||
|
||||
//Immune to physical bullets and resistant to brute, but very vulnerable to burn damage. Dusts on death.
|
||||
/datum/species/golem/sand
|
||||
name = "Sand Golem"
|
||||
id = "sand"
|
||||
fixed_mut_color = "ffdc8f"
|
||||
meat = /obj/item/weapon/ore/glass //this is sand
|
||||
armor = 0
|
||||
burnmod = 3 //melts easily
|
||||
brutemod = 0.25
|
||||
info_text = "As a <span class='danger'>Sand Golem</span>, you are immune to physical bullets and take very little brute damage, but are extremely vulnerable to burn damage. You will also turn to sand when dying, preventing any form of recovery."
|
||||
attack_sound = "sound/effects/shovel_dig.ogg"
|
||||
|
||||
/datum/species/golem/sand/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='danger'>[H] turns into a pile of sand!</span>")
|
||||
for(var/obj/item/W in H)
|
||||
H.dropItemToGround(W)
|
||||
for(var/i=1, i <= rand(3,5), i++)
|
||||
new /obj/item/weapon/ore/glass(get_turf(H))
|
||||
qdel(H)
|
||||
|
||||
/datum/species/golem/sand/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
if(!(P.original == H && P.firer == H))
|
||||
if(P.flag == "bullet" || P.flag == "bomb")
|
||||
playsound(H, "sound/effects/shovel_dig.ogg", 70, 1)
|
||||
H.visible_message("<span class='danger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>", \
|
||||
"<span class='userdanger'>The [P.name] sinks harmlessly in [H]'s sandy body!</span>")
|
||||
return 2
|
||||
return 0
|
||||
|
||||
//Reflects lasers and resistant to burn damage, but very vulnerable to brute damage. Shatters on death.
|
||||
/datum/species/golem/glass
|
||||
name = "Glass Golem"
|
||||
id = "glass"
|
||||
fixed_mut_color = "5a96b4aa" //transparent body
|
||||
meat = /obj/item/weapon/shard
|
||||
armor = 0
|
||||
brutemod = 3 //very fragile
|
||||
burnmod = 0.25
|
||||
info_text = "As a <span class='danger'>Glass Golem</span>, you reflect lasers and energy weapons, and are very resistant to burn damage, but you are extremely vulnerable to brute damage. On death, you'll shatter beyond any hope of recovery."
|
||||
attack_sound = "sound/effects/Glassbr2.ogg"
|
||||
|
||||
/datum/species/golem/glass/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
playsound(H, "shatter", 70, 1)
|
||||
H.visible_message("<span class='danger'>[H] shatters!</span>")
|
||||
for(var/obj/item/W in H)
|
||||
H.dropItemToGround(W)
|
||||
for(var/i=1, i <= rand(3,5), i++)
|
||||
new /obj/item/weapon/shard(get_turf(H))
|
||||
qdel(H)
|
||||
|
||||
/datum/species/golem/glass/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
if(!(P.original == H && P.firer == H)) //self-shots don't reflect
|
||||
if(P.flag == "laser" || P.flag == "energy")
|
||||
H.visible_message("<span class='danger'>The [P.name] gets reflected by [H]'s glass skin!</span>", \
|
||||
"<span class='userdanger'>The [P.name] gets reflected by [H]'s glass skin!</span>")
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/turf/curloc = get_turf(H)
|
||||
|
||||
// redirect the projectile
|
||||
P.original = locate(new_x, new_y, P.z)
|
||||
P.starting = curloc
|
||||
P.current = curloc
|
||||
P.firer = H
|
||||
P.yo = new_y - curloc.y
|
||||
P.xo = new_x - curloc.x
|
||||
P.Angle = null
|
||||
return -1
|
||||
return 0
|
||||
|
||||
//Teleports when hit or when it wants to
|
||||
/datum/species/golem/bluespace
|
||||
name = "Bluespace Golem"
|
||||
id = "bluespace"
|
||||
fixed_mut_color = "33f"
|
||||
meat = /obj/item/weapon/ore/bluespace_crystal
|
||||
info_text = "As a <span class='danger'>Bluespace Golem</span>, are spatially unstable: you will teleport when hit, and you can teleport manually at a long distance."
|
||||
attack_verb = "bluespace punch"
|
||||
attack_sound = "sound/effects/phasein.ogg"
|
||||
|
||||
var/datum/action/innate/unstable_teleport/unstable_teleport
|
||||
var/teleport_cooldown = 100
|
||||
var/last_teleport = 0
|
||||
|
||||
/datum/species/golem/bluespace/proc/reactive_teleport(mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='warning'>[H] teleports!</span>", "<span class='danger'>You destabilize and teleport!</span>")
|
||||
new /obj/effect/particle_effect/sparks(get_turf(H))
|
||||
playsound(get_turf(H), "sparks", 50, 1)
|
||||
do_teleport(H, get_turf(H), 6, asoundin = 'sound/weapons/emitter2.ogg')
|
||||
last_teleport = world.time
|
||||
|
||||
/datum/species/golem/bluespace/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
|
||||
..()
|
||||
var/obj/item/I
|
||||
if(istype(AM, /obj/item))
|
||||
I = AM
|
||||
if(I.thrownby == H) //No throwing stuff at yourself to trigger the teleport
|
||||
return 0
|
||||
else
|
||||
reactive_teleport(H)
|
||||
|
||||
/datum/species/golem/bluespace/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
|
||||
..()
|
||||
if(world.time > last_teleport + teleport_cooldown && M != H && M.a_intent != INTENT_HELP)
|
||||
reactive_teleport(H)
|
||||
|
||||
/datum/species/golem/bluespace/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_teleport + teleport_cooldown && user != H)
|
||||
reactive_teleport(H)
|
||||
|
||||
/datum/species/golem/bluespace/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_teleport + teleport_cooldown)
|
||||
reactive_teleport(H)
|
||||
|
||||
/datum/species/golem/bluespace/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
if(ishuman(C))
|
||||
unstable_teleport = new
|
||||
unstable_teleport.Grant(C)
|
||||
|
||||
/datum/species/golem/bluespace/on_species_loss(mob/living/carbon/C)
|
||||
if(unstable_teleport)
|
||||
unstable_teleport.Remove(C)
|
||||
..()
|
||||
|
||||
/datum/action/innate/unstable_teleport
|
||||
name = "Unstable Teleport"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "jaunt"
|
||||
var/cooldown = 150
|
||||
var/last_teleport = 0
|
||||
|
||||
/datum/action/innate/unstable_teleport/IsAvailable()
|
||||
if(..())
|
||||
if(world.time > last_teleport + cooldown)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/innate/unstable_teleport/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
H.visible_message("<span class='warning'>[H] starts vibrating!</span>", "<span class='danger'>You start charging your bluespace core...</span>")
|
||||
playsound(get_turf(H), 'sound/weapons/flash.ogg', 25, 1)
|
||||
addtimer(CALLBACK(src, .proc/teleport, H), 15)
|
||||
|
||||
/datum/action/innate/unstable_teleport/proc/teleport(mob/living/carbon/human/H)
|
||||
H.visible_message("<span class='warning'>[H] disappears in a shower of sparks!</span>", "<span class='danger'>You teleport!</span>")
|
||||
var/datum/effect_system/spark_spread/spark_system = new /datum/effect_system/spark_spread
|
||||
spark_system.set_up(10, 0, src)
|
||||
spark_system.attach(H)
|
||||
spark_system.start()
|
||||
do_teleport(H, get_turf(H), 12, asoundin = 'sound/weapons/emitter2.ogg')
|
||||
last_teleport = world.time
|
||||
UpdateButtonIcon() //action icon looks unavailable
|
||||
sleep(cooldown + 5)
|
||||
UpdateButtonIcon() //action icon looks available again
|
||||
|
||||
|
||||
//honk
|
||||
/datum/species/golem/bananium
|
||||
name = "Bananium Golem"
|
||||
id = "bananium"
|
||||
fixed_mut_color = "ff0"
|
||||
say_mod = "honks"
|
||||
punchdamagelow = 0
|
||||
punchdamagehigh = 1
|
||||
punchstunthreshold = 2 //Harmless and can't stun
|
||||
meat = /obj/item/weapon/ore/bananium
|
||||
info_text = "As a <span class='danger'>Bananium Golem</span>, you are made for pranking. Your body emits natural honks, and you cannot hurt people when punching them. Your skin also emits bananas when damaged."
|
||||
attack_verb = "honk"
|
||||
attack_sound = "sound/items/AirHorn2.ogg"
|
||||
|
||||
var/last_honk = 0
|
||||
var/honkooldown = 0
|
||||
var/last_banana = 0
|
||||
var/banana_cooldown = 100
|
||||
var/active = null
|
||||
|
||||
/datum/species/golem/bananium/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style = M.martial_art)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown && M != H && M.a_intent != INTENT_HELP)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown && user != H)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
..()
|
||||
if(world.time > last_banana + banana_cooldown)
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
|
||||
..()
|
||||
var/obj/item/I
|
||||
if(istype(AM, /obj/item))
|
||||
I = AM
|
||||
if(I.thrownby == H) //No throwing stuff at yourself to make bananas
|
||||
return 0
|
||||
else
|
||||
new/obj/item/weapon/grown/bananapeel/specialpeel(get_turf(H))
|
||||
last_banana = world.time
|
||||
|
||||
/datum/species/golem/bananium/spec_life(mob/living/carbon/human/H)
|
||||
if(!active)
|
||||
if(world.time > last_honk + honkooldown)
|
||||
active = 1
|
||||
playsound(get_turf(H), 'sound/items/bikehorn.ogg', 50, 1)
|
||||
last_honk = world.time
|
||||
honkooldown = rand(20, 80)
|
||||
active = null
|
||||
..()
|
||||
|
||||
/datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0)
|
||||
|
||||
/datum/species/golem/bananium/get_spans()
|
||||
return list(SPAN_CLOWN)
|
||||
@@ -0,0 +1,25 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(MUTCOLORS_PARTSONLY,EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
mutant_bodyparts = list("tail_human", "ears")
|
||||
default_features = list("tail_human" = "None", "ears" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
if((!features["tail_human"] || features["tail_human"] == "None") && (!features["ears"] || features["ears"] == "None"))
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
return ..()
|
||||
|
||||
//Curiosity killed the cat's wagging tail.
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/datum/species/human/space_move(mob/living/carbon/human/H)
|
||||
var/obj/item/device/flightpack/F = H.get_flightpack()
|
||||
if(istype(F) && (F.flight) && F.allow_thrust(0.01, src))
|
||||
return TRUE
|
||||
@@ -0,0 +1,331 @@
|
||||
/datum/species/jelly
|
||||
// Entirely alien beings that seem to be made entirely out of gel. They have three eyes and a skeleton visible within them.
|
||||
name = "Xenobiological Jelly Entity"
|
||||
id = "jelly"
|
||||
default_color = "00FF90"
|
||||
say_mod = "chirps"
|
||||
eyes = "jelleyes"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,TOXINLOVER)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
exotic_blood = "slimejelly"
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
|
||||
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
|
||||
if(regenerate_limbs)
|
||||
regenerate_limbs.Remove(C)
|
||||
..()
|
||||
|
||||
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
if(ishuman(C))
|
||||
regenerate_limbs = new
|
||||
regenerate_limbs.Grant(C)
|
||||
|
||||
/datum/species/jelly/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely
|
||||
return
|
||||
if(!H.blood_volume)
|
||||
H.blood_volume += 5
|
||||
H.adjustBruteLoss(5)
|
||||
H << "<span class='danger'>You feel empty!</span>"
|
||||
|
||||
if(H.blood_volume < BLOOD_VOLUME_NORMAL)
|
||||
if(H.nutrition >= NUTRITION_LEVEL_STARVING)
|
||||
H.blood_volume += 3
|
||||
H.nutrition -= 2.5
|
||||
if(H.blood_volume < BLOOD_VOLUME_OKAY)
|
||||
if(prob(5))
|
||||
H << "<span class='danger'>You feel drained!</span>"
|
||||
if(H.blood_volume < BLOOD_VOLUME_BAD)
|
||||
Cannibalize_Body(H)
|
||||
H.update_action_buttons_icon()
|
||||
|
||||
/datum/species/jelly/proc/Cannibalize_Body(mob/living/carbon/human/H)
|
||||
var/list/limbs_to_consume = list("r_arm", "l_arm", "r_leg", "l_leg") - H.get_missing_limbs()
|
||||
var/obj/item/bodypart/consumed_limb
|
||||
if(!limbs_to_consume.len)
|
||||
H.losebreath++
|
||||
return
|
||||
if(H.get_num_legs()) //Legs go before arms
|
||||
limbs_to_consume -= list("r_arm", "l_arm")
|
||||
consumed_limb = H.get_bodypart(pick(limbs_to_consume))
|
||||
consumed_limb.drop_limb()
|
||||
H << "<span class='userdanger'>Your [consumed_limb] is drawn back into your body, unable to maintain its shape!</span>"
|
||||
qdel(consumed_limb)
|
||||
H.blood_volume += 20
|
||||
|
||||
/datum/action/innate/regenerate_limbs
|
||||
name = "Regenerate Limbs"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "slimeheal"
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
/datum/action/innate/regenerate_limbs/IsAvailable()
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
if(limbs_to_heal.len < 1)
|
||||
return 0
|
||||
if(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/innate/regenerate_limbs/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
var/list/limbs_to_heal = H.get_missing_limbs()
|
||||
if(limbs_to_heal.len < 1)
|
||||
H << "<span class='notice'>You feel intact enough as it is.</span>"
|
||||
return
|
||||
H << "<span class='notice'>You focus intently on your missing [limbs_to_heal.len >= 2 ? "limbs" : "limb"]...</span>"
|
||||
if(H.blood_volume >= 40*limbs_to_heal.len+BLOOD_VOLUME_OKAY)
|
||||
H.regenerate_limbs()
|
||||
H.blood_volume -= 40*limbs_to_heal.len
|
||||
H << "<span class='notice'>...and after a moment you finish reforming!</span>"
|
||||
return
|
||||
else if(H.blood_volume >= 40)//We can partially heal some limbs
|
||||
while(H.blood_volume >= BLOOD_VOLUME_OKAY+40)
|
||||
var/healed_limb = pick(limbs_to_heal)
|
||||
H.regenerate_limb(healed_limb)
|
||||
limbs_to_heal -= healed_limb
|
||||
H.blood_volume -= 40
|
||||
H << "<span class='warning'>...but there is not enough of you to fix everything! You must attain more mass to heal completely!</span>"
|
||||
return
|
||||
H << "<span class='warning'>...but there is not enough of you to go around! You must attain more mass to heal!</span>"
|
||||
|
||||
////////////////////////////////////////////////////////SLIME PEOPLE///////////////////////////////////////////////////////////////////
|
||||
|
||||
/datum/species/jelly/slime
|
||||
// Humans mutated by slime mutagen, produced from green slimes. They are not targetted by slimes.
|
||||
name = "Slimeperson"
|
||||
id = "slime"
|
||||
default_color = "00FFFF"
|
||||
darksight = 3
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE, TOXINLOVER)
|
||||
say_mod = "says"
|
||||
eyes = "eyes"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 150
|
||||
ignored_by = list(/mob/living/simple_animal/slime)
|
||||
burnmod = 0.5
|
||||
coldmod = 2
|
||||
heatmod = 0.5
|
||||
var/datum/action/innate/split_body/slime_split
|
||||
var/list/mob/living/carbon/bodies
|
||||
var/datum/action/innate/swap_body/swap_body
|
||||
|
||||
/datum/species/jelly/slime/on_species_loss(mob/living/carbon/C)
|
||||
if(slime_split)
|
||||
slime_split.Remove(C)
|
||||
if(swap_body)
|
||||
swap_body.Remove(C)
|
||||
bodies -= C // This means that the other bodies maintain a link
|
||||
// so if someone mindswapped into them, they'd still be shared.
|
||||
bodies = null
|
||||
C.faction -= "slime"
|
||||
C.blood_volume = min(C.blood_volume, BLOOD_VOLUME_NORMAL)
|
||||
..()
|
||||
|
||||
/datum/species/jelly/slime/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
..()
|
||||
if(ishuman(C))
|
||||
/* slime_split = new
|
||||
slime_split.Grant(C)
|
||||
swap_body = new
|
||||
swap_body.Grant(C) */
|
||||
|
||||
if(!bodies || !bodies.len)
|
||||
bodies = list(C)
|
||||
else
|
||||
bodies |= C
|
||||
|
||||
C.faction |= "slime"
|
||||
|
||||
/datum/species/jelly/slime/spec_life(mob/living/carbon/human/H)
|
||||
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
if(prob(5))
|
||||
H << "<span class='notice'>You feel very bloated!</span>"
|
||||
else if(H.nutrition >= NUTRITION_LEVEL_WELL_FED)
|
||||
H.blood_volume += 3
|
||||
H.nutrition -= 2.5
|
||||
|
||||
..()
|
||||
|
||||
/datum/action/innate/split_body
|
||||
name = "Split Body"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "slimesplit"
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
/datum/action/innate/split_body/IsAvailable()
|
||||
if(..())
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/datum/action/innate/split_body/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(!isslimeperson(H))
|
||||
return
|
||||
CHECK_DNA_AND_SPECIES(H)
|
||||
H.visible_message("<span class='notice'>[owner] gains a look of \
|
||||
concentration while standing perfectly still.</span>",
|
||||
"<span class='notice'>You focus intently on moving your body while \
|
||||
standing perfectly still...</span>")
|
||||
|
||||
H.notransform = TRUE
|
||||
|
||||
if(do_after(owner, delay=60, needhand=FALSE, target=owner, progress=TRUE))
|
||||
if(H.blood_volume >= BLOOD_VOLUME_SLIME_SPLIT)
|
||||
make_dupe()
|
||||
else
|
||||
H << "<span class='warning'>...but there is not enough of you to \
|
||||
go around! You must attain more mass to split!</span>"
|
||||
else
|
||||
H << "<span class='warning'>...but fail to stand perfectly still!\
|
||||
</span>"
|
||||
|
||||
H.notransform = FALSE
|
||||
|
||||
/datum/action/innate/split_body/proc/make_dupe()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
CHECK_DNA_AND_SPECIES(H)
|
||||
|
||||
var/mob/living/carbon/human/spare = new /mob/living/carbon/human(H.loc)
|
||||
|
||||
spare.underwear = "Nude"
|
||||
H.dna.transfer_identity(spare, transfer_SE=1)
|
||||
spare.dna.features["mcolor"] = pick("FFFFFF","7F7F7F", "7FFF7F", "7F7FFF", "FF7F7F", "7FFFFF", "FF7FFF", "FFFF7F")
|
||||
spare.real_name = spare.dna.real_name
|
||||
spare.name = spare.dna.real_name
|
||||
spare.updateappearance(mutcolor_update=1)
|
||||
spare.domutcheck()
|
||||
spare.Move(get_step(H.loc, pick(NORTH,SOUTH,EAST,WEST)))
|
||||
|
||||
H.blood_volume = BLOOD_VOLUME_SAFE
|
||||
H.notransform = 0
|
||||
|
||||
var/datum/species/jelly/slime/origin_datum = H.dna.species
|
||||
origin_datum.bodies |= spare
|
||||
|
||||
var/datum/species/jelly/slime/spare_datum = spare.dna.species
|
||||
spare_datum.bodies = origin_datum.bodies
|
||||
|
||||
H.mind.transfer_to(spare)
|
||||
spare.visible_message("<span class='warning'>[H] distorts as a new body \
|
||||
\"steps out\" of them.</span>",
|
||||
"<span class='notice'>...and after a moment of disorentation, \
|
||||
you're besides yourself!</span>")
|
||||
|
||||
|
||||
/datum/action/innate/swap_body
|
||||
name = "Swap Body"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
button_icon_state = "slimeswap"
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
/datum/action/innate/swap_body/Activate()
|
||||
if(!isslimeperson(owner))
|
||||
owner << "<span class='warning'>You are not a slimeperson.</span>"
|
||||
Remove(owner)
|
||||
else
|
||||
ui_interact(owner)
|
||||
|
||||
/datum/action/innate/swap_body/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = conscious_state)
|
||||
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "slime_swap_body", name, 400, 400, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/datum/action/innate/swap_body/ui_data(mob/user)
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(!isslimeperson(H))
|
||||
return
|
||||
|
||||
var/datum/species/jelly/slime/SS = H.dna.species
|
||||
|
||||
var/list/data = list()
|
||||
data["bodies"] = list()
|
||||
for(var/b in SS.bodies)
|
||||
if(!b || qdeleted(b) || !isslimeperson(b))
|
||||
SS.bodies -= b
|
||||
continue
|
||||
var/mob/living/carbon/human/body = b
|
||||
|
||||
var/list/L = list()
|
||||
// HTML colors need a # prefix
|
||||
L["htmlcolor"] = "#[body.dna.features["mcolor"]]"
|
||||
var/area/A = get_area(body)
|
||||
L["area"] = A.name
|
||||
var/stat = "error"
|
||||
switch(body.stat)
|
||||
if(CONSCIOUS)
|
||||
stat = "Conscious"
|
||||
if(UNCONSCIOUS)
|
||||
stat = "Unconscious"
|
||||
if(DEAD)
|
||||
stat = "Dead"
|
||||
var/current = body.mind
|
||||
var/is_conscious = (body.stat == CONSCIOUS)
|
||||
|
||||
L["status"] = stat
|
||||
L["exoticblood"] = body.blood_volume
|
||||
L["name"] = body.name
|
||||
L["ref"] = "\ref[body]"
|
||||
L["is_current"] = current
|
||||
var/button
|
||||
if(current)
|
||||
button = "selected"
|
||||
else if(is_conscious)
|
||||
button = null
|
||||
else
|
||||
button = "disabled"
|
||||
|
||||
L["swap_button_state"] = button
|
||||
L["swappable"] = !current && is_conscious
|
||||
|
||||
data["bodies"] += list(L)
|
||||
|
||||
return data
|
||||
|
||||
/datum/action/innate/swap_body/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(!isslimeperson(owner))
|
||||
return
|
||||
var/datum/species/jelly/slime/SS = H.dna.species
|
||||
|
||||
var/datum/mind/M
|
||||
for(var/mob/living/L in SS.bodies)
|
||||
if(L.mind && L.mind.active)
|
||||
M = L.mind
|
||||
if(!M)
|
||||
return
|
||||
if(!isslimeperson(M.current))
|
||||
return
|
||||
|
||||
switch(action)
|
||||
if("swap")
|
||||
var/mob/living/carbon/human/selected = locate(params["ref"])
|
||||
if(!(selected in SS.bodies))
|
||||
return
|
||||
if(!selected || qdeleted(selected) || !isslimeperson(selected))
|
||||
SS.bodies -= selected
|
||||
return
|
||||
if(M.current == selected)
|
||||
return
|
||||
if(selected.stat != CONSCIOUS)
|
||||
return
|
||||
|
||||
swap_to_dupe(M, selected)
|
||||
|
||||
/datum/action/innate/swap_body/proc/swap_to_dupe(datum/mind/M, mob/living/carbon/human/dupe)
|
||||
M.current.visible_message("<span class='notice'>[M.current] \
|
||||
stops moving and starts staring vacantly into space.</span>",
|
||||
"<span class='notice'>You stop moving this body...</span>")
|
||||
M.transfer_to(dupe)
|
||||
dupe.visible_message("<span class='notice'>[dupe] blinks and looks \
|
||||
around.</span>",
|
||||
"<span class='notice'>...and move this one instead.</span>")
|
||||
@@ -0,0 +1,41 @@
|
||||
/datum/species/lizard
|
||||
// Reptilian humanoids with scaled skin and tails.
|
||||
name = "Lizardperson"
|
||||
id = "lizard"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,FACEHAIR)
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs")
|
||||
mutant_organs = list(/obj/item/organ/tongue/lizard)
|
||||
default_features = list("mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0", "tail" = "Smooth", "snout" = "Round", "horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None", "legs" = "Normal Legs")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/lizard
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/lizard
|
||||
exotic_bloodtype = "L"
|
||||
|
||||
/datum/species/lizard/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
return random_unique_lizard_name(gender)
|
||||
|
||||
var/randname = lizard_name(gender)
|
||||
|
||||
if(lastname)
|
||||
randname += " [lastname]"
|
||||
|
||||
return randname
|
||||
|
||||
//I wag in death
|
||||
/datum/species/lizard/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
H.endTailWag()
|
||||
|
||||
/*
|
||||
Lizard subspecies: ASHWALKERS
|
||||
*/
|
||||
/datum/species/lizard/ashwalker
|
||||
name = "Ash Walker"
|
||||
id = "ashlizard"
|
||||
limbs_id = "lizard"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,NOBREATH,NOGUNS,DIGITIGRADE)
|
||||
@@ -0,0 +1,70 @@
|
||||
var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_state"="plasmaman")
|
||||
|
||||
/datum/species/plasmaman
|
||||
name = "Plasmaman"
|
||||
id = "plasmaman"
|
||||
say_mod = "rattles"
|
||||
sexes = 0
|
||||
meat = /obj/item/stack/sheet/mineral/plasma
|
||||
species_traits = list(NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,VIRUSIMMUNE,NOHUNGER)
|
||||
mutantlungs = /obj/item/organ/lungs/plasmaman
|
||||
dangerous_existence = 1 //So so much
|
||||
blacklisted = 1 //See above
|
||||
burnmod = 2
|
||||
heatmod = 2
|
||||
breathid = "tox"
|
||||
speedmod = 1
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much
|
||||
|
||||
/datum/species/plasmaman/spec_life(mob/living/carbon/human/H)
|
||||
var/datum/gas_mixture/environment = H.loc.return_air()
|
||||
var/atmos_sealed = (H.wear_suit && (H.wear_suit.flags & STOPSPRESSUREDMAGE)) && (H.head && (H.head.flags & STOPSPRESSUREDMAGE))
|
||||
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
|
||||
if(environment)
|
||||
if(environment.total_moles())
|
||||
if(environment.gases["o2"] && (environment.gases["o2"][MOLES]) >= 1) //Same threshhold that extinguishes fire
|
||||
H.adjust_fire_stacks(0.5)
|
||||
if(!H.on_fire && H.fire_stacks > 0)
|
||||
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
|
||||
H.IgniteMob()
|
||||
internal_fire = TRUE
|
||||
else
|
||||
if(H.fire_stacks)
|
||||
var/obj/item/clothing/under/plasmaman/P = H.w_uniform
|
||||
if(istype(P))
|
||||
P.Extinguish(H)
|
||||
internal_fire = FALSE
|
||||
else
|
||||
internal_fire = FALSE
|
||||
H.update_fire()
|
||||
|
||||
/datum/species/plasmaman/handle_fire(mob/living/carbon/human/H, no_protection)
|
||||
if(internal_fire)
|
||||
no_protection = TRUE
|
||||
..()
|
||||
|
||||
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
|
||||
H.equipOutfit(O, visualsOnly)
|
||||
H.internal = H.get_item_for_held_index(2)
|
||||
H.update_internals_hud_icon(1)
|
||||
return 0
|
||||
|
||||
/datum/species/plasmaman/qualifies_for_rank(rank, list/features)
|
||||
if(rank in security_positions)
|
||||
return 0
|
||||
if(rank == "Clown" || rank == "Mime")//No funny bussiness
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/species/plasmaman/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
return random_unique_plasmaman_name()
|
||||
|
||||
var/randname = plasmaman_name()
|
||||
|
||||
if(lastname)
|
||||
randname += " [lastname]"
|
||||
|
||||
return randname
|
||||
@@ -0,0 +1,64 @@
|
||||
/datum/species/pod
|
||||
// A mutation caused by a human being ressurected in a revival pod. These regain health in light, and begin to wither in darkness.
|
||||
name = "Podperson"
|
||||
id = "pod"
|
||||
default_color = "59CE00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR)
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slice.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
burnmod = 1.25
|
||||
heatmod = 1.5
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/plant
|
||||
|
||||
/datum/species/pod/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
C.faction |= "plants"
|
||||
C.faction |= "vines"
|
||||
|
||||
/datum/species/pod/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.faction -= "plants"
|
||||
C.faction -= "vines"
|
||||
|
||||
/datum/species/pod/spec_life(mob/living/carbon/human/H)
|
||||
if(H.stat == DEAD)
|
||||
return
|
||||
var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing
|
||||
if(isturf(H.loc)) //else, there's considered to be no light
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(10,T.get_lumcount()) - 5
|
||||
H.nutrition += light_amount
|
||||
if(H.nutrition > NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL
|
||||
if(light_amount > 2) //if there's enough light, heal
|
||||
H.heal_overall_damage(1,1)
|
||||
H.adjustToxLoss(-1)
|
||||
H.adjustOxyLoss(-1)
|
||||
|
||||
if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
|
||||
H.take_overall_damage(2,0)
|
||||
|
||||
/datum/species/pod/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "plantbgone")
|
||||
H.adjustToxLoss(3)
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
|
||||
/datum/species/pod/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
|
||||
switch(P.type)
|
||||
if(/obj/item/projectile/energy/floramut)
|
||||
if(prob(15))
|
||||
H.rad_act(rand(30,80))
|
||||
H.Weaken(5)
|
||||
H.visible_message("<span class='warning'>[H] writhes in pain as [H.p_their()] vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
|
||||
if(prob(80))
|
||||
H.randmutb()
|
||||
else
|
||||
H.randmutg()
|
||||
H.domutcheck()
|
||||
else
|
||||
H.adjustFireLoss(rand(5,15))
|
||||
H.show_message("<span class='userdanger'>The radiation beam singes you!</span>")
|
||||
if(/obj/item/projectile/energy/florayield)
|
||||
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
|
||||
@@ -0,0 +1,51 @@
|
||||
/datum/species/shadow
|
||||
// Humans cursed to stay in the darkness, lest their life forces drain. They regain health in shadow and die in light.
|
||||
name = "???"
|
||||
id = "shadow"
|
||||
darksight = 8
|
||||
invis_sight = SEE_INVISIBLE_MINIMUM
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
species_traits = list(NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE)
|
||||
dangerous_existence = 1
|
||||
var/datum/action/innate/shadow/darkvision/vision_toggle
|
||||
|
||||
/datum/action/innate/shadow/darkvision //Darkvision toggle so shadowpeople can actually see where darkness is
|
||||
name = "Toggle Darkvision"
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
background_icon_state = "bg_default"
|
||||
button_icon_state = "blind"
|
||||
|
||||
/datum/action/innate/shadow/darkvision/Activate()
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.see_in_dark < 8)
|
||||
H.see_in_dark = 8
|
||||
H.see_invisible = SEE_INVISIBLE_MINIMUM
|
||||
H << "<span class='notice'>You adjust your vision to pierce the darkness.</span>"
|
||||
else
|
||||
H.see_in_dark = 2
|
||||
H.see_invisible = SEE_INVISIBLE_LIVING
|
||||
H << "<span class='notice'>You adjust your vision to recognize the shadows.</span>"
|
||||
|
||||
/datum/species/shadow/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
vision_toggle = new
|
||||
vision_toggle.Grant(C)
|
||||
|
||||
/datum/species/shadow/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
if(vision_toggle)
|
||||
vision_toggle.Remove(C)
|
||||
|
||||
/datum/species/shadow/spec_life(mob/living/carbon/human/H)
|
||||
var/light_amount = 0
|
||||
if(isturf(H.loc))
|
||||
var/turf/T = H.loc
|
||||
light_amount = T.get_lumcount()
|
||||
|
||||
if(light_amount > 2) //if there's enough light, start dying
|
||||
H.take_overall_damage(1,1)
|
||||
else if (light_amount < 2) //heal in the dark
|
||||
H.heal_overall_damage(1,1)
|
||||
@@ -0,0 +1,11 @@
|
||||
/datum/species/skeleton
|
||||
// 2spooky
|
||||
name = "Spooky Scary Skeleton"
|
||||
id = "skeleton"
|
||||
say_mod = "rattles"
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutant_organs = list(/obj/item/organ/tongue/bone)
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
@@ -0,0 +1,121 @@
|
||||
/datum/species/synth
|
||||
name = "Synth" //inherited from the real species, for health scanners and things
|
||||
id = "synth"
|
||||
say_mod = "beep boops" //inherited from a user's real species
|
||||
sexes = 0
|
||||
species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
|
||||
dangerous_existence = 1
|
||||
blacklisted = 1
|
||||
meat = null
|
||||
damage_overlay_type = "synth"
|
||||
limbs_id = "synth"
|
||||
var/list/initial_species_traits = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //for getting these values back for assume_disguise()
|
||||
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
|
||||
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
|
||||
|
||||
/datum/species/synth/military
|
||||
name = "Military Synth"
|
||||
id = "military_synth"
|
||||
armor = 25
|
||||
punchdamagelow = 10
|
||||
punchdamagehigh = 19
|
||||
punchstunthreshold = 14 //about 50% chance to stun
|
||||
disguise_fail_health = 50
|
||||
|
||||
/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
..()
|
||||
assume_disguise(old_species, H)
|
||||
|
||||
/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "synthflesh")
|
||||
chem.reaction_mob(H, TOUCH, 2 ,0) //heal a little
|
||||
H.reagents.remove_reagent(chem.id, REAGENTS_METABOLISM)
|
||||
return 1
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/species/synth/proc/assume_disguise(datum/species/S, mob/living/carbon/human/H)
|
||||
if(S && !istype(S, type))
|
||||
name = S.name
|
||||
say_mod = S.say_mod
|
||||
sexes = S.sexes
|
||||
species_traits = initial_species_traits.Copy()
|
||||
species_traits.Add(S.species_traits)
|
||||
attack_verb = S.attack_verb
|
||||
attack_sound = S.attack_sound
|
||||
miss_sound = S.miss_sound
|
||||
meat = S.meat
|
||||
mutant_bodyparts = S.mutant_bodyparts.Copy()
|
||||
mutant_organs = S.mutant_organs.Copy()
|
||||
default_features = S.default_features.Copy()
|
||||
nojumpsuit = S.nojumpsuit
|
||||
no_equip = S.no_equip.Copy()
|
||||
limbs_id = S.limbs_id
|
||||
use_skintones = S.use_skintones
|
||||
fixed_mut_color = S.fixed_mut_color
|
||||
hair_color = S.hair_color
|
||||
fake_species = new S.type
|
||||
else
|
||||
name = initial(name)
|
||||
say_mod = initial(say_mod)
|
||||
species_traits = initial_species_traits.Copy()
|
||||
attack_verb = initial(attack_verb)
|
||||
attack_sound = initial(attack_sound)
|
||||
miss_sound = initial(miss_sound)
|
||||
mutant_bodyparts = list()
|
||||
default_features = list()
|
||||
nojumpsuit = initial(nojumpsuit)
|
||||
no_equip = list()
|
||||
qdel(fake_species)
|
||||
fake_species = null
|
||||
meat = initial(meat)
|
||||
limbs_id = "synth"
|
||||
use_skintones = 0
|
||||
sexes = 0
|
||||
fixed_mut_color = ""
|
||||
hair_color = ""
|
||||
|
||||
for(var/X in H.bodyparts) //propagates the damage_overlay changes
|
||||
var/obj/item/bodypart/BP = X
|
||||
BP.update_limb()
|
||||
H.update_body_parts() //to update limb icon cache with the new damage overlays
|
||||
|
||||
//Proc redirects:
|
||||
//Passing procs onto the fake_species, to ensure we look as much like them as possible
|
||||
|
||||
/datum/species/synth/handle_hair(mob/living/carbon/human/H, forced_colour)
|
||||
if(fake_species)
|
||||
fake_species.handle_hair(H, forced_colour)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/species/synth/handle_body(mob/living/carbon/human/H)
|
||||
if(fake_species)
|
||||
fake_species.handle_body(H)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/species/synth/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour)
|
||||
if(fake_species)
|
||||
fake_species.handle_body(H,forced_colour)
|
||||
else
|
||||
return ..()
|
||||
|
||||
|
||||
/datum/species/synth/get_spans()
|
||||
if(fake_species)
|
||||
return fake_species.get_spans()
|
||||
return list()
|
||||
|
||||
|
||||
/datum/species/synth/handle_speech(message, mob/living/carbon/human/H)
|
||||
if(H.health > disguise_fail_health)
|
||||
if(fake_species)
|
||||
return fake_species.handle_speech(message,H)
|
||||
else
|
||||
return ..()
|
||||
else
|
||||
return ..()
|
||||
@@ -0,0 +1,62 @@
|
||||
/datum/species/zombie
|
||||
// 1spooky
|
||||
name = "High Functioning Zombie"
|
||||
id = "zombie"
|
||||
say_mod = "moans"
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
|
||||
/datum/species/zombie/infectious
|
||||
name = "Infectious Zombie"
|
||||
id = "memezombies"
|
||||
limbs_id = "zombie"
|
||||
no_equip = list(slot_wear_mask, slot_head)
|
||||
armor = 20 // 120 damage to KO a zombie, which kills it
|
||||
speedmod = 2
|
||||
|
||||
/datum/species/zombie/infectious/spec_life(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
|
||||
if(C.InCritical())
|
||||
C.death()
|
||||
// Zombies only move around when not in crit, they instantly
|
||||
// succumb otherwise, and will standup again soon
|
||||
|
||||
/datum/species/zombie/infectious/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
// Drop items in hands
|
||||
// If you're a zombie lucky enough to have a NODROP item, then it stays.
|
||||
for(var/V in C.held_items)
|
||||
var/obj/item/I = V
|
||||
if(istype(I))
|
||||
if(C.dropItemToGround(I))
|
||||
var/obj/item/zombie_hand/zh = new /obj/item/zombie_hand()
|
||||
C.put_in_hands(zh)
|
||||
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
|
||||
var/obj/item/zombie_hand/zh = new /obj/item/zombie_hand()
|
||||
C.put_in_hands(zh)
|
||||
|
||||
// Next, deal with the source of this zombie corruption
|
||||
var/obj/item/organ/zombie_infection/infection
|
||||
infection = C.getorganslot("zombie_infection")
|
||||
if(!infection)
|
||||
infection = new(C)
|
||||
|
||||
/datum/species/zombie/infectious/on_species_loss(mob/living/carbon/C)
|
||||
. = ..()
|
||||
for(var/obj/item/I in C.held_items)
|
||||
if(istype(I, /obj/item/zombie_hand))
|
||||
qdel(I)
|
||||
|
||||
|
||||
// Your skin falls off
|
||||
/datum/species/krokodil_addict
|
||||
name = "Human"
|
||||
id = "goofzombies"
|
||||
limbs_id = "zombie" //They look like zombies
|
||||
sexes = 0
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
mutant_organs = list(/obj/item/organ/tongue/zombie)
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
/mob/living/carbon/human/Stun(amount, updating = 1, ignore_canstun = 0)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/Weaken(amount, updating = 1, ignore_canstun = 0)
|
||||
amount = dna.species.spec_stun(src,amount)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/cure_husk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
|
||||
/mob/living/carbon/human/become_husk()
|
||||
. = ..()
|
||||
if(.)
|
||||
update_hair()
|
||||
@@ -4,8 +4,10 @@
|
||||
/* Keep these comments up-to-date if you -insist- on hurting my code-baby ;_;
|
||||
This system allows you to update individual mob-overlays, without regenerating them all each time.
|
||||
When we generate overlays we generate the standing version and then rotate the mob as necessary..
|
||||
|
||||
As of the time of writing there are 20 layers within this list. Please try to keep this from increasing. //22 and counting, good job guys
|
||||
var/overlays_standing[20] //For the standing stance
|
||||
|
||||
Most of the time we only wish to update one overlay:
|
||||
e.g. - we dropped the fireaxe out of our left hand and need to remove its icon from our mob
|
||||
e.g.2 - our hair colour has changed, so we need to update our hair icons on our mob
|
||||
@@ -13,21 +15,28 @@ In these cases, instead of updating every overlay using the old behaviour (regen
|
||||
the appropriate update_X proc.
|
||||
e.g. - update_l_hand()
|
||||
e.g.2 - update_hair()
|
||||
|
||||
Note: Recent changes by aranclanos+carn:
|
||||
update_icons() no longer needs to be called.
|
||||
the system is easier to use. update_icons() should not be called unless you absolutely -know- you need it.
|
||||
IN ALL OTHER CASES it's better to just call the specific update_X procs.
|
||||
|
||||
Note: The defines for layer numbers is now kept exclusvely in __DEFINES/misc.dm instead of being defined there,
|
||||
then redefined and undefiend everywhere else. If you need to change the layering of sprites (or add a new layer)
|
||||
that's where you should start.
|
||||
|
||||
All of this means that this code is more maintainable, faster and still fairly easy to use.
|
||||
|
||||
There are several things that need to be remembered:
|
||||
> Whenever we do something that should cause an overlay to update (which doesn't use standard procs
|
||||
( i.e. you do something like l_hand = /obj/item/something new(src), rather than using the helper procs)
|
||||
You will need to call the relevant update_inv_* proc
|
||||
|
||||
All of these are named after the variable they update from. They are defined at the mob/ level like
|
||||
update_clothing was, so you won't cause undefined proc runtimes with usr.update_inv_wear_id() if the usr is a
|
||||
slime etc. Instead, it'll just return without doing any work. So no harm in calling it for slimes and such.
|
||||
|
||||
|
||||
> There are also these special cases:
|
||||
update_damage_overlays() //handles damage overlays for brute/burn damage
|
||||
update_body() //Handles updating your mob's body layer and mutant bodyparts
|
||||
@@ -35,30 +44,10 @@ There are several things that need to be remembered:
|
||||
//NOTE: update_mutantrace() is now merged into this!
|
||||
update_hair() //Handles updating your hair overlay (used to be update_face, but mouth and
|
||||
eyes were merged into update_body())
|
||||
|
||||
|
||||
*/
|
||||
|
||||
//DAMAGE OVERLAYS
|
||||
//constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists
|
||||
/mob/living/carbon/human/update_damage_overlays()
|
||||
remove_overlay(DAMAGE_LAYER)
|
||||
|
||||
var/image/standing = image("icon"='icons/mob/dam_human.dmi', "icon_state"="blank", "layer"=-DAMAGE_LAYER)
|
||||
overlays_standing[DAMAGE_LAYER] = standing
|
||||
|
||||
var/dmgoverlaytype = ""
|
||||
if(dna.species.exotic_damage_overlay)
|
||||
dmgoverlaytype = dna.species.exotic_damage_overlay + "_"
|
||||
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(BP.brutestate)
|
||||
standing.overlays += "[dmgoverlaytype][BP.body_zone]_[BP.brutestate]0" //we're adding icon_states of the base image as overlays
|
||||
if(BP.burnstate)
|
||||
standing.overlays += "[dmgoverlaytype][BP.body_zone]_0[BP.burnstate]"
|
||||
|
||||
apply_overlay(DAMAGE_LAYER)
|
||||
|
||||
|
||||
//HAIR OVERLAY
|
||||
/mob/living/carbon/human/update_hair()
|
||||
dna.species.handle_hair(src)
|
||||
@@ -68,47 +57,14 @@ There are several things that need to be remembered:
|
||||
dna.species.handle_mutant_bodyparts(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_body()
|
||||
/mob/living/carbon/human/update_body()
|
||||
remove_overlay(BODY_LAYER)
|
||||
dna.species.handle_body(src)
|
||||
update_body_parts()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/update_fire()
|
||||
..("Standing")
|
||||
|
||||
/mob/living/carbon/human/proc/update_body_parts()
|
||||
//CHECK FOR UPDATE
|
||||
var/oldkey = icon_render_key
|
||||
icon_render_key = generate_icon_render_key()
|
||||
if(oldkey == icon_render_key)
|
||||
return
|
||||
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
|
||||
//LOAD ICONS
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
load_limb_from_cache()
|
||||
update_damage_overlays()
|
||||
update_mutant_bodyparts()
|
||||
update_hair()
|
||||
return
|
||||
|
||||
//GENERATE NEW LIMBS
|
||||
var/list/new_limbs = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(!BP.no_update)
|
||||
BP.update_limb()
|
||||
var/image/temp = BP.get_limb_icon()
|
||||
if(temp)
|
||||
new_limbs += temp
|
||||
if(new_limbs.len)
|
||||
overlays_standing[BODYPARTS_LAYER] = new_limbs
|
||||
limb_icon_cache[icon_render_key] = new_limbs
|
||||
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
update_damage_overlays()
|
||||
|
||||
|
||||
/* --------------------------------------- */
|
||||
//For legacy support.
|
||||
@@ -130,6 +86,7 @@ There are several things that need to be remembered:
|
||||
update_inv_back()
|
||||
update_inv_wear_suit()
|
||||
update_inv_pockets()
|
||||
update_inv_neck()
|
||||
update_transform()
|
||||
//mutations
|
||||
update_mutations_overlay()
|
||||
@@ -148,10 +105,11 @@ There are several things that need to be remembered:
|
||||
|
||||
if(istype(w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = w_uniform
|
||||
U.screen_loc = ui_iclothing
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
U.screen_loc = ui_iclothing //...draw the item in the inventory screen
|
||||
client.screen += w_uniform //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += w_uniform
|
||||
update_observer_view(w_uniform,1)
|
||||
|
||||
if(wear_suit && (wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
return
|
||||
@@ -160,27 +118,30 @@ There are several things that need to be remembered:
|
||||
var/t_color = U.item_color
|
||||
if(!t_color)
|
||||
t_color = U.icon_state
|
||||
if(U.adjusted)
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
else if(U.adjusted == DIGITIGRADE_STYLE)
|
||||
t_color = "[t_color]_l"
|
||||
|
||||
var/image/standing
|
||||
|
||||
if(dna && dna.species.sexes)
|
||||
var/G = (gender == FEMALE) ? "f" : "m"
|
||||
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
|
||||
standing = U.build_worn_icon(state = "[t_color]_s", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE, femaleuniform = U.fitted)
|
||||
standing = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE, femaleuniform = U.fitted)
|
||||
|
||||
if(!standing)
|
||||
standing = U.build_worn_icon(state = "[t_color]_s", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE)
|
||||
standing = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = 'icons/mob/uniform.dmi', isinhands = FALSE)
|
||||
|
||||
overlays_standing[UNIFORM_LAYER] = standing
|
||||
|
||||
else
|
||||
else if(!(dna && dna.species.nojumpsuit))
|
||||
// Automatically drop anything in store / id / belt if you're not wearing a uniform. //CHECK IF NECESARRY
|
||||
for(var/obj/item/thing in list(r_store, l_store, wear_id, belt)) //
|
||||
unEquip(thing)
|
||||
for(var/obj/item/thing in list(r_store, l_store, wear_id, belt))
|
||||
dropItemToGround(thing)
|
||||
|
||||
apply_overlay(UNIFORM_LAYER)
|
||||
update_mutant_bodyparts()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_id()
|
||||
@@ -191,9 +152,10 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_id)
|
||||
wear_id.screen_loc = ui_id
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
wear_id.screen_loc = ui_id
|
||||
client.screen += wear_id
|
||||
update_observer_view(wear_id)
|
||||
|
||||
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
|
||||
var/image/standing = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi')
|
||||
@@ -206,18 +168,25 @@ There are several things that need to be remembered:
|
||||
remove_overlay(GLOVES_LAYER)
|
||||
|
||||
if(get_num_arms() <2)
|
||||
if(!gloves && blood_DNA)
|
||||
if(has_left_hand())
|
||||
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_left", "layer"=-GLOVES_LAYER)
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
else if(has_right_hand())
|
||||
overlays_standing[GLOVES_LAYER] = image("icon"='icons/effects/blood.dmi', "icon_state"="bloodyhands_right", "layer"=-GLOVES_LAYER)
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
return
|
||||
|
||||
if(client && hud_used)
|
||||
if(client && hud_used && hud_used.inv_slots[slot_gloves])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_gloves]
|
||||
inv.update_icon()
|
||||
|
||||
if(gloves)
|
||||
gloves.screen_loc = ui_gloves
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
gloves.screen_loc = ui_gloves //...draw the item in the inventory screen
|
||||
client.screen += gloves //Either way, add the item to the HUD
|
||||
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += gloves
|
||||
update_observer_view(gloves,1)
|
||||
var/t_state = gloves.item_state
|
||||
if(!t_state)
|
||||
t_state = gloves.icon_state
|
||||
@@ -233,7 +202,6 @@ There are several things that need to be remembered:
|
||||
apply_overlay(GLOVES_LAYER)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_glasses()
|
||||
remove_overlay(GLASSES_LAYER)
|
||||
|
||||
@@ -245,11 +213,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(glasses)
|
||||
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
glasses.screen_loc = ui_glasses //...draw the item in the inventory screen
|
||||
client.screen += glasses //Either way, add the item to the HUD
|
||||
|
||||
client.screen += glasses //Either way, add the item to the HUD
|
||||
update_observer_view(glasses,1)
|
||||
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
|
||||
|
||||
var/image/standing = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
|
||||
@@ -269,10 +237,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(ears)
|
||||
ears.screen_loc = ui_ears //move the item to the appropriate screen loc
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
ears.screen_loc = ui_ears //...draw the item in the inventory screen
|
||||
client.screen += ears //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown) //if the inventory is open
|
||||
client.screen += ears //add it to the client's screen
|
||||
update_observer_view(ears,1)
|
||||
|
||||
var/image/standing = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
|
||||
overlays_standing[EARS_LAYER] = standing
|
||||
@@ -291,11 +260,11 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(shoes)
|
||||
shoes.screen_loc = ui_shoes //move the item to the appropriate screen loc
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
shoes.screen_loc = ui_shoes //...draw the item in the inventory screen
|
||||
client.screen += shoes //Either way, add the item to the HUD
|
||||
|
||||
if(hud_used.inventory_shown) //if the inventory is open
|
||||
client.screen += shoes //add it to client's screen
|
||||
update_observer_view(shoes,1)
|
||||
var/image/standing = shoes.build_worn_icon(state = shoes.icon_state, default_layer = SHOES_LAYER, default_icon_file = 'icons/mob/feet.dmi')
|
||||
overlays_standing[SHOES_LAYER] = standing
|
||||
|
||||
@@ -310,10 +279,10 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(s_store)
|
||||
s_store.screen_loc = ui_sstore1
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
s_store.screen_loc = ui_sstore1
|
||||
client.screen += s_store
|
||||
|
||||
update_observer_view(s_store)
|
||||
var/t_state = s_store.item_state
|
||||
if(!t_state)
|
||||
t_state = s_store.icon_state
|
||||
@@ -322,19 +291,10 @@ There are several things that need to be remembered:
|
||||
apply_overlay(SUIT_STORE_LAYER)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_head()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
..()
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_head]
|
||||
inv.update_icon()
|
||||
|
||||
update_mutant_bodyparts()
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_belt()
|
||||
remove_overlay(BELT_LAYER)
|
||||
|
||||
@@ -342,11 +302,12 @@ There are several things that need to be remembered:
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_belt]
|
||||
inv.update_icon()
|
||||
|
||||
if(hud_used.hud_shown && belt)
|
||||
client.screen += belt
|
||||
belt.screen_loc = ui_belt
|
||||
|
||||
if(belt)
|
||||
belt.screen_loc = ui_belt
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
client.screen += belt
|
||||
update_observer_view(belt)
|
||||
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state)
|
||||
t_state = belt.icon_state
|
||||
@@ -367,17 +328,17 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(istype(wear_suit, /obj/item/clothing/suit))
|
||||
wear_suit.screen_loc = ui_oclothing
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown) //if the inventory is open ...
|
||||
wear_suit.screen_loc = ui_oclothing //TODO //...draw the item in the inventory screen
|
||||
client.screen += wear_suit //Either way, add the item to the HUD
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += wear_suit
|
||||
update_observer_view(wear_suit,1)
|
||||
|
||||
var/image/standing = wear_suit.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = 'icons/mob/suit.dmi')
|
||||
overlays_standing[SUIT_LAYER] = standing
|
||||
|
||||
if(istype(wear_suit, /obj/item/clothing/suit/straight_jacket))
|
||||
drop_l_hand()
|
||||
drop_r_hand()
|
||||
if(wear_suit.breakouttime) //suit is restraining
|
||||
drop_all_held_items()
|
||||
|
||||
update_hair()
|
||||
update_mutant_bodyparts()
|
||||
@@ -395,31 +356,23 @@ There are several things that need to be remembered:
|
||||
inv = hud_used.inv_slots[slot_r_store]
|
||||
inv.update_icon()
|
||||
|
||||
if(hud_used.hud_shown)
|
||||
if(l_store)
|
||||
if(l_store)
|
||||
l_store.screen_loc = ui_storage1
|
||||
if(hud_used.hud_shown)
|
||||
client.screen += l_store
|
||||
l_store.screen_loc = ui_storage1
|
||||
update_observer_view(l_store)
|
||||
|
||||
if(r_store)
|
||||
if(r_store)
|
||||
r_store.screen_loc = ui_storage2
|
||||
if(hud_used.hud_shown)
|
||||
client.screen += r_store
|
||||
r_store.screen_loc = ui_storage2
|
||||
update_observer_view(r_store)
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_mask()
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
if(!get_bodypart("head")) //Decapitated
|
||||
return
|
||||
..()
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[slot_wear_mask]
|
||||
inv.update_icon()
|
||||
update_mutant_bodyparts()
|
||||
update_mutant_bodyparts() //e.g. upgate needed because mask now hides lizard snout
|
||||
|
||||
/mob/living/carbon/human/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
/mob/living/carbon/human/update_inv_legcuffed()
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
@@ -439,7 +392,7 @@ There are several things that need to be remembered:
|
||||
|
||||
/mob/living/carbon/human/proc/get_overlays_copy(list/unwantedLayers)
|
||||
var/list/out = new
|
||||
for(var/i=1;i<=TOTAL_LAYERS;i++)
|
||||
for(var/i in 1 to TOTAL_LAYERS)
|
||||
if(overlays_standing[i])
|
||||
if(i in unwantedLayers)
|
||||
continue
|
||||
@@ -451,23 +404,36 @@ There are several things that need to be remembered:
|
||||
|
||||
//update whether our head item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_head(obj/item/I)
|
||||
I.screen_loc = ui_head
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
I.screen_loc = ui_head
|
||||
client.screen += I
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our mask item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_wear_mask(obj/item/I)
|
||||
I.screen_loc = ui_mask
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
I.screen_loc = ui_mask
|
||||
client.screen += I
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_neck(obj/item/I)
|
||||
I.screen_loc = ui_neck
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += I
|
||||
update_observer_view(I,1)
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
/mob/living/carbon/human/update_hud_back(obj/item/I)
|
||||
I.screen_loc = ui_back
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
I.screen_loc = ui_back
|
||||
client.screen += I
|
||||
update_observer_view(I)
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@@ -477,15 +443,23 @@ covers:
|
||||
centering large images
|
||||
layering images on custom layers
|
||||
building images from custom icon files
|
||||
|
||||
By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons())
|
||||
|
||||
state: A string to use as the state, this is FAR too complex to solve in this proc thanks to shitty old code
|
||||
so it's specified as an argument instead.
|
||||
|
||||
default_layer: The layer to draw this on if no other layer is specified
|
||||
|
||||
default_icon_file: The icon file to draw states from if no other icon file is specified
|
||||
|
||||
isinhands: If true then alternate_worn_icon is skipped so that default_icon_file is used,
|
||||
in this situation default_icon_file is expected to match either the lefthand_ or righthand_ file var
|
||||
|
||||
femalueuniform: A value matching a uniform item's fitted var, if this is anything but NO_FEMALE_UNIFORM, we
|
||||
generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
|
||||
*/
|
||||
/obj/item/proc/build_worn_icon(var/state = "", var/default_layer = 0, var/default_icon_file = null, var/isinhands = FALSE, var/femaleuniform = NO_FEMALE_UNIFORM)
|
||||
|
||||
@@ -517,41 +491,42 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
standing = center_image(standing, isinhands ? inhand_x_dimension : worn_x_dimension, isinhands ? inhand_y_dimension : worn_y_dimension)
|
||||
|
||||
//Handle held offsets
|
||||
var/mob/M = loc
|
||||
if(istype(M))
|
||||
var/list/L = get_held_offsets()
|
||||
if(L)
|
||||
standing.pixel_x += L["x"] //+= because of center()ing
|
||||
standing.pixel_y += L["y"]
|
||||
|
||||
standing.alpha = alpha
|
||||
standing.color = color
|
||||
|
||||
return standing
|
||||
|
||||
|
||||
/obj/item/proc/get_held_offsets()
|
||||
var/list/L
|
||||
if(ismob(loc))
|
||||
var/mob/M = loc
|
||||
L = M.get_item_offsets_for_index(M.get_held_index_of_item(src))
|
||||
return L
|
||||
|
||||
|
||||
//Can't think of a better way to do this, sadly
|
||||
/mob/proc/get_item_offsets_for_index(i)
|
||||
switch(i)
|
||||
if(3) //odd = left hands
|
||||
return list("x" = 0, "y" = 16)
|
||||
if(4) //even = right hands
|
||||
return list("x" = 0, "y" = 16)
|
||||
else //No offsets or Unwritten number of hands
|
||||
return list("x" = 0, "y" = 0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Limb Icon Cache //
|
||||
/////////////////////
|
||||
/*
|
||||
Called from update_body_parts() these procs handle the limb icon cache.
|
||||
the limb icon cache adds an icon_render_key to a human mob, it represents:
|
||||
- skin_tone (if applicable)
|
||||
- gender
|
||||
- limbs (stores as the limb name and whether it is removed/fine, organic/robotic)
|
||||
These procs only store limbs as to increase the number of matching icon_render_keys
|
||||
This cache exists because drawing 6/7 icons for humans constantly is quite a waste
|
||||
See RemieRichards on irc.rizon.net #coderbus
|
||||
*/
|
||||
|
||||
var/global/list/limb_icon_cache = list()
|
||||
|
||||
/mob/living/carbon/human
|
||||
var/icon_render_key = ""
|
||||
|
||||
|
||||
//produces a key based on the human's limbs
|
||||
/mob/living/carbon/human/proc/generate_icon_render_key()
|
||||
/mob/living/carbon/human/generate_icon_render_key()
|
||||
. = "[dna.species.limbs_id]"
|
||||
|
||||
if(dna.check_mutation(HULK))
|
||||
@@ -562,8 +537,6 @@ var/global/list/limb_icon_cache = list()
|
||||
. += "-coloured-[dna.species.fixed_mut_color]"
|
||||
else if(dna.features["mcolor"])
|
||||
. += "-coloured-[dna.features["mcolor"]]"
|
||||
else if(dna.features["mcolor"] && dna.species.use_skintones)
|
||||
. += "-coloured-[skin_tone]"
|
||||
else
|
||||
. += "-not_coloured"
|
||||
|
||||
@@ -572,18 +545,35 @@ var/global/list/limb_icon_cache = list()
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
. += "-[BP.body_zone]"
|
||||
if(BP.status == ORGAN_ORGANIC)
|
||||
if(BP.status == BODYPART_ORGANIC)
|
||||
. += "-organic"
|
||||
else
|
||||
. += "-robotic"
|
||||
if(BP.use_digitigrade)
|
||||
. += "-digitigrade[BP.use_digitigrade]"
|
||||
if(BP.dmg_overlay_type)
|
||||
. += "-[BP.dmg_overlay_type]"
|
||||
|
||||
if(disabilities & HUSK)
|
||||
. += "-husk"
|
||||
|
||||
/mob/living/carbon/human/load_limb_from_cache()
|
||||
..()
|
||||
update_hair()
|
||||
|
||||
//change the human's icon to the one matching it's key
|
||||
/mob/living/carbon/human/proc/load_limb_from_cache()
|
||||
if(limb_icon_cache[icon_render_key])
|
||||
remove_overlay(BODYPARTS_LAYER)
|
||||
overlays_standing[BODYPARTS_LAYER] = limb_icon_cache[icon_render_key]
|
||||
apply_overlay(BODYPARTS_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/update_observer_view(obj/item/I, inventory)
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client && observe.client.eye == src)
|
||||
if(observe.hud_used)
|
||||
if(inventory && !observe.hud_used.inventory_shown)
|
||||
continue
|
||||
observe.client.screen += I
|
||||
else
|
||||
observers -= observe
|
||||
if(!observers.len)
|
||||
observers = null
|
||||
break
|
||||
@@ -37,12 +37,11 @@
|
||||
|
||||
// If whispering your last words, limit the whisper based on how close you are to death.
|
||||
if(critical)
|
||||
var/health_diff = round(-config.health_threshold_dead + health)
|
||||
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
|
||||
// If we cut our message short, abruptly end it with a-..
|
||||
var/message_len = length(message)
|
||||
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
|
||||
message = Ellipsis(message, 10, 1)
|
||||
whispers = "whispers in their final breath"
|
||||
|
||||
message = treat_message(message)
|
||||
|
||||
@@ -60,12 +59,13 @@
|
||||
watching -= eavesdropping
|
||||
|
||||
var/rendered
|
||||
|
||||
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers] something.</span>"
|
||||
whispers = critical ? "whispers something in [p_their()] final breath." : "whispers something."
|
||||
rendered = "<span class='game say'><span class='name'>[src.name]</span> [whispers]</span>"
|
||||
for(var/mob/M in watching)
|
||||
M.show_message(rendered, 2)
|
||||
|
||||
var/spans = list(SPAN_ITALICS)
|
||||
whispers = critical ? "whispers in [p_their()] final breath" : "whispers"
|
||||
rendered = "<span class='game say'><span class='name'>[GetVoice()]</span>[alt_name] [whispers], <span class='message'>\"[attach_spans(message, spans)]\"</span></span>"
|
||||
|
||||
for(var/atom/movable/AM in listening)
|
||||
|
||||
@@ -4,18 +4,23 @@
|
||||
return back
|
||||
if(slot_wear_mask)
|
||||
return wear_mask
|
||||
if(slot_neck)
|
||||
return wear_neck
|
||||
if(slot_head)
|
||||
return head
|
||||
if(slot_handcuffed)
|
||||
return handcuffed
|
||||
if(slot_legcuffed)
|
||||
return legcuffed
|
||||
if(slot_l_hand)
|
||||
return l_hand
|
||||
if(slot_r_hand)
|
||||
return r_hand
|
||||
return null
|
||||
|
||||
/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/I, list/slots, qdel_on_fail = 1)
|
||||
for(var/slot in slots)
|
||||
if(equip_to_slot_if_possible(I, slots[slot], qdel_on_fail = 0, disable_warning = TRUE))
|
||||
return slot
|
||||
if(qdel_on_fail)
|
||||
qdel(I)
|
||||
return null
|
||||
|
||||
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
|
||||
/mob/living/carbon/equip_to_slot(obj/item/I, slot)
|
||||
@@ -24,19 +29,26 @@
|
||||
if(!istype(I))
|
||||
return
|
||||
|
||||
if(I == l_hand)
|
||||
l_hand = null
|
||||
else if(I == r_hand)
|
||||
r_hand = null
|
||||
var/index = get_held_index_of_item(I)
|
||||
if(index)
|
||||
held_items[index] = null
|
||||
|
||||
if(I.pulledby)
|
||||
I.pulledby.stop_pulling()
|
||||
|
||||
I.screen_loc = null // will get moved if inventory is visible
|
||||
I.screen_loc = null
|
||||
if(client)
|
||||
client.screen -= I
|
||||
if(observers && observers.len)
|
||||
for(var/M in observers)
|
||||
var/mob/dead/observe = M
|
||||
if(observe.client)
|
||||
observe.client.screen -= I
|
||||
I.loc = src
|
||||
I.equipped(src, slot)
|
||||
I.layer = ABOVE_HUD_LAYER
|
||||
|
||||
I.plane = ABOVE_HUD_PLANE
|
||||
I.appearance_flags |= NO_CLIENT_COLOR
|
||||
var/not_handled = FALSE
|
||||
switch(slot)
|
||||
if(slot_back)
|
||||
back = I
|
||||
@@ -47,27 +59,36 @@
|
||||
if(slot_head)
|
||||
head = I
|
||||
head_update(I)
|
||||
if(slot_neck)
|
||||
wear_neck = I
|
||||
update_inv_neck(I)
|
||||
if(slot_handcuffed)
|
||||
handcuffed = I
|
||||
update_handcuffed()
|
||||
if(slot_legcuffed)
|
||||
legcuffed = I
|
||||
update_inv_legcuffed()
|
||||
if(slot_l_hand)
|
||||
l_hand = I
|
||||
update_inv_l_hand()
|
||||
if(slot_r_hand)
|
||||
r_hand = I
|
||||
update_inv_r_hand()
|
||||
if(slot_hands)
|
||||
put_in_hands(I)
|
||||
update_inv_hands()
|
||||
if(slot_in_backpack)
|
||||
if(I == get_active_hand())
|
||||
unEquip(I)
|
||||
I.loc = back
|
||||
var/obj/item/weapon/storage/B = back
|
||||
var/prev_jimmies = B.rustle_jimmies
|
||||
B.rustle_jimmies = FALSE //don't conspicously rustle
|
||||
B.handle_item_insertion(I, 1, src)
|
||||
B.rustle_jimmies = prev_jimmies
|
||||
else
|
||||
return 1
|
||||
not_handled = TRUE
|
||||
|
||||
//Item has been handled at this point and equipped callback can be safely called
|
||||
//We cannot call it for items that have not been handled as they are not yet correctly
|
||||
//in a slot (handled further down inheritance chain, probably living/carbon/human/equip_to_slot
|
||||
if(!not_handled)
|
||||
I.equipped(src, slot)
|
||||
|
||||
/mob/living/carbon/unEquip(obj/item/I)
|
||||
return not_handled
|
||||
|
||||
/mob/living/carbon/doUnEquip(obj/item/I)
|
||||
. = ..() //Sets the default return value to what the parent returns.
|
||||
if(!. || !I) //We don't want to set anything to null if the parent returned 0.
|
||||
return
|
||||
@@ -81,6 +102,9 @@
|
||||
else if(I == wear_mask)
|
||||
wear_mask = null
|
||||
wear_mask_update(I, toggle_off = 1)
|
||||
if(I == wear_neck)
|
||||
wear_neck = null
|
||||
update_inv_neck(I)
|
||||
else if(I == handcuffed)
|
||||
handcuffed = null
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
@@ -105,6 +129,8 @@
|
||||
var/obj/item/clothing/C = I
|
||||
if(C.tint || initial(C.tint))
|
||||
update_tint()
|
||||
update_sight()
|
||||
if(I.flags_inv & HIDEMASK || forced)
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
|
||||
|
||||
@@ -4,24 +4,25 @@
|
||||
|
||||
if (notransform)
|
||||
return
|
||||
if(!loc)
|
||||
return
|
||||
|
||||
if(damageoverlaytemp)
|
||||
damageoverlaytemp = 0
|
||||
update_damage_hud()
|
||||
|
||||
if(..())
|
||||
. = 1
|
||||
|
||||
if(..()) //not dead
|
||||
handle_blood()
|
||||
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(stat != DEAD)
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
O.on_life()
|
||||
|
||||
//Updates the number of stored chemicals for powers
|
||||
handle_changeling()
|
||||
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
///////////////
|
||||
// BREATHING //
|
||||
///////////////
|
||||
@@ -50,7 +51,7 @@
|
||||
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(health <= config.health_threshold_crit || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
|
||||
if(health <= HEALTH_THRESHOLD_CRIT || (pulledby && pulledby.grab_state >= GRAB_KILL && !getorganslot("breathing_tube")))
|
||||
losebreath++
|
||||
|
||||
//Suffocate
|
||||
@@ -259,7 +260,7 @@
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
|
||||
if(radiation)
|
||||
|
||||
radiation = Clamp(radiation, 0, 100)
|
||||
switch(radiation)
|
||||
if(0 to 50)
|
||||
radiation = max(radiation-1,0)
|
||||
@@ -275,8 +276,6 @@
|
||||
if(75 to 100)
|
||||
radiation = max(radiation-3,0)
|
||||
adjustToxLoss(3)
|
||||
else
|
||||
radiation = Clamp(radiation, 0, 100)
|
||||
|
||||
/mob/living/carbon/handle_chemicals_in_body()
|
||||
if(reagents)
|
||||
@@ -284,7 +283,6 @@
|
||||
|
||||
|
||||
/mob/living/carbon/handle_stomach()
|
||||
/*
|
||||
set waitfor = 0
|
||||
for(var/mob/living/M in stomach_contents)
|
||||
if(M.loc != src)
|
||||
@@ -300,7 +298,7 @@
|
||||
if(!(M.status_flags & GODMODE))
|
||||
M.adjustBruteLoss(5)
|
||||
nutrition += 10
|
||||
*/
|
||||
|
||||
//this updates all special effects: stunned, sleeping, weakened, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
@@ -314,7 +312,7 @@
|
||||
if(sleeping)
|
||||
handle_dreams()
|
||||
AdjustSleeping(-1)
|
||||
if(prob(10) && health>config.health_threshold_crit)
|
||||
if(prob(10) && health>HEALTH_THRESHOLD_CRIT)
|
||||
emote("snore")
|
||||
|
||||
var/restingpwr = 1 + 4 * resting
|
||||
@@ -389,8 +387,6 @@
|
||||
var/body_temperature_difference = 310.15 - bodytemperature
|
||||
switch(bodytemperature)
|
||||
if(-INFINITY to 260.15) //260.15 is 310.15 - 50, the temperature where you start to feel effects.
|
||||
if(nutrition >= 2) //If we are very, very cold we'll use up quite a bit of nutriment to heat us up.
|
||||
nutrition -= 2
|
||||
bodytemperature += max((body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR), BODYTEMP_AUTORECOVERY_MINIMUM)
|
||||
if(260.15 to 310.15)
|
||||
bodytemperature += max(body_temperature_difference * metabolism_efficiency / BODYTEMP_AUTORECOVERY_DIVISOR, min(body_temperature_difference, BODYTEMP_AUTORECOVERY_MINIMUM/4))
|
||||
|
||||
@@ -0,0 +1,458 @@
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
var/aggressive=0 // set to 1 using VV for an angry monkey
|
||||
var/frustration=0
|
||||
var/pickupTimer=0
|
||||
var/list/enemies = list()
|
||||
var/mob/living/target
|
||||
var/obj/item/pickupTarget
|
||||
var/mode = MONKEY_IDLE
|
||||
var/list/myPath = list()
|
||||
var/list/blacklistItems = list()
|
||||
var/maxStepsTick = 6
|
||||
var/best_force = 0
|
||||
var/martial_art = new/datum/martial_art
|
||||
var/resisting = FALSE
|
||||
var/pickpocketing = FALSE
|
||||
var/disposing_body = FALSE
|
||||
var/obj/machinery/disposal/bodyDisposal = null
|
||||
|
||||
/mob/living/carbon/monkey/proc/IsStandingStill()
|
||||
return resisting || pickpocketing || disposing_body
|
||||
|
||||
// blocks
|
||||
// taken from /mob/living/carbon/human/interactive/
|
||||
/mob/living/carbon/monkey/proc/walk2derpless(target)
|
||||
if(!target || IsStandingStill())
|
||||
return 0
|
||||
|
||||
if(myPath.len <= 0)
|
||||
myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, MAX_RANGE_FIND + 1, 250,1)
|
||||
|
||||
if(myPath)
|
||||
if(myPath.len > 0)
|
||||
for(var/i = 0; i < maxStepsTick; ++i)
|
||||
if(!IsDeadOrIncap())
|
||||
if(myPath.len >= 1)
|
||||
walk_to(src,myPath[1],0,5)
|
||||
myPath -= myPath[1]
|
||||
return 1
|
||||
|
||||
// failed to path correctly so just try to head straight for a bit
|
||||
walk_to(src,get_turf(target),0,5)
|
||||
sleep(1)
|
||||
walk_to(src,0)
|
||||
|
||||
return 0
|
||||
|
||||
// taken from /mob/living/carbon/human/interactive/
|
||||
/mob/living/carbon/monkey/proc/IsDeadOrIncap(checkDead = TRUE)
|
||||
if(!canmove)
|
||||
return 1
|
||||
if(health <= 0 && checkDead)
|
||||
return 1
|
||||
if(paralysis)
|
||||
return 1
|
||||
if(stunned)
|
||||
return 1
|
||||
if(stat)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/monkey/proc/equip_item(var/obj/item/I)
|
||||
|
||||
if(I.loc == src)
|
||||
return TRUE
|
||||
|
||||
if(I.anchored)
|
||||
blacklistItems[I] ++
|
||||
return FALSE
|
||||
|
||||
// WEAPONS
|
||||
if(istype(I, /obj/item/weapon))
|
||||
var/obj/item/weapon/W = I
|
||||
if(W.force >= best_force)
|
||||
put_in_hands(W)
|
||||
best_force = W.force
|
||||
return TRUE
|
||||
|
||||
// CLOTHING
|
||||
else if(istype(I,/obj/item/clothing))
|
||||
var/obj/item/clothing/C = I
|
||||
monkeyDrop(C)
|
||||
addtimer(CALLBACK(src, .proc/pickup_and_wear, C), 5)
|
||||
return TRUE
|
||||
|
||||
// EVERYTHING ELSE
|
||||
else
|
||||
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
|
||||
put_in_hands(I)
|
||||
return TRUE
|
||||
|
||||
blacklistItems[I] ++
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/monkey/proc/pickup_and_wear(var/obj/item/clothing/C)
|
||||
if(!equip_to_appropriate_slot(C))
|
||||
monkeyDrop(get_item_by_slot(C)) // remove the existing item if worn
|
||||
sleep(5)
|
||||
equip_to_appropriate_slot(C)
|
||||
|
||||
/mob/living/carbon/monkey/resist_restraints()
|
||||
var/obj/item/I = null
|
||||
if(handcuffed)
|
||||
I = handcuffed
|
||||
else if(legcuffed)
|
||||
I = legcuffed
|
||||
if(I)
|
||||
changeNext_move(CLICK_CD_BREAKOUT)
|
||||
last_special = world.time + CLICK_CD_BREAKOUT
|
||||
cuff_resist(I)
|
||||
|
||||
/mob/living/carbon/monkey/proc/should_target(var/mob/living/L)
|
||||
|
||||
if(L == src)
|
||||
return 0
|
||||
|
||||
if(enemies[L])
|
||||
return 1
|
||||
|
||||
// target non-monkey mobs when aggressive, with a small probability of monkey v monkey
|
||||
if(aggressive && (!istype(L, /mob/living/carbon/monkey/) || prob(MONKEY_AGGRESSIVE_MVM_PROB)))
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/monkey/proc/handle_combat()
|
||||
|
||||
if(on_fire || buckled || restrained())
|
||||
if(!resisting && prob(MONKEY_RESIST_PROB))
|
||||
resisting = TRUE
|
||||
walk_to(src,0)
|
||||
resist()
|
||||
else
|
||||
resisting = FALSE
|
||||
|
||||
|
||||
if(IsDeadOrIncap())
|
||||
return TRUE
|
||||
|
||||
// have we been disarmed
|
||||
if(!locate(/obj/item/weapon) in held_items)
|
||||
best_force = 0
|
||||
|
||||
if(restrained() || blacklistItems[pickupTarget] || (pickupTarget && (pickupTarget.flags & NODROP)))
|
||||
pickupTarget = null
|
||||
|
||||
if(!resisting && pickupTarget)
|
||||
pickupTimer++
|
||||
|
||||
// next to target
|
||||
if(Adjacent(pickupTarget) || Adjacent(pickupTarget.loc))
|
||||
INVOKE_ASYNC(src, .proc/walk2derpless, pickupTarget.loc)
|
||||
|
||||
// who cares about these items, i want that one!
|
||||
drop_all_held_items()
|
||||
|
||||
// on floor
|
||||
if(isturf(pickupTarget.loc))
|
||||
equip_item(pickupTarget)
|
||||
pickupTarget = null
|
||||
pickupTimer = 0
|
||||
|
||||
// in someones hand
|
||||
else if(ismob(pickupTarget.loc))
|
||||
var/mob/M = pickupTarget.loc
|
||||
if(!pickpocketing)
|
||||
pickpocketing = TRUE
|
||||
M.visible_message("[src] starts trying to take [pickupTarget] from [M]", "[src] tries to take [pickupTarget]!")
|
||||
INVOKE_ASYNC(src, .proc/pickpocket, M)
|
||||
|
||||
else
|
||||
if(pickupTimer >= 8)
|
||||
blacklistItems[pickupTarget] ++
|
||||
pickupTarget = null
|
||||
pickupTimer = 0
|
||||
else
|
||||
INVOKE_ASYNC(src, .proc/walk2derpless, pickupTarget.loc)
|
||||
|
||||
return TRUE
|
||||
|
||||
// nuh uh you don't pull me!
|
||||
if(pulledby && (mode != MONKEY_IDLE || prob(MONKEY_PULL_AGGRO_PROB)))
|
||||
if(Adjacent(pulledby))
|
||||
a_intent = INTENT_DISARM
|
||||
monkey_attack(pulledby)
|
||||
retaliate(pulledby)
|
||||
return TRUE
|
||||
|
||||
switch(mode)
|
||||
|
||||
if(MONKEY_IDLE) // idle
|
||||
|
||||
var/list/around = view(src, MONKEY_ENEMY_VISION)
|
||||
bodyDisposal = locate(/obj/machinery/disposal/) in around
|
||||
|
||||
// scan for enemies
|
||||
for(var/mob/living/L in around)
|
||||
if( should_target(L) )
|
||||
if(L.stat == CONSCIOUS)
|
||||
emote(pick("roar","screech"))
|
||||
retaliate(L)
|
||||
return TRUE
|
||||
else if(bodyDisposal)
|
||||
target = L
|
||||
mode = MONKEY_DISPOSE
|
||||
return TRUE
|
||||
|
||||
// pickup any nearby objects
|
||||
if(!pickupTarget && prob(MONKEY_PICKUP_PROB))
|
||||
var/obj/item/I = locate(/obj/item/) in oview(5,src)
|
||||
if(I && !blacklistItems[I])
|
||||
pickupTarget = I
|
||||
|
||||
// I WANNA STEAL
|
||||
if(!pickupTarget && prob(MONKEY_STEAL_PROB))
|
||||
var/mob/living/carbon/human/H = locate(/mob/living/carbon/human/) in oview(5,src)
|
||||
if(H)
|
||||
pickupTarget = pick(H.held_items)
|
||||
|
||||
// clear any combat walking
|
||||
if(!resisting)
|
||||
walk_to(src,0)
|
||||
|
||||
return IsStandingStill()
|
||||
|
||||
if(MONKEY_HUNT) // hunting for attacker
|
||||
if(health < MONKEY_FLEE_HEALTH)
|
||||
mode = MONKEY_FLEE
|
||||
return TRUE
|
||||
|
||||
if(target != null)
|
||||
INVOKE_ASYNC(src, .proc/walk2derpless, target)
|
||||
|
||||
// pickup any nearby weapon
|
||||
if(!pickupTarget && prob(MONKEY_WEAPON_PROB))
|
||||
var/obj/item/weapon/W = locate(/obj/item/weapon/) in oview(2,src)
|
||||
if(W && !blacklistItems[W] && W.force > best_force)
|
||||
pickupTarget = W
|
||||
|
||||
// recruit other monkies
|
||||
var/list/around = view(src, MONKEY_ENEMY_VISION)
|
||||
for(var/mob/living/carbon/monkey/M in around)
|
||||
if(M.mode == MONKEY_IDLE && prob(MONKEY_RECRUIT_PROB))
|
||||
M.emote(pick("roar","screech"))
|
||||
M.target = target
|
||||
M.mode = MONKEY_HUNT
|
||||
|
||||
// switch targets
|
||||
for(var/mob/living/L in around)
|
||||
if(L != target && should_target(L) && L.stat == CONSCIOUS && prob(MONKEY_SWITCH_TARGET_PROB))
|
||||
target = L
|
||||
return TRUE
|
||||
|
||||
// if can't reach target for long enough, go idle
|
||||
if(frustration >= MONKEY_HUNT_FRUSTRATION_LIMIT)
|
||||
back_to_idle()
|
||||
return TRUE
|
||||
|
||||
if(target && target.stat == CONSCIOUS) // make sure target exists
|
||||
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
|
||||
|
||||
// check if target has a weapon
|
||||
var/obj/item/weapon/W = locate(/obj/item/weapon) in target.held_items
|
||||
|
||||
// if the target has a weapon, chance to disarm them
|
||||
if(W && prob(MONKEY_ATTACK_DISARM_PROB))
|
||||
pickupTarget = W
|
||||
a_intent = INTENT_DISARM
|
||||
monkey_attack(target)
|
||||
|
||||
else
|
||||
a_intent = INTENT_HARM
|
||||
monkey_attack(target)
|
||||
|
||||
return TRUE
|
||||
|
||||
else // not next to perp
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
if(MONKEY_FLEE)
|
||||
var/list/around = view(src, MONKEY_FLEE_VISION)
|
||||
target = null
|
||||
|
||||
// flee from anyone who attacked us and we didn't beat down
|
||||
for(var/mob/living/L in around)
|
||||
if( enemies[L] && L.stat == CONSCIOUS )
|
||||
target = L
|
||||
|
||||
if(target != null)
|
||||
walk_away(src, target, MONKEY_ENEMY_VISION, 5)
|
||||
else
|
||||
back_to_idle()
|
||||
|
||||
return TRUE
|
||||
|
||||
if(MONKEY_DISPOSE)
|
||||
|
||||
// if can't dispose of body go back to idle
|
||||
if(!target || !bodyDisposal || frustration >= MONKEY_DISPOSE_FRUSTRATION_LIMIT)
|
||||
back_to_idle()
|
||||
return TRUE
|
||||
|
||||
if(target.pulledby != src && !istype(target.pulledby, /mob/living/carbon/monkey/))
|
||||
|
||||
INVOKE_ASYNC(src, .proc/walk2derpless, target.loc)
|
||||
|
||||
if(Adjacent(target) && isturf(target.loc))
|
||||
a_intent = INTENT_GRAB
|
||||
target.grabbedby(src)
|
||||
else
|
||||
var/turf/olddist = get_dist(src, target)
|
||||
if((get_dist(src, target)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
|
||||
else if(!disposing_body)
|
||||
INVOKE_ASYNC(src, .proc/walk2derpless, bodyDisposal.loc)
|
||||
|
||||
if(Adjacent(bodyDisposal))
|
||||
disposing_body = TRUE
|
||||
addtimer(CALLBACK(src, .proc/stuff_mob_in), 5)
|
||||
|
||||
else
|
||||
var/turf/olddist = get_dist(src, bodyDisposal)
|
||||
if((get_dist(src, bodyDisposal)) >= (olddist))
|
||||
frustration++
|
||||
else
|
||||
frustration = 0
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
return IsStandingStill()
|
||||
|
||||
/mob/living/carbon/monkey/proc/pickpocket(var/mob/M)
|
||||
if(do_mob(src, M, MONKEY_ITEM_SNATCH_DELAY) && pickupTarget)
|
||||
for(var/obj/item/I in M.held_items)
|
||||
if(I == pickupTarget)
|
||||
M.visible_message("<span class='danger'>[src] snatches [pickupTarget] from [M].</span>", "<span class='userdanger'>[src] snatched [pickupTarget]!</span>")
|
||||
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !qdeleted(pickupTarget))
|
||||
equip_item(pickupTarget)
|
||||
else
|
||||
M.visible_message("<span class='danger'>[src] tried to snatch [pickupTarget] from [M], but failed!</span>", "<span class='userdanger'>[src] tried to grab [pickupTarget]!</span>")
|
||||
pickpocketing = FALSE
|
||||
pickupTarget = null
|
||||
pickupTimer = 0
|
||||
|
||||
/mob/living/carbon/monkey/proc/stuff_mob_in()
|
||||
if(bodyDisposal && target && Adjacent(bodyDisposal))
|
||||
bodyDisposal.stuff_mob_in(target, src)
|
||||
disposing_body = FALSE
|
||||
back_to_idle()
|
||||
|
||||
/mob/living/carbon/monkey/proc/back_to_idle()
|
||||
|
||||
if(pulling)
|
||||
stop_pulling()
|
||||
|
||||
mode = MONKEY_IDLE
|
||||
target = null
|
||||
a_intent = INTENT_HELP
|
||||
frustration = 0
|
||||
walk_to(src,0)
|
||||
|
||||
// attack using a held weapon otherwise bite the enemy, then if we are angry there is a chance we might calm down a little
|
||||
/mob/living/carbon/monkey/proc/monkey_attack(mob/living/L)
|
||||
var/obj/item/weapon/Weapon = locate(/obj/item/weapon) in held_items
|
||||
|
||||
// attack with weapon if we have one
|
||||
if(Weapon)
|
||||
L.attackby(Weapon, src)
|
||||
else
|
||||
L.attack_paw(src)
|
||||
|
||||
// no de-aggro
|
||||
if(aggressive)
|
||||
return
|
||||
|
||||
// if we arn't enemies, we were likely recruited to attack this target, jobs done if we calm down so go back to idle
|
||||
if(!enemies[L])
|
||||
if( target == L && prob(MONKEY_HATRED_REDUCTION_PROB) )
|
||||
back_to_idle()
|
||||
return // already de-aggroed
|
||||
|
||||
if(prob(MONKEY_HATRED_REDUCTION_PROB))
|
||||
enemies[L] --
|
||||
|
||||
// if we are not angry at our target, go back to idle
|
||||
if(enemies[L] <= 0)
|
||||
enemies.Remove(L)
|
||||
if( target == L )
|
||||
back_to_idle()
|
||||
|
||||
// get angry are a mob
|
||||
/mob/living/carbon/monkey/proc/retaliate(mob/living/L)
|
||||
mode = MONKEY_HUNT
|
||||
target = L
|
||||
enemies[L] += MONKEY_HATRED_AMOUNT
|
||||
|
||||
if(a_intent != INTENT_HARM)
|
||||
emote(pick("roar","screech"))
|
||||
a_intent = INTENT_HARM
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/L)
|
||||
if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
|
||||
retaliate(L)
|
||||
else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB))
|
||||
retaliate(L)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/L)
|
||||
if(L.a_intent == INTENT_HARM && prob(MONKEY_RETALIATE_HARM_PROB))
|
||||
retaliate(L)
|
||||
else if(L.a_intent == INTENT_DISARM && prob(MONKEY_RETALIATE_DISARM_PROB))
|
||||
retaliate(L)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/monkey/attackby(obj/item/weapon/W, mob/user, params)
|
||||
..()
|
||||
if((W.force) && (!target) && (W.damtype != STAMINA) )
|
||||
retaliate(user)
|
||||
|
||||
/mob/living/carbon/monkey/bullet_act(obj/item/projectile/Proj)
|
||||
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
|
||||
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
|
||||
if(!Proj.nodamage && Proj.damage < src.health)
|
||||
retaliate(Proj.firer)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
|
||||
if(istype(AM, /obj/item))
|
||||
var/obj/item/I = AM
|
||||
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
|
||||
var/mob/living/carbon/human/H = I.thrownby
|
||||
retaliate(H)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/Crossed(atom/movable/AM)
|
||||
if(!IsDeadOrIncap() && ismob(AM) && target)
|
||||
var/mob/living/carbon/monkey/M = AM
|
||||
if(!istype(M) || !M)
|
||||
return
|
||||
knockOver(M)
|
||||
return
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/proc/monkeyDrop(var/obj/item/A)
|
||||
if(A)
|
||||
dropItemToGround(A, TRUE)
|
||||
update_icons()
|
||||
@@ -1,19 +1,5 @@
|
||||
/mob/living/carbon/monkey/gib_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/gib_animation, list(loc, "gibbed-m"))
|
||||
new /obj/effect/overlay/temp/gib_animation(loc, "gibbed-m")
|
||||
|
||||
/mob/living/carbon/monkey/dust_animation()
|
||||
PoolOrNew(/obj/effect/overlay/temp/dust_animation, list(loc, "dust-m"))
|
||||
|
||||
/mob/living/carbon/monkey/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
stat = DEAD
|
||||
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
|
||||
if(ticker && ticker.mode)
|
||||
ticker.mode.check_win()
|
||||
|
||||
return ..(gibbed)
|
||||
new /obj/effect/overlay/temp/dust_animation(loc, "dust-m")
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/mob/living/carbon/monkey/emote(act,m_type=1,message = null)
|
||||
if(stat == DEAD && (act != "deathgasp") || (status_flags & FAKEDEATH)) //if we're faking, don't emote at all
|
||||
return
|
||||
|
||||
var/param = null
|
||||
if (findtext(act, "-", 1, null))
|
||||
var/t1 = findtext(act, "-", 1, null)
|
||||
param = copytext(act, t1 + 1, length(act) + 1)
|
||||
act = copytext(act, 1, t1)
|
||||
|
||||
var/muzzled = is_muzzled()
|
||||
|
||||
switch(act) //Ooh ooh ah ah keep this alphabetical ooh ooh ah ah!
|
||||
if ("deathgasp","deathgasps")
|
||||
message = "<b>[src]</b> lets out a faint chimper as it collapses and stops moving..."
|
||||
m_type = 1
|
||||
|
||||
if ("gnarl","gnarls")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> gnarls and shows its teeth.."
|
||||
m_type = 2
|
||||
|
||||
if ("me")
|
||||
..()
|
||||
return
|
||||
|
||||
if ("moan","moans")
|
||||
message = "<B>[src]</B> moans!"
|
||||
m_type = 2
|
||||
|
||||
if ("paw")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> flails its paw."
|
||||
m_type = 1
|
||||
|
||||
if ("roar","roars")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> roars."
|
||||
m_type = 2
|
||||
|
||||
if ("roll","rolls")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> rolls."
|
||||
m_type = 1
|
||||
|
||||
if ("scratch","scratches")
|
||||
if (!src.restrained())
|
||||
message = "<B>[src]</B> scratches."
|
||||
m_type = 1
|
||||
|
||||
if ("screech","screeches")
|
||||
if (!muzzled)
|
||||
message = "<B>[src]</B> screeches."
|
||||
m_type = 2
|
||||
|
||||
if ("shiver","shivers")
|
||||
message = "<B>[src]</B> shivers."
|
||||
m_type = 2
|
||||
|
||||
if ("sign","signs")
|
||||
if (!src.restrained())
|
||||
message = text("<B>[src]</B> signs[].", (text2num(param) ? text(" the number []", text2num(param)) : null))
|
||||
m_type = 1
|
||||
|
||||
if ("tail")
|
||||
message = "<B>[src]</B> waves its tail."
|
||||
m_type = 1
|
||||
|
||||
if ("help") //Ooh ah ooh ooh this is an exception to alphabetical ooh ooh.
|
||||
src << "Help for monkey emotes. You can use these emotes with say \"*emote\":\n\naflap, airguitar, blink, blink_r, blush, bow-(none)/mob, burp, choke, chuckle, clap, collapse, cough, dance, deathgasp, drool, flap, frown, gasp, gnarl, giggle, glare-(none)/mob, grin, jump, laugh, look, me, moan, nod, paw, point-(atom), roar, roll, scream, scratch, screech, shake, shiver, sigh, sign-#, sit, smile, sneeze, sniff, snore, stare-(none)/mob, sulk, sway, tail, tremble, twitch, twitch_s, wave whimper, wink, yawn"
|
||||
|
||||
else
|
||||
..()
|
||||
|
||||
if ((message && src.stat == 0))
|
||||
if(src.client)
|
||||
log_emote("[name]/[key] : [message]")
|
||||
if (m_type & 1)
|
||||
visible_message(message)
|
||||
else
|
||||
audible_message(message)
|
||||
return
|
||||
@@ -1,32 +1,34 @@
|
||||
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
switch(slot)
|
||||
if(slot_l_hand)
|
||||
if(l_hand)
|
||||
return 0
|
||||
return 1
|
||||
if(slot_r_hand)
|
||||
if(r_hand)
|
||||
return 0
|
||||
return 1
|
||||
if(slot_hands)
|
||||
if(get_empty_held_indexes())
|
||||
return TRUE
|
||||
return FALSE
|
||||
if(slot_wear_mask)
|
||||
if(wear_mask)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_MASK) )
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_neck)
|
||||
if(wear_neck)
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_NECK) )
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_head)
|
||||
if(head)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_HEAD) )
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
if(slot_back)
|
||||
if(back)
|
||||
return 0
|
||||
return FALSE
|
||||
if( !(I.slot_flags & SLOT_BACK) )
|
||||
return 0
|
||||
return 1
|
||||
return 0 //Unsupported slot
|
||||
return FALSE
|
||||
return TRUE
|
||||
return FALSE //Unsupported slot
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
|
||||
@@ -10,34 +10,40 @@
|
||||
if (notransform)
|
||||
return
|
||||
|
||||
..()
|
||||
if(..())
|
||||
|
||||
if(!client && stat == CONSCIOUS)
|
||||
if(prob(33) && canmove && isturf(loc) && !pulledby)
|
||||
step(src, pick(cardinal))
|
||||
if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
if(!client)
|
||||
if(stat == CONSCIOUS)
|
||||
if(!handle_combat())
|
||||
if(prob(33) && canmove && isturf(loc) && !pulledby)
|
||||
step(src, pick(cardinal))
|
||||
if(prob(1))
|
||||
emote(pick("scratch","jump","roll","tail"))
|
||||
else
|
||||
walk_to(src,0)
|
||||
|
||||
/mob/living/carbon/monkey/handle_mutations_and_radiation()
|
||||
|
||||
if (radiation)
|
||||
if (radiation > 100)
|
||||
if(!weakened)
|
||||
emote("collapse")
|
||||
Weaken(10)
|
||||
src << "<span class='danger'>You feel weak.</span>"
|
||||
emote("collapse")
|
||||
|
||||
switch(radiation)
|
||||
|
||||
if(50 to 75)
|
||||
if(prob(5))
|
||||
if(!weakened)
|
||||
emote("collapse")
|
||||
Weaken(3)
|
||||
src << "<span class='danger'>You feel weak.</span>"
|
||||
emote("collapse")
|
||||
|
||||
if(75 to 100)
|
||||
if(prob(1))
|
||||
src << "<span class='danger'>You mutate!</span>"
|
||||
randmutb(src)
|
||||
randmutb()
|
||||
emote("gasp")
|
||||
domutcheck()
|
||||
..()
|
||||
@@ -81,29 +87,29 @@
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 1)
|
||||
adjustFireLoss(2)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 2)
|
||||
adjustFireLoss(3)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
throw_alert("temp", /obj/screen/alert/hot, 3)
|
||||
if(on_fire)
|
||||
adjustFireLoss(8)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
adjustFireLoss(3)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
|
||||
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
switch(bodytemperature)
|
||||
if(200 to 260)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 1)
|
||||
adjustFireLoss(0.5)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_1, BURN)
|
||||
if(120 to 200)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 2)
|
||||
adjustFireLoss(1.5)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_2, BURN)
|
||||
if(-INFINITY to 120)
|
||||
throw_alert("temp", /obj/screen/alert/cold, 3)
|
||||
adjustFireLoss(3)
|
||||
apply_damage(COLD_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
clear_alert("temp")
|
||||
|
||||
@@ -140,7 +146,29 @@
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/monkey/handle_fire()
|
||||
if(..())
|
||||
return
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
return
|
||||
. = ..()
|
||||
if(on_fire)
|
||||
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
var/list/burning_items = list()
|
||||
//HEAD//
|
||||
var/obj/item/clothing/head_clothes = null
|
||||
if(wear_mask)
|
||||
head_clothes = wear_mask
|
||||
if(wear_neck)
|
||||
head_clothes = wear_neck
|
||||
if(head)
|
||||
head_clothes = head
|
||||
if(head_clothes)
|
||||
burning_items += head_clothes
|
||||
|
||||
if(back)
|
||||
burning_items += back
|
||||
|
||||
for(var/X in burning_items)
|
||||
var/obj/item/I = X
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(fire_stacks, BURN, "fire", 0)
|
||||
|
||||
bodytemperature += BODYTEMP_HEATING_MAX
|
||||
|
||||
|
||||
@@ -3,16 +3,21 @@
|
||||
voice_name = "monkey"
|
||||
verb_say = "chimpers"
|
||||
icon = 'icons/mob/monkey.dmi'
|
||||
icon_state = "monkey1"
|
||||
icon_state = ""
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
languages_spoken = MONKEY
|
||||
languages_understood = MONKEY
|
||||
ventcrawler = 1
|
||||
ventcrawler = VENTCRAWLER_NUDE
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey = 5, /obj/item/stack/sheet/animalhide/monkey = 1)
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/monkey
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
unique_name = 1
|
||||
devourable = 1
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/New()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
@@ -22,31 +27,26 @@
|
||||
gender = pick(MALE, FEMALE)
|
||||
real_name = name
|
||||
|
||||
//initialize limbs, currently only used to handle cavity implant surgery, no dismemberment.
|
||||
bodyparts = newlist(/obj/item/bodypart/chest, /obj/item/bodypart/head, /obj/item/bodypart/l_arm,
|
||||
/obj/item/bodypart/r_arm, /obj/item/bodypart/r_leg, /obj/item/bodypart/l_leg)
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/O = X
|
||||
O.owner = src
|
||||
//initialize limbs
|
||||
create_bodyparts()
|
||||
|
||||
if(good_mutations.len) //genetic mutations have been set up.
|
||||
initialize()
|
||||
create_internal_organs()
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/Initialize()
|
||||
..()
|
||||
create_dna(src)
|
||||
dna.initialize_dna(random_blood_type())
|
||||
|
||||
/mob/living/carbon/monkey/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/appendix
|
||||
internal_organs += new /obj/item/organ/lungs
|
||||
internal_organs += new /obj/item/organ/heart
|
||||
internal_organs += new /obj/item/organ/brain
|
||||
internal_organs += new /obj/item/organ/tongue
|
||||
|
||||
for(var/obj/item/organ/I in internal_organs)
|
||||
I.Insert(src)
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/initialize()
|
||||
create_dna(src)
|
||||
dna.initialize_dna(random_blood_type())
|
||||
|
||||
/mob/living/carbon/monkey/movement_delay()
|
||||
if(reagents)
|
||||
if(reagents.has_reagent("morphine"))
|
||||
@@ -64,133 +64,6 @@
|
||||
. += (283.222 - bodytemperature) / 10 * 1.75
|
||||
return . + config.monkey_delay
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/M)
|
||||
if(..()) //successful monkey bite.
|
||||
var/damage = rand(1, 5)
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if("harm")
|
||||
M.do_attack_animation(src)
|
||||
if (prob(75))
|
||||
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [name]!</span>")
|
||||
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
var/damage = rand(5, 10)
|
||||
if (prob(40))
|
||||
damage = rand(10, 15)
|
||||
if ( (paralysis < 5) && (health > 0) )
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has knocked out [name]!</span>")
|
||||
adjustBruteLoss(damage)
|
||||
add_logs(M, src, "attacked")
|
||||
updatehealth()
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [name]!</span>")
|
||||
if("disarm")
|
||||
if (!( paralysis ))
|
||||
M.do_attack_animation(src)
|
||||
if (prob(25))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>")
|
||||
else
|
||||
if(drop_item())
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>")
|
||||
|
||||
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
if (M.a_intent == "harm")
|
||||
if ((prob(95) && health > 0))
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
var/damage = rand(15, 30)
|
||||
if (damage >= 25)
|
||||
damage = rand(20, 40)
|
||||
if (paralysis < 15)
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [name]!</span>")
|
||||
else
|
||||
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed [name]!</span>")
|
||||
|
||||
if (stat != DEAD)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
add_logs(M, src, "attacked")
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>")
|
||||
|
||||
if (M.a_intent == "disarm")
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Weaken(10)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>")
|
||||
else
|
||||
if(drop_item())
|
||||
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [name]!</span>")
|
||||
add_logs(M, src, "disarmed")
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
switch(M.melee_damage_type)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
adjustBruteLoss(damage)
|
||||
updatehealth()
|
||||
|
||||
/mob/living/carbon/monkey/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
@@ -209,24 +82,6 @@
|
||||
internal = null
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/ex_act(severity, target)
|
||||
..()
|
||||
switch(severity)
|
||||
if(1)
|
||||
gib()
|
||||
return
|
||||
if(2)
|
||||
adjustBruteLoss(60)
|
||||
adjustFireLoss(60)
|
||||
adjustEarDamage(30,120)
|
||||
if(3)
|
||||
adjustBruteLoss(30)
|
||||
if (prob(50))
|
||||
Paralyse(10)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
updatehealth()
|
||||
return
|
||||
|
||||
/mob/living/carbon/monkey/IsAdvancedToolUser()//Unless its monkey mode monkeys cant use advanced tools
|
||||
return 0
|
||||
@@ -249,46 +104,27 @@
|
||||
//Lasertag bullshit
|
||||
if(lasercolor)
|
||||
if(lasercolor == "b")//Lasertag turrets target the opposing team, how great is that? -Sieve
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/redtag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/redtag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/redtag))
|
||||
threatcount += 4
|
||||
|
||||
if(lasercolor == "r")
|
||||
if((istype(r_hand,/obj/item/weapon/gun/energy/laser/bluetag)) || (istype(l_hand,/obj/item/weapon/gun/energy/laser/bluetag)))
|
||||
if(is_holding_item_of_type(/obj/item/weapon/gun/energy/laser/bluetag))
|
||||
threatcount += 4
|
||||
|
||||
return threatcount
|
||||
|
||||
//Check for weapons
|
||||
if(judgebot.weaponscheck)
|
||||
if(judgebot.check_for_weapons(l_hand))
|
||||
threatcount += 4
|
||||
if(judgebot.check_for_weapons(r_hand))
|
||||
threatcount += 4
|
||||
for(var/obj/item/I in held_items)
|
||||
if(judgebot.check_for_weapons(I))
|
||||
threatcount += 4
|
||||
|
||||
//mindshield implants imply trustworthyness
|
||||
if(isloyal(src))
|
||||
if(isloyal())
|
||||
threatcount -= 1
|
||||
|
||||
return threatcount
|
||||
|
||||
/mob/living/carbon/monkey/acid_act(acidpwr, toxpwr, acid_volume)
|
||||
if(wear_mask)
|
||||
if(!wear_mask.unacidable)
|
||||
wear_mask.acid_act(acidpwr)
|
||||
update_inv_wear_mask()
|
||||
else
|
||||
src << "<span class='warning'>Your mask protects you from the acid.</span>"
|
||||
return
|
||||
|
||||
take_organ_damage(min(6*toxpwr, acid_volume * acidpwr/10))
|
||||
|
||||
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
|
||||
if(health < 0 && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.do_cpr(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/get_permeability_protection()
|
||||
var/protection = 0
|
||||
if(head)
|
||||
@@ -298,13 +134,6 @@
|
||||
protection = protection/7 //the rest of the body isn't covered.
|
||||
return protection
|
||||
|
||||
/mob/living/carbon/monkey/check_eye_prot()
|
||||
var/number = ..()
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/monkey/fully_heal(admin_revive = 0)
|
||||
if(!getorganslot("lungs"))
|
||||
var/obj/item/organ/lungs/L = new()
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
|
||||
/mob/living/carbon/monkey/get_eye_protection()
|
||||
var/number = ..()
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask))
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
return number
|
||||
|
||||
/mob/living/carbon/monkey/help_shake_act(mob/living/carbon/M)
|
||||
if(health < 0 && ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
H.do_cpr(src)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/living/carbon/monkey/attack_paw(mob/living/M)
|
||||
if(..()) //successful monkey bite.
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(M.limb_destroyer)
|
||||
dismembering_strike(M, affecting.body_zone)
|
||||
if(stat != DEAD)
|
||||
var/dmg = rand(1, 5)
|
||||
apply_damage(dmg, BRUTE, affecting)
|
||||
damage_clothes(dmg, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_larva(mob/living/carbon/alien/larva/L)
|
||||
if(..()) //successful larva bite.
|
||||
var/damage = rand(1, 3)
|
||||
if(stat != DEAD)
|
||||
L.amount_grown = min(L.amount_grown + damage, L.max_grown)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(L.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
/mob/living/carbon/monkey/attack_hand(mob/living/carbon/human/M)
|
||||
if(..()) //To allow surgery to return properly.
|
||||
return
|
||||
|
||||
switch(M.a_intent)
|
||||
if("help")
|
||||
help_shake_act(M)
|
||||
if("grab")
|
||||
grabbedby(M)
|
||||
if("harm")
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
|
||||
if (prob(75))
|
||||
visible_message("<span class='danger'>[M] has punched [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
var/damage = rand(5, 10)
|
||||
if (prob(40))
|
||||
damage = rand(10, 15)
|
||||
if ( (paralysis < 5) && (health > 0) )
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has knocked out [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has knocked out [name]!</span>", null, 5)
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
add_logs(M, src, "attacked")
|
||||
|
||||
else
|
||||
playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to punch [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to punch [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if("disarm")
|
||||
if (!paralysis)
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
|
||||
if (prob(25))
|
||||
Paralyse(2)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has pushed down [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
if(drop_item())
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/carbon/monkey/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if(..()) //if harm or disarm intent.
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if ((prob(95) && health > 0))
|
||||
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
|
||||
var/damage = rand(15, 30)
|
||||
if (damage >= 25)
|
||||
damage = rand(20, 40)
|
||||
if (paralysis < 15)
|
||||
Paralyse(rand(10, 15))
|
||||
visible_message("<span class='danger'>[M] has wounded [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has wounded [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
visible_message("<span class='danger'>[M] has slashed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has slashed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
add_logs(M, src, "attacked")
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
if(!dismembering_strike(M, affecting.body_zone)) //Dismemberment successful
|
||||
return 1
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
else
|
||||
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has attempted to lunge at [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has attempted to lunge at [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if (M.a_intent == INTENT_DISARM)
|
||||
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
|
||||
if(prob(95))
|
||||
Weaken(10)
|
||||
visible_message("<span class='danger'>[M] has tackled down [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has tackled down [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
else
|
||||
if(drop_item())
|
||||
visible_message("<span class='danger'>[M] has disarmed [name]!</span>", \
|
||||
"<span class='userdanger'>[M] has disarmed [name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
add_logs(M, src, "disarmed")
|
||||
updatehealth()
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_animal(mob/living/simple_animal/M)
|
||||
if(..())
|
||||
var/damage = rand(M.melee_damage_lower, M.melee_damage_upper)
|
||||
var/dam_zone = dismembering_strike(M, pick("chest", "l_hand", "r_hand", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, M.melee_damage_type, affecting)
|
||||
damage_clothes(damage, M.melee_damage_type, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/attack_slime(mob/living/simple_animal/slime/M)
|
||||
if(..()) //successful slime attack
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
var/dam_zone = dismembering_strike(M, pick("head", "chest", "l_arm", "r_arm", "l_leg", "r_leg"))
|
||||
if(!dam_zone) //Dismemberment successful
|
||||
return 1
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(dam_zone))
|
||||
if(!affecting)
|
||||
affecting = get_bodypart("chest")
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
damage_clothes(damage, BRUTE, "melee", affecting.body_zone)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/acid_act(acidpwr, acid_volume, bodyzone_hit)
|
||||
. = 1
|
||||
if(!bodyzone_hit || bodyzone_hit == "head")
|
||||
if(wear_mask)
|
||||
if(!(wear_mask.resistance_flags & UNACIDABLE))
|
||||
wear_mask.acid_act(acidpwr)
|
||||
else
|
||||
src << "<span class='warning'>Your mask protects you from the acid.</span>"
|
||||
return
|
||||
if(head)
|
||||
if(!(head.resistance_flags & UNACIDABLE))
|
||||
head.acid_act(acidpwr)
|
||||
else
|
||||
src << "<span class='warning'>Your hat protects you from the acid.</span>"
|
||||
return
|
||||
take_bodypart_damage(acidpwr * min(0.6, acid_volume*0.1))
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/ex_act(severity, target, origin)
|
||||
if(origin && istype(origin, /datum/spacevine_mutation) && isvineimmune(src))
|
||||
return
|
||||
..()
|
||||
|
||||
switch (severity)
|
||||
if (1)
|
||||
gib()
|
||||
return
|
||||
|
||||
if (2)
|
||||
take_overall_damage(60, 60)
|
||||
damage_clothes(200, BRUTE, "bomb")
|
||||
adjustEarDamage(30, 120)
|
||||
if(prob(70))
|
||||
Paralyse(10)
|
||||
|
||||
if(3)
|
||||
take_overall_damage(30, 0)
|
||||
damage_clothes(50, BRUTE, "bomb")
|
||||
adjustEarDamage(15,60)
|
||||
if (prob(50))
|
||||
Paralyse(8)
|
||||
|
||||
|
||||
//attempt to dismember bodyparts
|
||||
if(severity <= 2)
|
||||
var/max_limb_loss = round(4/severity) //so you don't lose four limbs at severity 3.
|
||||
for(var/X in bodyparts)
|
||||
var/obj/item/bodypart/BP = X
|
||||
if(prob(50/severity) && BP.body_zone != "chest")
|
||||
BP.brute_dam = BP.max_damage
|
||||
BP.dismember()
|
||||
max_limb_loss--
|
||||
if(!max_limb_loss)
|
||||
break
|
||||
@@ -11,14 +11,10 @@
|
||||
|
||||
/mob/living/carbon/monkey/punpun/New()
|
||||
Read_Memory()
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
|
||||
if(ancestor_name)
|
||||
name = ancestor_name
|
||||
if(ancestor_chain > 1)
|
||||
name += " [num2roman(ancestor_chain)]"
|
||||
name += " \Roman[ancestor_chain]"
|
||||
else
|
||||
if(prob(5))
|
||||
name = pick(rare_pet_monkey_names)
|
||||
@@ -27,6 +23,14 @@
|
||||
gender = pick(MALE, FEMALE)
|
||||
..()
|
||||
|
||||
//These have to be after the parent new to ensure that the monkey
|
||||
//bodyparts are actually created before we try to equip things to
|
||||
//those slots
|
||||
if(relic_hat)
|
||||
equip_to_slot_or_del(new relic_hat, slot_head)
|
||||
if(relic_mask)
|
||||
equip_to_slot_or_del(new relic_mask, slot_wear_mask)
|
||||
|
||||
/mob/living/carbon/monkey/punpun/Life()
|
||||
if(ticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
Write_Memory(0)
|
||||
|
||||
@@ -1,29 +1,47 @@
|
||||
|
||||
/mob/living/carbon/monkey/regenerate_icons()
|
||||
if(!..())
|
||||
update_body_parts()
|
||||
update_hair()
|
||||
update_inv_wear_mask()
|
||||
update_inv_head()
|
||||
update_inv_back()
|
||||
update_icons()
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/monkey/update_icons()
|
||||
cut_overlays()
|
||||
icon_state = "monkey1"
|
||||
for(var/image/I in overlays_standing)
|
||||
add_overlay(I)
|
||||
|
||||
////////
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_hair()
|
||||
remove_overlay(HAIR_LAYER)
|
||||
|
||||
var/obj/item/bodypart/head/HD = get_bodypart("head")
|
||||
if(!HD) //Decapitated
|
||||
return
|
||||
|
||||
if(disabilities & HUSK)
|
||||
return
|
||||
|
||||
var/hair_hidden = 0
|
||||
|
||||
if(head)
|
||||
var/obj/item/I = head
|
||||
if(I.flags_inv & HIDEHAIR)
|
||||
hair_hidden = 1
|
||||
if(wear_mask)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
if(M.flags_inv & HIDEHAIR)
|
||||
hair_hidden = 1
|
||||
if(!hair_hidden)
|
||||
if(!getorgan(/obj/item/organ/brain)) //Applies the debrained overlay if there is no brain
|
||||
var/image/I = image("icon"='icons/mob/human_face.dmi', "icon_state" = "debrained", "layer" = -HAIR_LAYER)
|
||||
overlays_standing[HAIR_LAYER] = I
|
||||
apply_overlay(HAIR_LAYER)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/update_fire()
|
||||
..("Monkey_burning")
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = image("icon"='icons/mob/mob.dmi', "icon_state"="handcuff1", "layer"=-HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
/mob/living/carbon/monkey/update_inv_legcuffed()
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
if(legcuffed)
|
||||
@@ -47,6 +65,12 @@
|
||||
I.screen_loc = ui_monkey_mask
|
||||
client.screen += I
|
||||
|
||||
//update whether our neck item appears on our hud.
|
||||
/mob/living/carbon/monkey/update_hud_neck(obj/item/I)
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
I.screen_loc = ui_monkey_mask
|
||||
client.screen += I
|
||||
|
||||
//update whether our back item appears on our hud.
|
||||
/mob/living/carbon/monkey/update_hud_back(obj/item/I)
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
|
||||
@@ -24,3 +24,7 @@
|
||||
var/obj/item/organ/tongue/T = getorganslot("tongue")
|
||||
if(T)
|
||||
. |= T.get_spans()
|
||||
|
||||
var/obj/item/I = get_active_held_item()
|
||||
if(I)
|
||||
. |= I.get_held_item_speechspans(src)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user