diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index fd9d33c7d53..33d0f78d5f5 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -54,12 +54,10 @@ /datum/game_mode/blob/proc/life() - if (blobs.len > 0) + if(active_blobs.len) for(var/i = 1 to 10) sleep(-1) - if (blobs.len == 0) - break - + if(!active_blobs.len) break var/obj/blob/B = pick(active_blobs) if(B.z != 1) continue diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 6f26d493a26..d9c9d8333c2 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -1,4 +1,4 @@ - +//I will need to recode parts of this but I am way too tired atm /obj/blob name = "blob" icon = 'blob.dmi' @@ -11,11 +11,13 @@ active = 1 health = 30 brute_resist = 4 + fire_resist = 1 blobtype = "Blob" blobdebug = 0 /*Types Blob Node + Core Factory Shield */ @@ -34,13 +36,13 @@ blobs -= src if(active) active_blobs -= src - if(blobtype == "Node") + if((blobtype == "Node") || (blobtype == "Core")) processing_objects.Remove(src) ..() CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if( (air_group && blobtype != "Shield") || (height==0)) return 1 + if((air_group && blobtype != "Shield") || (height==0)) return 1 if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 return 0 @@ -49,10 +51,11 @@ if(blobtype != "Blob") return desc = "This really needs a better sprite." //Spaceeeeeeblobbb - if((istype(src.loc, /turf/space)) || (blobdebug == 3)) + if((istype(src.loc, /turf/space)) || (blobdebug == 4)) active = 0 - health = 60 - brute_resist = 2 + health = min(health*2, 100) + brute_resist = 1 + fire_resist = 2 name = "strong blob" icon_state = "blob_idle"//needs a new sprite blobtype = "Shield" @@ -61,16 +64,30 @@ //Commandblob if((blobdebug == 1)) active = 0 - health = 100 - name = "solid blob" + health = min(health*4, 200) + brute_resist = 2 + fire_resist = 2 + name = "blob core" + icon_state = "blob_node"//needs a new sprite + blobtype = "Core" + active_blobs -= src + processing_objects.Add(src) + return 1 + //Nodeblob + if((blobdebug == 2)) + active = 0 + health = min(health*3, 150) + brute_resist = 1 + fire_resist = 2 + name = "blob node" icon_state = "blob_node"//needs a new sprite blobtype = "Node" active_blobs -= src processing_objects.Add(src) return 1 - if((blobdebug == 2)) - health += 20 - name = "odd blob" + if((blobdebug == 3)) + health = min(health*2, 100) + name = "porous blob" icon_state = "blob_factory"//needs a new sprite blobtype = "Factory" return 1 @@ -83,16 +100,16 @@ return - proc/Pulse(var/pulse = 0, var/origin_dir = 0) + proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand set background = 1 - if(blobtype != "Node") + if((blobtype != "Node") && (blobtype != "Core"))//This is so bad if(special_action())//If we can do something here then we dont need to pulse more return if(check_mutations()) return if((blobtype == "Blob") && (pulse <= 2)) - blobdebug = 3 + blobdebug = 4 check_mutations() return @@ -114,13 +131,19 @@ return - proc/special_action()//For things like the set background = 1 switch(blobtype) if("Factory") new/obj/critter/blob(src.loc) return 1 + if("Core") + spawn(0)//Needs to be changed + Pulse(0,1) + Pulse(0,2) + Pulse(0,4) + Pulse(0,8) + return 1 if("Node") spawn(0) Pulse(0,0) @@ -140,37 +163,38 @@ proc/expand(var/turf/T = null) - if(!prob(health)) return + if(!prob(health)) return//TODO: Change this to prob(health + o2 mols or such) if(!T) var/list/dirs = list(1,2,4,8) for(var/i = 1 to 4) var/dirn = pick(dirs) dirs.Remove(dirn) T = get_step(src, dirn) - if((locate(/obj/blob) in T)) continue + if((locate(/obj/blob) in T)) + T = null + continue else break if(T) var/obj/blob/B = new /obj/blob(src.loc, min(src.health, 30)) if(T.Enter(B,src)) B.loc = T else - for(var/atom/A in T)//This might be killing the spores, it IS killing the spores - A.blob_act() T.blob_act() del(B) + for(var/atom/A in T)//This might be killing the spores, it IS killing the spores and come to think of it I am ok with this + A.blob_act() return ex_act(severity) switch(severity) if(1) - src.health -= rand(90,150) + src.health -= rand(40,60) if(2) - src.health -= rand(60,90) - src.update() + src.health -= rand(20,40) if(3) - src.health -= rand(30,40) - src.update() + src.health -= rand(15,20) + src.update() proc/update()//Needs to be updated with the types @@ -188,7 +212,15 @@ bullet_act(var/obj/item/projectile/Proj) - health -= Proj.damage + for(var/i = 1, i<= Proj.mobdamage.len, i++) + switch(i) + if(1) + var/d = Proj.mobdamage[BRUTE] + health -= (d / max(src.brute_resist,1)) + if(2) + var/d = Proj.mobdamage[BURN] + health -= (d / max(src.fire_resist,1)) + //health -= Proj.damage ..() update() @@ -199,7 +231,7 @@ var/damage = 0 switch(W.damtype) if("fire") - damage = (W.force) + damage = (W.force / max(src.fire_resist,1)) if(istype(W, /obj/item/weapon/weldingtool)) playsound(src.loc, 'Welder.ogg', 100, 1) if("brute") @@ -251,6 +283,7 @@ src.mach++ + /datum/station_state/proc/score(var/datum/station_state/result) var/r1a = min( result.floor / max(floor,1), 1.0) var/r1b = min(result.r_wall/ max(r_wall,1), 1.0) @@ -269,6 +302,7 @@ desc = "it looks... tasty" icon_state = "blobidle0" + New(loc, var/h = 10) src.health = h src.dir = pick(1,2,4,8) @@ -294,14 +328,22 @@ B.Life() ..() -/obj/blob/node/New() + + +/obj/blob/core/New() ..() spawn() src.blobdebug = 1 src.Life() -/obj/blob/factory/New() +/obj/blob/node/New() ..() spawn() src.blobdebug = 2 + src.Life() + +/obj/blob/factory/New() + ..() + spawn() + src.blobdebug = 3 src.Life() \ No newline at end of file diff --git a/code/game/gamemodes/events/miniblob.dm b/code/game/gamemodes/events/miniblob.dm index d16667d8508..b2c3a6a65df 100644 --- a/code/game/gamemodes/events/miniblob.dm +++ b/code/game/gamemodes/events/miniblob.dm @@ -18,11 +18,10 @@ /proc/dotheblobbaby() if (blobevent) - if (blobs.len > 0) + if(active_blobs.len) for(var/i = 1 to 10) sleep(-1) - if (blobs.len == 0) - break + if(!active_blobs.len) break var/obj/blob/B = pick(active_blobs) if(B.z != 1) continue diff --git a/code/game/machinery/cloning.dm b/code/game/machinery/cloning.dm index a80903c5cfe..7706476c044 100644 --- a/code/game/machinery/cloning.dm +++ b/code/game/machinery/cloning.dm @@ -332,7 +332,7 @@ //Add an implant if needed - var/obj/item/weapon/implant/health/imp =locate(/obj/item/weapon/implant/health, subject) + var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject) if (isnull(imp)) imp = new /obj/item/weapon/implant/health(subject) imp.implanted = subject @@ -436,7 +436,7 @@ //Start growing a human clone in the pod! /obj/machinery/clonepod/proc/growclone(mob/ghost as mob, var/clonename, var/ui, var/se, var/mindref, var/mrace, var/UI, var/datum/changeling/changelingClone) - if (((!ghost) || (!ghost.client)) || src.mess || src.attempting) + if(((!ghost) || (!ghost.client)) || src.mess || src.attempting) return 0 src.attempting = 1 //One at a time!! @@ -462,7 +462,7 @@ src.occupant << "\blue Clone generation process initiated." src.occupant << "\blue This will take a moment, please hold." - if (clonename) + if(clonename) src.occupant.real_name = clonename else src.occupant.real_name = "clone" //No null names!! @@ -484,15 +484,15 @@ // -- Mode/mind specific stuff goes here switch(ticker.mode.name) - if ("revolution") + if("revolution") if(src.occupant.mind in ticker.mode:revolutionaries) ticker.mode:update_all_rev_icons() //So the icon actually appears if(src.occupant.mind in ticker.mode:head_revolutionaries) ticker.mode:update_all_rev_icons() - if ("nuclear emergency") + if("nuclear emergency") if (src.occupant.mind in ticker.mode:syndicates) ticker.mode:update_all_synd_icons() - if ("cult") + if("cult") if (src.occupant.mind in ticker.mode:cult) ticker.mode:add_cultist(src.occupant.mind) ticker.mode:update_all_cult_icons() //So the icon actually appears @@ -506,15 +506,15 @@ occupant:UI = UI - if (istype(ghost, /mob/dead/observer)) + if(istype(ghost, /mob/dead/observer)) del(ghost) //Don't leave ghosts everywhere!! - if (!src.occupant.dna) + if(!src.occupant.dna) src.occupant.dna = new /datum/dna( ) - if (ui) + if(ui) src.occupant.dna.uni_identity = ui updateappearance(src.occupant, ui) - if (se) + if(se) src.occupant.dna.struc_enzymes = se randmutb(src.occupant) //Sometimes the clones come out wrong. src.occupant:update_face() @@ -527,13 +527,13 @@ //Grow clones to maturity then kick them out. FREELOADERS /obj/machinery/clonepod/process() - if (stat & NOPOWER) //Autoeject if power is lost + if(stat & NOPOWER) //Autoeject if power is lost if (src.occupant) src.locked = 0 src.go_out() return - if ((src.occupant) && (src.occupant.loc == src)) + if((src.occupant) && (src.occupant.loc == src)) if((src.occupant.stat == 2) || (src.occupant.suiciding)) //Autoeject corpses and suiciding dudes. src.locked = 0 src.go_out() @@ -650,7 +650,7 @@ return /obj/machinery/clonepod/proc/malfunction() - if (src.occupant) + if(src.occupant) src.connected_message("Critical Error!") src.mess = 1 src.icon_state = "pod_g" diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index cdad34db610..cc4f791fbaa 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -271,14 +271,16 @@ /mob/living/carbon/human/abiotic() - if ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.ears || src.gloves)) +// if ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || (src.back || src.wear_mask || src.head || src.shoes || src.w_uniform || src.wear_suit || src.glasses || src.ears || src.gloves)) + if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract ))) return 1 else return 0 return /mob/proc/abiotic() - if ((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || src.back || src.wear_mask) +// if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract )) || src.back || src.wear_mask) + if((src.l_hand && !( src.l_hand.abstract )) || (src.r_hand && !( src.r_hand.abstract ))) return 1 else return 0 diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 851308d1615..29576d12d83 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -163,6 +163,7 @@ verbs += /client/proc/only_one verbs += /client/proc/send_space_ninja verbs += /client/proc/restartcontroller //Can call via aproccall --I_hate_easy_things.jpg, Mport --Agouri + verbs += /client/proc/Blobize//I need to remember to move/remove this later if (holder.level >= 4)//Badmin******************************************************************** verbs += /obj/admins/proc/adrev //toggle admin revives @@ -376,6 +377,7 @@ verbs -= /client/proc/play_local_sound verbs -= /client/proc/enable_mapping_debug verbs -= /client/proc/toggleprayers + verbs -= /client/proc/Blobize return diff --git a/code/modules/mob/living/blob/blob.dm b/code/modules/mob/living/blob/blob.dm new file mode 100644 index 00000000000..d23fb4a658f --- /dev/null +++ b/code/modules/mob/living/blob/blob.dm @@ -0,0 +1,207 @@ +/mob/living/blob + name = "blob fragment" + real_name = "blob fragment" + icon = 'blob.dmi' + icon_state = "blob_spore_temp" + pass_flags = PASSBLOB + see_in_dark = 8 + see_invisible = 2 + var + ghost_name = "Unknown" + creating_blob = 0 + + +/mob/living/blob/New() + real_name += " [pick(rand(1, 99))]" + name = real_name + ..() + + +/mob/living/blob/say(var/message) + return//No talking for you + + +/mob/living/blob/emote(var/act,var/m_type=1,var/message = null) + return + + +/mob/living/blob/Life() + set invisibility = 0 + set background = 1 + + clamp_values() + UpdateDamage() + if(health < 0) + src.death(1) + + +/mob/living/blob + proc + + clamp_values() + stunned = 0//No stun here + paralysis = 0 + weakened = 0 + sleeping = 0 + bruteloss = max(bruteloss, 0) + toxloss = max(toxloss, 0) + oxyloss = max(oxyloss, 0) + fireloss = max(fireloss, 0) + if(stat) + stat = 0 + return + + + UpdateDamage() + health = 60 - (oxyloss + toxloss + fireloss + bruteloss + cloneloss) + return + + +/mob/living/blob/death(gibbed) + if(key) + var/mob/dead/observer/ghost = new(src) + ghost.name = ghost_name + ghost.real_name = ghost_name + ghost.key = key + if (ghost.client) + ghost.client.eye = ghost +// spawn(10) +// del(src) + src.gib() +// return ..(gibbed) + + +/mob/living/blob/bullet_act(var/obj/item/projectile/Proj) + for(var/i = 1, i<= Proj.mobdamage.len, i++) + switch(i) + if(1) + bruteloss = Proj.mobdamage[BRUTE] + if(2) + fireloss = Proj.mobdamage[BURN] + return + + +/mob/living/blob/blob_act() + src << "The blob attempts to reabsorb you." + toxloss += 10 + return + + +/mob/living/blob/verb/create_node() + set category = "Blob" + set name = "Create Node" + set desc = "Create a Node." + if(creating_blob) return + var/turf/T = get_turf(src) + creating_blob = 1 + if(!T) + creating_blob = 0 + return + var/obj/blob/B = (locate(/obj/blob) in T) + if(!B)//We are on a blob + usr << "There is no blob here!" + creating_blob = 0 + return + if(B.blobtype != "Blob") + usr << "Unable to use this blob, find another one." + creating_blob = 0 + return + for(var/obj/blob/blob in orange(5)) + if(blob.blobtype == "Node") + usr << "There is another node nearby, move away from it!" + creating_blob = 0 + return + B.blobdebug = 2 + spawn(0) + B.Life() + death(1) + return + + +/mob/living/blob/verb/create_factory() + set category = "Blob" + set name = "Create Defense" + set desc = "Create a Spore producing blob." + if(creating_blob) return + var/turf/T = get_turf(src) + creating_blob = 1 + if(!T) + creating_blob = 0 + return + var/obj/blob/B = (locate(/obj/blob) in T) + if(!B) + usr << "There is no blob here!" + creating_blob = 0 + return + if(B.blobtype != "Blob") + usr << "Unable to use this blob, find another one." + creating_blob = 0 + return + for(var/obj/blob/blob in orange(1))//Not right next to nodes/cores + if(blob.blobtype == "Node") + usr << "There is a node nearby, move away from it!" + creating_blob = 0 + return + if(blob.blobtype == "Core") + usr << "There is a core nearby, move away from it!" + creating_blob = 0 + return + B.blobdebug = 3 + spawn(0) + B.Life() + death(1) + return + + +///mob/proc/Blobize() +/client/proc/Blobize()//Mostly stolen from the respawn command + set category = "Debug" + set name = "Ghostblob" + set desc = "Ghost into blobthing." + set hidden = 1 + + if(!authenticated || !holder) + src << "Only administrators may use this command." + return + var/input = input(src, "Please specify which key will be turned into a bloby.", "Key", "") + if(!input) + return + + var/mob/dead/observer/G_found + if(input == "Random") + var/list/ghosts = list() + for(var/mob/dead/observer/G in world) + if(G.client) + ghosts += G + if(ghosts.len) + G_found = pick(ghosts) + + else + for(var/mob/dead/observer/G in world) + if(G.client&&ckey(G.key)==ckey(input)) + G_found = G + break + + if(!G_found)//If a ghost was not found. + alert("There is no active key like that in the game or the person is not currently a ghost. Aborting command.") + return + + if(G_found.client) + G_found.client.screen.len = null + var/mob/living/blob/B = new/mob/living/blob(locate(0,0,1))//temp area also just in case should do this better but tired + for(var/obj/blob/core in world) + if(core) + if(core.blobtype == "Core") + B.loc = core.loc + B.ghost_name = G_found.real_name + if (G_found.client) + G_found.client.mob = B + B.verbs += /mob/living/blob/verb/create_node + B.verbs += /mob/living/blob/verb/create_factory + B << "You are now a blob fragment." + B << "You are a weak bit that has temporarily broken off of the blob." + B << "If you stay on the blob for too long you will likely be reabsorbed." + B << "If you stray from the blob you will likely be killed by other organisms." + B << "You have the power to create a new blob node that will help expand the blob." + B << "To create this node you will have to be on a normal blob tile and far enough away from any other node." + B << "Check your Blob verbs and hit Create Node to build a node." diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi index b7aa9f013e7..80f7ee82bf1 100644 Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi index 315e397bc29..0600ff1624a 100644 Binary files a/icons/mob/critter.dmi and b/icons/mob/critter.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 4cd88479901..dd6dbda63d1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -93,6 +93,7 @@ #define FILE_DIR "code/modules/mob/dead" #define FILE_DIR "code/modules/mob/dead/observer" #define FILE_DIR "code/modules/mob/living" +#define FILE_DIR "code/modules/mob/living/blob" #define FILE_DIR "code/modules/mob/living/carbon" #define FILE_DIR "code/modules/mob/living/carbon/alien" #define FILE_DIR "code/modules/mob/living/carbon/alien/humanoid" @@ -735,6 +736,7 @@ #include "code\modules\mob\dead\observer\say.dm" #include "code\modules\mob\living\living.dm" #include "code\modules\mob\living\say.dm" +#include "code\modules\mob\living\blob\blob.dm" #include "code\modules\mob\living\carbon\carbon.dm" #include "code\modules\mob\living\carbon\alien\say.dm" #include "code\modules\mob\living\carbon\alien\humanoid\alien_powers.dm"