diff --git a/code/_onclick/overmind.dm b/code/_onclick/overmind.dm new file mode 100644 index 00000000000..91f24465569 --- /dev/null +++ b/code/_onclick/overmind.dm @@ -0,0 +1,17 @@ +// Blob Overmind Controls + + +/mob/camera/blob/CtrlClickOn(var/atom/A) // Expand blob + var/turf/T = get_turf(A) + if(T) + expand_blob(T) + +/mob/camera/blob/MiddleClickOn(var/atom/A) // Rally spores + var/turf/T = get_turf(A) + if(T) + rally_spores(T) + +/mob/camera/blob/AltClickOn(var/atom/A) // Create a shield + var/turf/T = get_turf(A) + if(T) + create_shield(T) \ No newline at end of file diff --git a/code/datums/mind.dm b/code/datums/mind.dm index bce844da53c..d8fed878407 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1184,7 +1184,7 @@ datum/mind mind.special_role = "" //BLOB -/mob/camera/overmind/mind_initialize() +/mob/camera/blob/mind_initialize() ..() mind.special_role = "Blob" diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index 868cd62a5f6..1292be0ff22 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -15,12 +15,13 @@ feedback_set_details("round_end_result","loss - blob took over") world << "The blob has taken over the station!" world << "The entire station was eaten by the Blob" - check_quarantine() + log_game("Blob mode was lost.") else if(station_was_nuked) feedback_set_details("round_end_result","halfwin - nuke") world << "Partial Win: The station has been destroyed!" world << "Directive 7-12 has been successfully carried out preventing the Blob from spreading." + log_game("Blob mode was tie (station destroyed).") else if(!blob_cores.len) feedback_set_details("round_end_result","win - blob eliminated") @@ -45,34 +46,4 @@ datum/game_mode/proc/auto_declare_completion_blob() for(var/datum/mind/blob in blob_mode.infected_crew) text += "
[blob.key] was [blob.name]" world << text - return 1 - -/datum/game_mode/blob/proc/check_quarantine() - var/numDead = 0 - var/numAlive = 0 - var/numSpace = 0 - var/numOffStation = 0 - for (var/mob/living/silicon/ai/aiPlayer in mob_list) - for(var/mob/living/carbon/human/M in mob_list) - if ((M != aiPlayer && M.client)) - if (M.stat == 2) - numDead += 1 - else - var/T = M.loc - if (istype(T, /turf/space)) - numSpace += 1 - else if(istype(T, /turf)) - if (M.z!=1) - numOffStation += 1 - else - numAlive += 1 - if (numSpace==0 && numOffStation==0) - world << "The AI has won!" - world << "The AI successfully maintained the quarantine - no players were in space or were off-station (as far as we can tell)." - log_game("AI won at Blob mode despite overall loss.") - else - world << "The AI has lost!" - world << text("The AI failed to maintain the quarantine - [] were in space and [] were off-station (as far as we can tell).", numSpace, numOffStation) - log_game("AI lost at Blob mode.") - log_game("Blob mode was lost.") - return 1 + return 1 \ No newline at end of file diff --git a/code/game/gamemodes/blob/blobs/core.dm b/code/game/gamemodes/blob/blobs/core.dm index a01a40df21c..7abf2c27078 100644 --- a/code/game/gamemodes/blob/blobs/core.dm +++ b/code/game/gamemodes/blob/blobs/core.dm @@ -9,81 +9,77 @@ var/resource_delay = 0 var/point_rate = 2 - New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2) - blob_cores += src - processing_objects.Add(src) - if(!overmind) - create_overmind(new_overmind) - point_rate = new_rate - ..(loc, h) +/obj/effect/blob/core/New(loc, var/h = 200, var/client/new_overmind = null, var/new_rate = 2) + blob_cores += src + processing_objects.Add(src) + if(!overmind) + create_overmind(new_overmind) + point_rate = new_rate + ..(loc, h) - Del() - blob_cores -= src - if(overmind) - del(overmind) - processing_objects.Remove(src) - ..() +/obj/effect/blob/core/Del() + blob_cores -= src + if(overmind) + del(overmind) + processing_objects.Remove(src) + ..() + return + +/obj/effect/blob/core/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + +/obj/effect/blob/core/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() + return + return + +/obj/effect/blob/core/Life() + if(!overmind) + create_overmind() + else + if(resource_delay <= world.time) + resource_delay = world.time + 10 // 1 second + overmind.add_points(point_rate) + health = min(initial(health), health + 1) + for(var/i = 1; i < 8; i += i) + Pulse(0, i) + for(var/b_dir in alldirs) + if(!prob(5)) + continue + var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir) + if(B) + B.change_to(/obj/effect/blob/shield) + ..() + + +/obj/effect/blob/core/proc/create_overmind(var/client/new_overmind) + + if(overmind_get_delay > world.time) return - fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return + overmind_get_delay = world.time + 300 // 30 seconds - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return - return + if(overmind) + del(overmind) - Life() - if(!overmind) - create_overmind() - else - if(resource_delay <= world.time) - resource_delay = world.time + 10 // 1 second - overmind.add_points(point_rate) - health = min(initial(health), health + 1) - for(var/i = 1; i < 8; i += i) - Pulse(0, i) - for(var/b_dir in alldirs) - if(!prob(5)) - continue - var/obj/effect/blob/normal/B = locate() in get_step(src, b_dir) - if(B) - B.change_to(/obj/effect/blob/shield) - ..() + var/client/C = null + var/list/candidates = list() + if(!new_overmind) + candidates = get_candidates(BE_ALIEN) + if(candidates.len) + C = pick(candidates) + else + C = new_overmind - run_action() - return 0 - - - proc/create_overmind(var/client/new_overmind) - - if(overmind_get_delay > world.time) - return - - overmind_get_delay = world.time + 300 // 30 seconds - - if(overmind) - del(overmind) - - var/client/C = null - var/list/candidates = list() - - if(!new_overmind) - candidates = get_candidates(BE_ALIEN) - if(candidates.len) - C = pick(candidates) - else - C = new_overmind - - if(C) - var/mob/camera/blob/B = new(src.loc) - B.key = C.key - B.blob_core = src - src.overmind = B - return 1 - return 0 + if(C) + var/mob/camera/blob/B = new(src.loc) + B.key = C.key + B.blob_core = src + src.overmind = B + return 1 + return 0 diff --git a/code/game/gamemodes/blob/blobs/factory.dm b/code/game/gamemodes/blob/blobs/factory.dm index 2fb1b61b97f..c85832c0fd2 100644 --- a/code/game/gamemodes/blob/blobs/factory.dm +++ b/code/game/gamemodes/blob/blobs/factory.dm @@ -8,22 +8,27 @@ var/max_spores = 3 var/spore_delay = 0 - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return +/obj/effect/blob/factory/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() return + return +/obj/effect/blob/factory/PulseAnimation(var/activate = 0) + if(activate) + ..() + return - run_action() - if(spores.len >= max_spores) - return 0 - if(spore_delay > world.time) - return 0 - spore_delay = world.time + 100 // 10 seconds - new/mob/living/simple_animal/hostile/blobspore(src.loc, src) - return 1 +/obj/effect/blob/factory/run_action() + if(spores.len >= max_spores) + return 0 + if(spore_delay > world.time) + return 0 + spore_delay = world.time + 100 // 10 seconds + PulseAnimation(1) + new/mob/living/simple_animal/hostile/blobspore(src.loc, src) + return 1 /mob/living/simple_animal/hostile/blobspore @@ -52,41 +57,41 @@ minbodytemp = 0 maxbodytemp = 360 - fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5)) +/mob/living/simple_animal/hostile/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + ..() + adjustBruteLoss(Clamp(0.01 * exposed_temperature, 1, 5)) - blob_act() - return +/mob/living/simple_animal/hostile/blobspore/blob_act() + return - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(istype(mover, /obj/effect/blob)) - return 1 - return ..() +/mob/living/simple_animal/hostile/blobspore/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(istype(mover, /obj/effect/blob)) + return 1 + return ..() - New(loc, var/obj/effect/blob/factory/linked_node) - if(istype(linked_node)) - factory = linked_node - factory.spores += src - ..() +/mob/living/simple_animal/hostile/blobspore/New(loc, var/obj/effect/blob/factory/linked_node) + if(istype(linked_node)) + factory = linked_node + factory.spores += src + ..() - Die() - // On death, create a small smoke of harmful gas (s-Acid) - var/datum/effect/effect/system/chem_smoke_spread/S = new - var/turf/location = get_turf(src) +/mob/living/simple_animal/hostile/blobspore/Die() + // On death, create a small smoke of harmful gas (s-Acid) + var/datum/effect/effect/system/chem_smoke_spread/S = new + var/turf/location = get_turf(src) - // Create the reagents to put into the air, s-acid is yellow and stings a little - create_reagents(25) - reagents.add_reagent("spore", 25) + // Create the reagents to put into the air, s-acid is yellow and stings a little + create_reagents(25) + reagents.add_reagent("spore", 25) - // Attach the smoke spreader and setup/start it. - S.attach(location) - S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud - S.start() + // Attach the smoke spreader and setup/start it. + S.attach(location) + S.set_up(reagents, 1, 1, location, 15, 1) // only 1-2 smoke cloud + S.start() - del(src) + del(src) - Del() - if(factory) - factory.spores -= src - ..() +/mob/living/simple_animal/hostile/blobspore/Del() + if(factory) + factory.spores -= src + ..() diff --git a/code/game/gamemodes/blob/blobs/node.dm b/code/game/gamemodes/blob/blobs/node.dm index b4d9add7983..a205cd59263 100644 --- a/code/game/gamemodes/blob/blobs/node.dm +++ b/code/game/gamemodes/blob/blobs/node.dm @@ -6,32 +6,28 @@ fire_resist = 2 - New(loc, var/h = 100) - blob_nodes += src - processing_objects.Add(src) - ..(loc, h) +/obj/effect/blob/node/New(loc, var/h = 100) + blob_nodes += src + processing_objects.Add(src) + ..(loc, h) - fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) +/obj/effect/blob/node/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return + +/obj/effect/blob/node/Del() + blob_nodes -= src + processing_objects.Remove(src) + ..() + return + +/obj/effect/blob/node/Life() + for(var/i = 1; i < 8; i += i) + Pulse(5, i) + health = min(initial(health), health + 1) + +/obj/effect/blob/node/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() return - - Del() - blob_nodes -= src - processing_objects.Remove(src) - ..() - return - - Life() - for(var/i = 1; i < 8; i += i) - Pulse(5, i) - health = min(initial(health), health + 1) - - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return - return - - - run_action() - return 0 \ No newline at end of file + return \ No newline at end of file diff --git a/code/game/gamemodes/blob/blobs/resource.dm b/code/game/gamemodes/blob/blobs/resource.dm index 340f4344284..68b67cf75e7 100644 --- a/code/game/gamemodes/blob/blobs/resource.dm +++ b/code/game/gamemodes/blob/blobs/resource.dm @@ -7,20 +7,28 @@ var/mob/camera/blob/overmind = null var/resource_delay = 0 - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return +/obj/effect/blob/resource/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() return + return - run_action() - if(resource_delay > world.time) - return 0 +/obj/effect/blob/resource/PulseAnimation(var/activate = 0) + if(activate) + ..() + return - resource_delay = world.time + 40 // 4 seconds +/obj/effect/blob/resource/run_action() - if(overmind) - overmind.add_points(1) - return 1 + if(resource_delay > world.time) + return 0 + + PulseAnimation(1) + + resource_delay = world.time + 40 // 4 seconds + + if(overmind) + overmind.add_points(1) + return 1 diff --git a/code/game/gamemodes/blob/blobs/shield.dm b/code/game/gamemodes/blob/blobs/shield.dm index b9b13d61871..17d06f89f9a 100644 --- a/code/game/gamemodes/blob/blobs/shield.dm +++ b/code/game/gamemodes/blob/blobs/shield.dm @@ -7,16 +7,16 @@ fire_resist = 2 - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return +/obj/effect/blob/shield/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() return + return - fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - return +/obj/effect/blob/shield/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + return - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 - return 0 +/obj/effect/blob/shield/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 + return 0 diff --git a/code/game/gamemodes/blob/overmind.dm b/code/game/gamemodes/blob/overmind.dm index 995cfed91fb..0420ad525f6 100644 --- a/code/game/gamemodes/blob/overmind.dm +++ b/code/game/gamemodes/blob/overmind.dm @@ -24,7 +24,6 @@ /mob/camera/blob/Login() ..() sync_mind() - src << "You are the overmind!" src << "You are the overmind and can control the blob by placing new blob pieces such as..." src << "Normal Blob will expand your reach and allow you to upgrade into special blobs that perform certain functions." @@ -32,6 +31,7 @@ src << "Resource Blob is a blob which will collect more resources for you, try to build these earlier to get a strong income. It will benefit from being near your core or multiple nodes, by having an increased resource rate; put it alone and it won't create resources at all." src << "Node Blob is a blob which will grow, like the core. Unlike the core it won't give you a small income but it can power resource and factory blobs to increase their rate." src << "Factory Blob is a blob which will spawn blob spores which will attack nearby food. Putting this nearby nodes and your core will increase the spawn rate; put it alone and it will not spawn any spores." + src << "Shortcuts: CTRL Click = Expand Blob / Middle Mouse Click = Rally Spores / Alt Click = Create Shield" mob/camera/blob/Life() @@ -40,7 +40,35 @@ mob/camera/blob/Life() return /mob/camera/blob/say(var/message) - return//No talking for you + if (!message) + return + + if (src.client) + if(client.prefs.muted & MUTE_IC) + src << "You cannot send IC messages (muted)." + return + if (src.client.handle_spam_prevention(message,MUTE_IC)) + return + + if (stat) + return + + blob_talk(message) + +/mob/camera/blob/proc/blob_talk(message) + log_say("[key_name(src)] : [message]") + + message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN)) + + if (!message) + return + + var/message_a = say_quote(message) + var/rendered = "Blob Telepathy, [name] [message_a]" + + for (var/mob/M in mob_list) + if(isovermind(M) || isobserver(M)) + M.show_message(rendered, 2) /mob/camera/blob/emote(var/act,var/m_type=1,var/message = null) return @@ -64,3 +92,5 @@ mob/camera/blob/Life() loc = NewLoc else return 0 + + diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 75b333f6522..9eb63a07e2b 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -35,16 +35,15 @@ if(chosen_node) src.loc = chosen_node.loc -/mob/camera/blob/verb/create_shield() +/mob/camera/blob/verb/create_shield_power() set category = "Blob" set name = "Create Shield Blob (10)" set desc = "Create a shield blob." - var/turf/T = get_turf(src) + create_shield(T) - if(!T) - return +/mob/camera/blob/proc/create_shield(var/turf/T) var/obj/effect/blob/B = (locate(/obj/effect/blob) in T) @@ -64,6 +63,7 @@ return + /mob/camera/blob/verb/create_resource() set category = "Blob" set name = "Create Resource Blob (40)" @@ -85,7 +85,7 @@ src << "Unable to use this blob, find a normal one." return - for(var/obj/effect/blob/resource/blob in orange(4)) + for(var/obj/effect/blob/resource/blob in orange(4, T)) src << "There is a resource blob nearby, move more than 4 tiles away from it!" return @@ -121,7 +121,7 @@ src << "Unable to use this blob, find a normal one." return - for(var/obj/effect/blob/node/blob in orange(5)) + for(var/obj/effect/blob/node/blob in orange(5, T)) src << "There is another node nearby, move more than 5 tiles away from it!" return @@ -153,7 +153,7 @@ src << "Unable to use this blob, find a normal one." return - for(var/obj/effect/blob/factory/blob in orange(7)) + for(var/obj/effect/blob/factory/blob in orange(7, T)) src << "There is a factory blob nearby, move more than 7 tiles away from it!" return @@ -186,13 +186,15 @@ return -/mob/camera/blob/verb/spawn_blob() +/mob/camera/blob/verb/expand_blob_power() set category = "Blob" set name = "Expand Blob (5)" set desc = "Attempts to create a new blob in this tile. If the tile isn't clear we will attack it, which might clear it." var/turf/T = get_turf(src) + expand_blob(T) +/mob/camera/blob/proc/expand_blob(var/turf/T) if(!T) return @@ -201,7 +203,7 @@ src << "There is a blob here!" return - var/obj/effect/blob/OB = locate() in circlerange(src, 1) + var/obj/effect/blob/OB = locate() in circlerange(T, 1) if(!OB) src << "There is no blob adjacent to you." return @@ -212,20 +214,27 @@ return -/mob/camera/blob/verb/rally_spores() +/mob/camera/blob/verb/rally_spores_power() set category = "Blob" set name = "Rally Spores (5)" set desc = "Rally the spores to move to your location." + var/turf/T = get_turf(src) + rally_spores(T) + +/mob/camera/blob/proc/rally_spores(var/turf/T) + if(!can_buy(5)) return - var/list/surrounding_turfs = block(locate(x - 1, y - 1, z), locate(x + 1, y + 1, z)) + src << "You rally your spores." + + var/list/surrounding_turfs = block(locate(T.x - 1, T.y - 1, T.z), locate(T.x + 1, T.y + 1, T.z)) if(!surrounding_turfs.len) return for(var/mob/living/simple_animal/hostile/blobspore/BS in living_mob_list) - if(isturf(BS.loc) && get_dist(BS, src) <= 20) + if(isturf(BS.loc) && get_dist(BS, T) <= 35) BS.LoseTarget() BS.Goto(pick(surrounding_turfs), BS.move_to_delay) return \ No newline at end of file diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 417c1ee0b4d..7b4d932d67c 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -12,160 +12,180 @@ var/fire_resist = 1 - New(loc) - blobs += src - src.dir = pick(1, 2, 4, 8) - src.update_icon() - ..(loc) - for(var/atom/A in loc) - A.blob_act() - return +/obj/effect/blob/New(loc) + blobs += src + src.dir = pick(1, 2, 4, 8) + src.update_icon() + ..(loc) + for(var/atom/A in loc) + A.blob_act() + return - Del() - blobs -= src - ..() - return +/obj/effect/blob/Del() + blobs -= src + ..() + return - CanPass(atom/movable/mover, turf/target, height=0, air_group=0) - if(air_group || (height==0)) return 1 - if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 - return 0 +/obj/effect/blob/CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if(air_group || (height==0)) return 1 + if(istype(mover) && mover.checkpass(PASSBLOB)) return 1 + return 0 - process() - Life() - return - - fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) - ..() - var/damage = Clamp(0.01 * exposed_temperature / fire_resist, 0, 4 - fire_resist) - if(damage) - health -= damage - update_icon() - - proc/Life() - return - - - proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand - - set background = 1 - - if(run_action())//If we can do something here then we dont need to pulse more - return - - if(pulse > 30) - return//Inf loop check - - //Looking for another blob to pulse - var/list/dirs = list(1,2,4,8) - dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us - for(var/i = 1 to 4) - if(!dirs.len) break - var/dirn = pick(dirs) - dirs.Remove(dirn) - var/turf/T = get_step(src, dirn) - var/obj/effect/blob/B = (locate(/obj/effect/blob) in T) - if(!B) - expand(T)//No blob here so try and expand - return - B.Pulse((pulse+1),get_dir(src.loc,T)) - return - return - - - proc/run_action() - return 0 - - - proc/expand(var/turf/T = null, var/prob = 1) - if(prob && !prob(health)) return - if(istype(T, /turf/space) && prob(75)) return - 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/effect/blob) in T)) break - else T = null - - if(!T) return 0 - var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30)) - B.density = 1 - if(T.Enter(B,src))//Attempt to move into the tile - B.density = initial(B.density) - B.loc = T - else - T.blob_act()//If we cant move in hit the turf - B.Delete() - - for(var/atom/A in T)//Hit everything in the turf - A.blob_act() - return 1 - - - ex_act(severity) - var/damage = 150 - health -= ((damage/brute_resist) - (severity * 5)) - update_icon() - return - - - bullet_act(var/obj/item/projectile/Proj) - ..() - switch(Proj.damage_type) - if(BRUTE) - health -= (Proj.damage/brute_resist) - if(BURN) - health -= (Proj.damage/fire_resist) - - update_icon() - return 0 - - - attackby(var/obj/item/weapon/W, var/mob/user) - playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) - src.visible_message("\red The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") - var/damage = 0 - switch(W.damtype) - if("fire") - damage = (W.force / max(src.fire_resist,1)) - if(istype(W, /obj/item/weapon/weldingtool)) - playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) - if("brute") - damage = (W.force / max(src.brute_resist,1)) +/obj/effect/blob/process() + Life() + return +/obj/effect/blob/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) + ..() + var/damage = Clamp(0.01 * exposed_temperature / fire_resist, 0, 4 - fire_resist) + if(damage) health -= damage update_icon() + +/obj/effect/blob/proc/Life() + return + +/obj/effect/blob/proc/PulseAnimation() + flick("[icon_state]_glow", src) + return + + +/obj/effect/blob/proc/Pulse(var/pulse = 0, var/origin_dir = 0)//Todo: Fix spaceblob expand + + set background = 1 + + PulseAnimation() + + if(run_action())//If we can do something here then we dont need to pulse more return - proc/change_to(var/type) - if(!ispath(type)) - error("[type] is an invalid type for the blob.") - new type(src.loc) - Delete() - return + if(pulse > 30) + return//Inf loop check - proc/Delete() - del(src) + //Looking for another blob to pulse + var/list/dirs = list(1,2,4,8) + dirs.Remove(origin_dir)//Dont pulse the guy who pulsed us + for(var/i = 1 to 4) + if(!dirs.len) break + var/dirn = pick(dirs) + dirs.Remove(dirn) + var/turf/T = get_step(src, dirn) + var/obj/effect/blob/B = (locate(/obj/effect/blob) in T) + if(!B) + expand(T)//No blob here so try and expand + return + B.Pulse((pulse+1),get_dir(src.loc,T)) + return + return + + +/obj/effect/blob/proc/run_action() + return 0 + + +/obj/effect/blob/proc/expand(var/turf/T = null, var/prob = 1) + if(prob && !prob(health)) return + if(istype(T, /turf/space) && prob(75)) return + 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/effect/blob) in T)) break + else T = null + + if(!T) return 0 + var/obj/effect/blob/normal/B = new /obj/effect/blob/normal(src.loc, min(src.health, 30)) + B.density = 1 + if(T.Enter(B,src))//Attempt to move into the tile + B.density = initial(B.density) + B.loc = T + else + T.blob_act()//If we cant move in hit the turf + B.Delete() + + for(var/atom/A in T)//Hit everything in the turf + A.blob_act() + return 1 + + +/obj/effect/blob/ex_act(severity) + var/damage = 150 + health -= ((damage/brute_resist) - (severity * 5)) + update_icon() + return + + +/obj/effect/blob/bullet_act(var/obj/item/projectile/Proj) + ..() + switch(Proj.damage_type) + if(BRUTE) + health -= (Proj.damage/brute_resist) + if(BURN) + health -= (Proj.damage/fire_resist) + + update_icon() + return 0 + + +/obj/effect/blob/attackby(var/obj/item/weapon/W, var/mob/user) + playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1) + src.visible_message("\red The [src.name] has been attacked with \the [W][(user ? " by [user]." : ".")]") + var/damage = 0 + switch(W.damtype) + if("fire") + damage = (W.force / max(src.fire_resist,1)) + if(istype(W, /obj/item/weapon/weldingtool)) + playsound(src.loc, 'sound/items/Welder.ogg', 100, 1) + if("brute") + damage = (W.force / max(src.brute_resist,1)) + + health -= damage + update_icon() + return + +/obj/effect/blob/proc/change_to(var/type) + if(!ispath(type)) + error("[type] is an invalid type for the blob.") + new type(src.loc) + Delete() + return + +/obj/effect/blob/proc/Delete() + del(src) /obj/effect/blob/normal icon_state = "blob" luminosity = 0 health = 21 - Delete() - src.loc = null - blobs -= src +/obj/effect/blob/normal/Delete() + src.loc = null + blobs -= src - update_icon() - if(health <= 0) - playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) - Delete() - return - if(health <= 15) - icon_state = "blob_damaged" - return +/obj/effect/blob/normal/update_icon() + if(health <= 0) + playsound(src.loc, 'sound/effects/splat.ogg', 50, 1) + Delete() + return + if(health <= 15) + icon_state = "blob_damaged" + return + +/* // Used to create the glow sprites. Remember to set the animate loop to 1, instead of infinite! + +var/datum/blob_colour/B = new() + +/datum/blob_colour/New() + ..() + var/icon/I = 'icons/mob/blob.dmi' + I += rgb(35, 35, 0) + if(isfile("icons/mob/blob_result.dmi")) + fdel("icons/mob/blob_result.dmi") + fcopy(I, "icons/mob/blob_result.dmi") + +*/ \ No newline at end of file diff --git a/html/changelog.html b/html/changelog.html index 4fab1630f6c..8b07b2b2883 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -52,12 +52,20 @@ should be listed in the changelog upon commit tho. Thanks. --> - - - - - + +
+

6 October 2013

+

Giacom updated:

+
    +
  • New blob features!
  • +
  • The blob will glow when it is being pulsed from a core/node. Resource/factories have depended on being pulsed to work, but you couldn't see; well now you can.
  • +
  • Overminds can talk! But only to other overminds, but ghosts can hear their conversations.
  • +
  • As a blob overmind you can now use shortcuts to help robust that assistant with the welding tank dangerously close to your core.
  • +
  • Expand = CTRL Click - Rally = Middle Mouse Click - Create Shield = Alt Click
  • +
+
+
diff --git a/icons/mob/blob.dmi b/icons/mob/blob.dmi index 7b265ba2bd1..19528ccbb1b 100644 Binary files a/icons/mob/blob.dmi and b/icons/mob/blob.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 5099ce4c156..89b315eea00 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -42,6 +42,7 @@ #include "code\_onclick\item_attack.dm" #include "code\_onclick\observer.dm" #include "code\_onclick\other_mobs.dm" +#include "code\_onclick\overmind.dm" #include "code\_onclick\telekinesis.dm" #include "code\_onclick\hud\_defines.dm" #include "code\_onclick\hud\alien.dm"