From b03a4c259407502df39f3144cfea0b4f9bcf8221 Mon Sep 17 00:00:00 2001 From: uporotiy Date: Sat, 14 May 2011 14:30:46 +0000 Subject: [PATCH] Organs v0.03. The very basic version of the organ system, uploaded mostly for convenience. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1582 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/organs/implants.dm | 13 + code/WorkInProgress/organs/organs.dm | 265 ++++++++++++++++++ code/defines/mob/mob.dm | 4 +- code/defines/procs/helpers.dm | 12 +- code/modules/mob/living/carbon/human/human.dm | 16 +- code/modules/mob/living/carbon/human/life.dm | 2 + code/modules/mob/living/living.dm | 7 +- code/modules/mob/mob.dm | 12 +- icons/mob/organs.dmi | Bin 0 -> 2612 bytes tgstation.dme | 4 + 10 files changed, 328 insertions(+), 7 deletions(-) create mode 100644 code/WorkInProgress/organs/implants.dm create mode 100644 code/WorkInProgress/organs/organs.dm create mode 100644 icons/mob/organs.dmi diff --git a/code/WorkInProgress/organs/implants.dm b/code/WorkInProgress/organs/implants.dm new file mode 100644 index 00000000000..98350ee7f9a --- /dev/null +++ b/code/WorkInProgress/organs/implants.dm @@ -0,0 +1,13 @@ +/*------ +SPELL IMPLANTS + + Most diverse effects + - Limited charges, failure rate + +CYBERNETIC IMPLANTS + + Easiest to make + - Require power + +GRAFTS (includes basic human bodyparts) + + Permanent effects + - Horrible side effects +*/ \ No newline at end of file diff --git a/code/WorkInProgress/organs/organs.dm b/code/WorkInProgress/organs/organs.dm new file mode 100644 index 00000000000..0af9e2eb29f --- /dev/null +++ b/code/WorkInProgress/organs/organs.dm @@ -0,0 +1,265 @@ +//TODO: Move cyber organs active/inactive stats to vars. + +//flags for organType +#define CYBER 1 +#define SPELL 2 + +/obj/organstructure //used obj for the "contents" var + name = "organs" + + var/obj/item/weapon/cell/mainPowerCell = null //for ease of refernce for installed c. implants + var/species = "mob" //for speaking in unknown languages purposes + + var/obj/organ/limb/arms/arms = null + var/obj/organ/limb/legs/legs = null + var/obj/organ/chest/chest = null + + proc/FindMainPowercell() + if(chest) //priority goes to chest implant, if there is one + if((chest.organType & CYBER) && chest.canExportPower && chest.cell) + mainPowerCell = chest.cell + return + var/list/organs = GetAllContents() + for(var/obj/organ/otherOrgan in organs) //otherwise, maybe some other organ fits the criteria? + if((otherOrgan.organType & CYBER) && otherOrgan.canExportPower && otherOrgan.cell) + mainPowerCell = otherOrgan:cell + return + mainPowerCell = null //otherwise, seems there's no main cell + return + + proc/GetSpeciesName() + var/list/speciesPresent = list() + + for(var/obj/organ/organ in src) //only external organs count, since it's judging by the appearance + if(speciesPresent[organ.species]) + speciesPresent[organ.species]++ + else + speciesPresent[organ.species] = 1 //not sure, but I think it's not initialised before that, so can't ++ + + var/list/dominantSpecies = list() + + for(var/speciesName in speciesPresent) + if(!dominantSpecies.len) + dominantSpecies += speciesName + else + if(speciesPresent[dominantSpecies[1]] == speciesPresent[speciesName]) + dominantSpecies += speciesName + else if(speciesPresent[dominantSpecies[1]] < speciesPresent[speciesName]) + dominantSpecies = list(speciesName) + + if(!dominantSpecies.len) + species = "mob" + else + species = pick(dominantSpecies) + + return + + proc/RecalculateStructure() + var/list/organs = GetAllContents() + + arms = locate(/obj/organ/limb/arms) in organs + legs = locate(/obj/organ/limb/legs) in organs + chest = locate(/obj/organ/chest) in organs + + GetSpeciesName() + FindMainPowercell() + + return + + proc/ProcessOrgans() + set background = 1 + + var/list/organs = GetAllContents() + for(var/obj/organ/organ in organs) + organ.ProcessOrgan() + + return + + New() + ..() + RecalculateStructure() + +/obj/organstructure/human + name = "human organs" + + New() + //new /obj/organ/limb/arms/human(src) + //new /obj/organ/limb/legs/human(src) + new /obj/organ/chest/human(src) + ..() + +/obj/organstructure/cyber + name = "cyborg organs" + + New() + //new /obj/organ/limb/arms/cyber(src) + //new /obj/organ/limb/legs/cyber(src) + new /obj/organ/chest/cyber(src) + ..() + +/obj/organ + name = "organ" + + //All types + var/organType = 0 //CYBER and SPELL go here + var/species = "mob" + var/obj/organstructure/rootOrganStructure = null + + New(location) + ..() + + rootOrganStructure = FindRootStructure() + + proc/FindRootStructure() + if(istype(loc,/obj/organ)) + var/obj/organ/parent = loc + return parent.FindRootStructure() + else if(istype(loc,/obj/organstructure)) + return loc + return null + + proc/ProcessOrgan() + set background = 1 + + if(organType & CYBER) + var/hasPower = DrainPower() + if(!hasPower && active) + Deactivate() + else if(hasPower && !active) + Activate() + + //CYBORG type + var/obj/item/weapon/cell/cell = null + var/canExportPower = 0 //only comes in play if it has a cell + var/active = 0 + var/powerDrainPerTick = 0 + + proc/DrainPower() + set background = 1 + + if(!powerDrainPerTick) + return 1 + if(cell) + if(cell.charge >= powerDrainPerTick) + cell.charge -= powerDrainPerTick + return 1 + if(rootOrganStructure.mainPowerCell) + if(rootOrganStructure.mainPowerCell.charge >= powerDrainPerTick) + rootOrganStructure.mainPowerCell.charge -= powerDrainPerTick + return 1 + return 0 + + proc/Activate() //depends on the organ, involves setting active to 1 and changing the organ's vars to reflect its "activated" state + rootOrganStructure.loc << "\blue Your [name] powers up!" + active = 1 + return + + proc/Deactivate() //depends on the organ, involves setting active to 0 and changing the organ's vars to reflect its "deactivated" state + rootOrganStructure.loc << "\red Your [name] powers down." + active = 0 + return + +/obj/organ/limb + name = "limb" + +/obj/organ/limb/arms + name = "arms" + + var/minDamage = 5 //punching damage + var/maxDamage = 5 +// var/strangleDelay = 1 //The code is a bit too complicated for that right now + +/obj/organ/limb/arms/human + name = "human arms" + species = "human" + minDamage = 1 + maxDamage = 9 + +/obj/organ/limb/arms/cyber + name = "cyborg arms" + species = "cyborg" + organType = CYBER + powerDrainPerTick = 5 + + Activate() + ..() + minDamage = 3 + maxDamage = 14 + + Deactivate() + ..() + minDamage = 0 + maxDamage = 3 + + +/obj/organ/limb/legs + name = "legs" + + var/moveRunDelay = 1 //not sure about how that works + var/moveWalkDelay = 7 + //var/knockdownResist = 0 + +/obj/organ/limb/legs/human + name = "human legs" + species = "human" + +/obj/organ/limb/legs/cyber + name = "cyborg legs" + species = "cyborg" + organType = CYBER + powerDrainPerTick = 5 + + Activate() + ..() + moveRunDelay = 0 + moveWalkDelay = 3 + + Deactivate() + ..() + moveRunDelay = 2 + moveWalkDelay = 10 + + +/obj/organ/chest + name = "chest" + var/maxHealth = 50 //right now, the mob's (only humans for now) health depends only on it. Will be fixed later + +/obj/organ/chest/human + name = "human chest" + species = "human" + maxHealth = 100 + + New() + ..() + new /obj/organ/limb/arms/human(src) + new /obj/organ/limb/legs/human(src) + +/obj/organ/chest/cyber + name = "cyborg chest" + species = "cyborg" + organType = CYBER + canExportPower = 1 + maxHealth = 150 + + New() + ..() + cell = new /obj/item/weapon/cell/high(src) + cell.charge = cell.maxcharge + new /obj/organ/limb/arms/cyber(src) + new /obj/organ/limb/legs/cyber(src) + + Activate() + ..() + canExportPower = 1 + maxHealth = 150 + if(rootOrganStructure.loc && istype(rootOrganStructure.loc,/mob/living)) + var/mob/living/holder = rootOrganStructure.loc + holder.updatehealth() + + Deactivate() + ..() + canExportPower = 0 + maxHealth = 120 + if(rootOrganStructure.loc && istype(rootOrganStructure.loc,/mob/living)) + var/mob/living/holder = rootOrganStructure.loc + holder.updatehealth() \ No newline at end of file diff --git a/code/defines/mob/mob.dm b/code/defines/mob/mob.dm index 282753e90ef..0e6d94265e3 100644 --- a/code/defines/mob/mob.dm +++ b/code/defines/mob/mob.dm @@ -196,4 +196,6 @@ var/update_icon = 1 // Set to 0 if you want that the mob's icon doesn't update when it moves -- Skie // This can be used if you want to change the icon on the fly and want it to stay - var/UI = 'screen1_old.dmi' // For changing the UI from preferences \ No newline at end of file + var/UI = 'screen1_old.dmi' // For changing the UI from preferences + + var/obj/organstructure/organStructure = null //for dem organs \ No newline at end of file diff --git a/code/defines/procs/helpers.dm b/code/defines/procs/helpers.dm index f38a6543412..e195ba3da53 100644 --- a/code/defines/procs/helpers.dm +++ b/code/defines/procs/helpers.dm @@ -1036,4 +1036,14 @@ proc/isemptylist(list/list) proc/clearlist(list/list) if(istype(list)) list.len = 0 - return \ No newline at end of file + return + +/atom/proc/GetAllContents(searchDepth = 5) + var/list/toReturn = list() + + for(var/atom/part in contents) + toReturn += part + if(part.contents.len && searchDepth) + toReturn += part.GetAllContents(searchDepth - 1) + + return toReturn \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index fe40924810a..2e1a7bc375f 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -59,8 +59,18 @@ src.icon = src.stand_icon update_clothing() src << "\blue Your icons have been generated!" + ..() + organStructure = new /obj/organstructure/human(src) + +/mob/living/carbon/human/cyborg + New() + ..() + if(organStructure) //hacky, but it's not supposed to be in for a long time anyway + del(organStructure) + organStructure = new /obj/organstructure/cyber(src) + /mob/living/carbon/human/Bump(atom/movable/AM as mob|obj, yes) if ((!( yes ) || src.now_pushing)) return @@ -1699,7 +1709,11 @@ if (M.a_intent == "hurt" && !(M.gloves && M.gloves.elecgen == 1)) if (src.w_uniform) src.w_uniform.add_fingerprint(M) - var/damage = rand(1, 9) + var/damage = 0 + if(organStructure && organStructure.arms) + damage = rand(organStructure.arms.minDamage,organStructure.arms.maxDamage) + else + damage = rand(1, 9) //oh boy var/datum/organ/external/affecting = src.organs["chest"] var/t = M.zone_sel.selecting if ((t in list( "eyes", "mouth" ))) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index f3d14cd0852..b846d038069 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -80,6 +80,8 @@ for(var/obj/item/weapon/grab/G in src) G.process() + ..() //for organs + /* ................................................ ..........................._,-~"¯¯"~-, .................................................. ................__„-~"¯¯:::,-~~-,_::::"- diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index 3797e3beb28..d7b13222178 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -74,8 +74,11 @@ /mob/living/proc/updatehealth() - if (src.nodamage == 0) - src.health = 100 - src.oxyloss - src.toxloss - src.fireloss - src.bruteloss + if (!src.nodamage) + if(organStructure && organStructure.chest) + health = organStructure.chest.maxHealth - oxyloss - toxloss - fireloss - bruteloss + else + src.health = 100 - src.oxyloss - src.toxloss - src.fireloss - src.bruteloss else src.health = 100 src.stat = 0 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 17643ae2d52..5ec51f915a6 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1060,6 +1060,8 @@ proc/isobserver(A) return 0 /mob/proc/Life() + if(organStructure) + organStructure.ProcessOrgans() return /mob/proc/update_clothing() @@ -1816,12 +1818,18 @@ proc/isobserver(A) if("run") if (mob.drowsyness > 0) move_delay += 6 - move_delay += 1 + if(mob.organStructure && mob.organStructure.legs) + move_delay += mob.organStructure.legs.moveRunDelay + else + move_delay += 1 if("face") mob.dir = direct return if("walk") - move_delay += 7 + if(mob.organStructure && mob.organStructure.legs) + move_delay += mob.organStructure.legs.moveWalkDelay + else + move_delay += 7 move_delay += mob.movement_delay() diff --git a/icons/mob/organs.dmi b/icons/mob/organs.dmi new file mode 100644 index 0000000000000000000000000000000000000000..de56c52c9179497d2d55a4ee43ee19620c0c5f08 GIT binary patch literal 2612 zcmbtWdpy+J7XJ;x9k1r}@W>-$gqu7fPTolvjz^Rc9YZ37Gt7)Z&6tQ%9!1O{BF~(L zqU4bfX(F#NGkF%{cn{_bX&A5j^SPhT{qNpC?)hVX*JrP__jj+oKWneGl3ktcq@W5= z005+r_BL*yEZiI7q9ESyyLJK;4`VNQ;%ox2{*l2LT<~w<01%y*+FcDz&^u_$KF!x6 z;dE>9J#KLIgyyp$;Z9c9JEiXZHvZK6=>uLXts;W697Uc#5tfIj(hYiDZct$^P%Mmi z_W-I`{-8y5I3UUPl(LNTP0YD28lpc4X`borSxDb%ZSAEXDTlQ(4O|i*>8Km0{Lo_;WjxRN<*Pbw{!Fw;N`ujy7k5>FNX?0LF%cx7;hZz8? z_8C|V8O$3^ygs*+p(xdaHhNC;BgN=ZGRy9+fC6>*_8^tu$hLo~(~IW9!4 z*>udmqDZEmbC}g!UovPpG`{8HK~sq>W>xPH5bXq!+<*}im+PX`irren6--&~-MM_W zuAcA+8Jk~VaRX^{$JT=?ucV-FC{cDwxNU^VI&kRHks8fhomTrS)^PEd-<_MDw=9-b990F6HMw ziT0vk9f(cRb3)*>=!0zk>(FFf-&pZVYC2$&w?Z3lz!#Sd<7dC5X5^^8ZnO}Z!*I|; zR>E8#2LACa!V9`U)~LP+RQvAjFZ|&6CsxpAXi;|y>d+M27azqO-1bl$D%aDuBAAaC zZsbJ31y5&2d-}$T-?pRO{jQMj{-OA*ia}ul(er`>+8iA;_Xb3JmBU#k&3mld#r)*E zLHQc@w{{B4dMd_M4sy&cIfiqm1VbXGW33ZX0uudLBa)Sy-8b(3u6}Dmim~7_wotfb zKEm0PkW_xUd_UWPzcC*;32_=*=zqQSp;EdrC)%oXbE}MnvM#M9?K}zTS>yd0AzdCS z2p_u}LZWnh3aejGBey~y|NYQ(AOL40ZN~DSU@vEWddtAV5q65kI-dDefMENK>gU?; zq{YUIf9fx858*SWy?P2J#IE(Tt3SEX(LvPEv!Lj#AB_Ynus0WxRM#QclgdEQb>{M)>r80mm21Q{a@!!IVx%ELU^B zf3G&Mo+p-;N|z0hN{taTii3^HN3pfK*u$;}?s({QTbi4i^( zS7q#NpC&$CK;N{=j8qcXaWh{uWmrerJc_BK)6ZUXyMCkGRfo&vloj8hK1a`d&4v!I z2)Y8ITrFoBrVw9~(-oR^yU8ZeHE0AJeyPfdxbMvF95G{hM19bE`UevW`g^&$8RQIi zF~1f}OcdysOBfV7V>^-edYJ+!u5%KO)gk%pJoUw6FlfSJXCN%4;kv2DMzzf#hJlQI zZfa&^jcpkV-Am1l))4XZ6aAk#xC%NEQXW@+Bc%Sw!ZkQ5KgD%62k!EygTc zjBU~$9I*cUTWCegPo@jcwbCC4@gxJ@TEc=nh=a|tW@DbZ&Rg3S_^m10BjTdoXPQ3v zL8!a20@*k)EyJS*mBXpBZ^zBl%;yPp%&0IRdC_!f4w=@nV=HX8elq#_4+zE7ZQj4q za(D4d9jF$Ky;bs_1=$LXjIXsAoH5R188YiL9Jt{65CJX8zB4-TBe)(JdxG<$#IG%Rmc<6TA)`r>NRHiQO3< zKo$xAjT=tFoea!Ew#V1DVE~pn+e=4gpv_um$tb}7W%iu(#EYGwW5+CA1{eYsB*<@F zGrE?92fWx+R+IfL~M{$((XaET$mb0Kd)