Skip to content

Commit

Permalink
Sentinel flock structure + fixes (#3635)
Browse files Browse the repository at this point in the history
  • Loading branch information
moonlol committed Mar 4, 2021
1 parent d01d040 commit 8713b65
Show file tree
Hide file tree
Showing 11 changed files with 211 additions and 45 deletions.
17 changes: 14 additions & 3 deletions code/datums/abilities/flock/flockmind.dm
Expand Up @@ -216,7 +216,7 @@
// skip this one
continue
var/obj/item/device/radio/R = M.ears
if(R?.listening)
if(istype(R) && R.listening)
// your headset's on, you're fair game!!
targets += M
if(targets.len >= 1)
Expand Down Expand Up @@ -313,17 +313,28 @@
name = "Fabricate Structure"
desc = "Create a structure tealprint for your drones to construct onto."
icon_state = "fabstructure"
cooldown = 4
cooldown = 4 SECONDS
targeted = 0

/datum/targetable/flockmindAbility/createStructure/cast()
var/resourcecost = null
var/structurewantedtype = null
var/structurewanted = input("Select which structure you would like to create", "Tealprint Selection", "cancel") as null|anything in list("Collector")
var/turf/T = get_turf(holder.owner)
if(!istype(T, /turf/simulated/floor/feather))
boutput(holder.owner, "<span class='alert'>You aren't above a flocktile.</span>")//todo maybe make this flock themed?
return 1
if(locate(/obj/flock_structure) in T)
boutput(holder.owner, "<span class='alert'>There is already a flock structure on this flocktile!</span>")
return 1
//todo: replace with FANCY tgui/chui window with WHEELS and ICONS and stuff!
var/structurewanted = tgui_input_list(holder.owner, "Select which structure you would like to create", "Tealprint selection", list("Collector", "Sentinel"))
switch(structurewanted)
if("Collector")
structurewantedtype = /obj/flock_structure/collector
resourcecost = 200
if("Sentinel")
structurewantedtype = /obj/flock_structure/sentinel
resourcecost = 300
if(structurewantedtype)
var/mob/living/intangible/flock/F = holder.owner
F.createstructure(structurewantedtype, resourcecost)
2 changes: 1 addition & 1 deletion code/mob/living/critter/flock/flockdrone.dm
Expand Up @@ -363,7 +363,7 @@
if(!floor.on)
floor.on()
src.start_floorrunning()
else if(src.floorrunning)
else if(keys && src.floorrunning)
src.end_floorrunning()
. = ..()

Expand Down
2 changes: 2 additions & 0 deletions code/mob/living/critter/flockcritter_parent.dm
Expand Up @@ -537,3 +537,5 @@
amounttopay = min(F.resources, difference, 10)
F.pay_resources(amounttopay)
target.currentmats += amounttopay
if(F.resources && !F.is_npc) //npc check just to make sure it doesnt interfere with their ai.
src.onRestart() //restart the action akin to automenders
8 changes: 5 additions & 3 deletions code/obj/flock/furniture.dm
Expand Up @@ -284,10 +284,12 @@

// flockdrones can always move through
/obj/grille/flock/CanPass(atom/movable/mover, turf/target)
if (istype(mover, /mob/living/critter/flock/drone) && !mover:floorrunning)
. = ..()
var/mob/living/critter/flock/drone/drone = mover
if(istype(drone) && !drone.floorrunning)
animate_flock_passthrough(mover)
return 1
return ..()
. = TRUE


/obj/grille/flock/special_desc(dist, mob/user)
if(isflock(user))
Expand Down
50 changes: 30 additions & 20 deletions code/obj/flock/structure/collector.dm
@@ -1,40 +1,52 @@
//
//Collector structure
//
/// # Collector structure
/obj/flock_structure/collector
name = "Some weird lookin' pulsing thing"
desc = "Seems to be pulsing."
flock_id = "Collector"
var/drawfromgrid = 0 //does it draw from the local apc if its strong enough.
var/active = 0 //is it active?
var/maxrange = 5 //max range for the thing.
var/connected = 0 //amount of tiles "connected" to.
var/list/connectedto = list() //the tiles its connected to
health = 60
/// does it draw from the local apc if its strong enough.
var/drawfromgrid = 0
/// is it active?
var/active = 0
/// max range for the thing.
var/maxrange = 5
/// the tiles its connected to
var/list/turf/simulated/floor/feather/connectedto = list()

event_handler_flags = USE_CANPASS //needed for passthrough
// drones can pass through this, might change this later, as balance point
passthrough = TRUE

poweruse = 0
usesgroups = 1
usesgroups = TRUE
icon_state = "collector"

/obj/flock_structure/collector/New(var/atom/location, var/datum/flock/F=null)
..(location, F)

/obj/flock_structure/collector/building_specific_info()
return {"<span class='bold'>Connections:</span> Currently Connected to [connected] tile[connected == 1 ? "" : "s"].
return {"<span class='bold'>Connections:</span> Currently Connected to [length(connectedto)] tile[length(connectedto) == 1 ? "" : "s"].
<br><span class='bold'>Power generation:</span> Currently generating [abs(poweruse)]."}

/obj/flock_structure/collector/process()
..()
calcconnected()
if(connected > 0)
if(length(connectedto))
icon_state = "collectoron"
else
icon_state = "collector"
src.poweruse = ((connected * 5) / -1) //power = tiles connected * 5 / 1 (5 power per tile)
src.poweruse = ((length(connectedto) * 5) / -1) //(5 power per tile)

/obj/flock_structure/collector/disposing()
for(var/turf/simulated/floor/feather/flocktile as() in connectedto)
flocktile.off()
connectedto.len = 0
..()

/obj/flock_structure/collector/proc/calcconnected()
for(var/turf/simulated/floor/feather/f in connectedto)
f.off()
f.connected = 0
for(var/turf/simulated/floor/feather/flocktile as() in connectedto)
flocktile.off()
flocktile.connected = 0
connectedto.len = 0
var/myturf = get_turf(src)
var/distance = 0 //how far has it gone already?
Expand All @@ -55,10 +67,8 @@
distance++
connectedto |= floor

for(var/turf/simulated/floor/feather/f in connectedto)
f.connected = 1
f.on() //make it glo

connected = length(connectedto)
for(var/turf/simulated/floor/feather/flocktile as() in connectedto)
flocktile.connected = 1
flocktile.on() //make it glo


1 change: 1 addition & 0 deletions code/obj/flock/structure/flock_structure_ghost.dm
Expand Up @@ -7,6 +7,7 @@
var/building = null //thing thats being built
var/currentmats = 0 //mats currently in the thing.
flock_id = "Construction Tealprint"
density = 0


/obj/flock_structure/ghost/building_specific_info()
Expand Down
48 changes: 31 additions & 17 deletions code/obj/flock/structure/flock_structure_parent.dm
@@ -1,6 +1,4 @@
/////////////////////////////////////////////////////////////////////////////////
// FLOCK STRUCTURE PARENT
/////////////////////////////////////////////////////////////////////////////////
/// # Flock Structure Parent
/obj/flock_structure
icon = 'icons/misc/featherzone.dmi'
icon_state = "egg"
Expand All @@ -9,17 +7,25 @@
name = "uh oh"
desc = "CALL A CODER THIS SHOULDN'T BE SEEN"
var/flock_id = "ERROR"
var/time_started = 0 // when did we get created?
/// when did we get created?
var/time_started = 0
var/build_time = 6 // in seconds
var/health = 30 // fragile little thing
var/health_max
var/bruteVuln = 1.2
var/fireVuln = 0.2 // very flame-retardant
/// very flame-retardant
var/fireVuln = 0.2
var/datum/flock/flock = null
var/poweruse = 0 //does this use(/how much) power? (negatives mean it makes power)
var/usesgroups = 0 //not everything needs a group so dont check for everysingle god damn structure
var/datum/flock_tile_group/group = null //what group are we connected to?
var/turf/simulated/floor/feather/grouptile = null //the tile which its "connected to" and handles the group
/// can flockdrones pass through this akin to a grille? need to set USE_CANPASS to make this work however
var/passthrough = FALSE
/// does this use(/how much) power? (negatives mean it makes power)
var/poweruse = 0
/// not everything needs a group so dont check for everysingle god damn structure
var/usesgroups = FALSE
/// what group are we connected to?
var/datum/flock_tile_group/group = null
/// the tile which its "connected to" and handles the group
var/turf/simulated/floor/feather/grouptile = null

/obj/flock_structure/New(var/atom/location, var/datum/flock/F=null)
..()
Expand Down Expand Up @@ -63,20 +69,21 @@
/obj/flock_structure/proc/groupcheck() //rechecks if the tile under's group matches its own
if(!usesgroups) return
if(istype(get_turf(src), /turf/simulated/floor/feather))
var/turf/simulated/floor/feather/f = get_turf(src)
if(src.grouptile == f && grouptile.group == src.group) return//no changes its all good
else if(!src.grouptile == f && f.group == src.group)//if the grouptile is different but the groups the same
src.grouptile = f//just move the connected tile, this should really rarely happen if the structure is moved somehow
else if(!src.grouptile == f && !f.group == src.group)//if both stuff is different.
src.grouptile = f
var/turf/simulated/floor/feather/undertile = get_turf(src)
if(src.grouptile == undertile && grouptile.group == src.group) return//no changes its all good
else if(src.grouptile != undertile && undertile.group == src.group)//if the grouptile is different but the groups the same
src.grouptile = undertile//just move the connected tile, this should really rarely happen if the structure is moved somehow
else if(src.grouptile != undertile && undertile.group != src.group)//if both stuff is different.
src.grouptile = undertile
src.group?.removestructure(src)
src.group = f.group
src.group = undertile.group
src.group.addstructure(src)
else if(src.grouptile == f && !grouptile.group == src.group)//if just the tile's group is different
else if(src.grouptile == undertile && grouptile.group != src.group)//if just the tile's group is different
src.group?.removestructure(src)
src.group = grouptile.group
src.group.addstructure(src)


/obj/flock_structure/proc/takeDamage(var/damageType, var/amount)
switch(damageType)
if("brute")
Expand Down Expand Up @@ -197,3 +204,10 @@

takeDamage("mixed", damage)
src.visible_message("<span class='alert'>[src] is hit by the blob!/span>")

/obj/flock_structure/CanPass(atom/movable/mover, turf/target)
. = ..()
var/mob/living/critter/flock/drone/drone = mover
if(src.passthrough && istype(drone) && !drone.floorrunning)
animate_flock_passthrough(mover)
. = TRUE
122 changes: 122 additions & 0 deletions code/obj/flock/structure/sentinel.dm
@@ -0,0 +1,122 @@
//
/// # Sentinel structure,
//
#define NOT_CHARGED -1 //! The sentinel is without charge
#define LOSING_CHARGE 0 //! The sentinel is losing charge
#define CHARGING 1 //! The sentinel is gaining charge
#define CHARGED 2 //! The sentinel is charged
/obj/flock_structure/sentinel
name = "Glowing pylon"
desc = "A glowing pylon of sorts, faint sparks are jumping inside of it."
icon_state = "sentinel"
flock_id = "Sentinel"
health = 80
var/charge_status = NOT_CHARGED
/// 0-100 charge percent
var/charge = 0
var/powered = FALSE

event_handler_flags = USE_CANPASS
// flockdrones can pass through this
passthrough = TRUE

usesgroups = TRUE

// debug amount scale up if needed.
poweruse = 20

var/obj/effect/flock_sentinelrays/rays = null

/obj/flock_structure/sentinel/New(var/atom/location, var/datum/flock/F=null)
..(location, F)
src.rays = new /obj/effect/flock_sentinelrays
src.vis_contents += rays

/obj/flock_structure/sentinel/disposing()
qdel(src.rays)
..()


/obj/flock_structure/sentinel/building_specific_info()
return {"<span class='bold'>Status:</span> [charge_status == 1 ? "charging" : (charge_status == 2 ? "charged" : "idle")].
<br><span class='bold'>Charge Percentage:</span> [charge]%."}

/obj/flock_structure/sentinel/process()
updatefilter()

if(!src.group)//if it dont exist it off
powered = FALSE
else if(src.group.powerbalance >= 0)//if it has atleast 0 or more free power, the poweruse is already calculated in the group
powered = TRUE
else//if there isnt enough juice
powered = FALSE

if(powered == 1)
switch(charge_status)
if(NOT_CHARGED)
charge_status = CHARGING//begin charging as there is energy available
if(LOSING_CHARGE)
charge_status = CHARGING//if its losing charge and suddenly theres energy available begin charging
if(CHARGING)
if(icon_state != "sentinelon") icon_state = "sentinelon"//forgive me
src.charge(5)
if(CHARGED)
var/mob/loopmob = null
var/list/hit = list()
var/mob/mobtohit = null
for(loopmob in mobs)
if(IN_RANGE(loopmob, src, 5) && !isflock(loopmob) && src.flock?.isEnemy(loopmob) && isturf(loopmob.loc))
mobtohit = loopmob
break//found target
if(!mobtohit) return//if no target stop
arcFlash(src, mobtohit, 10000)
hit += mobtohit
for(var/i in 1 to rand(5,6))//this facilitates chaining. legally distinct from the loop above
for(var/mob/nearbymob in range(2, mobtohit))//todo: optimize(?) this.
if(nearbymob != mobtohit && !isflock(nearbymob) && !(nearbymob in hit) && isturf(nearbymob.loc) && src.flock?.isEnemy(nearbymob))
arcFlash(mobtohit, nearbymob, 10000)
hit += nearbymob
mobtohit = nearbymob
hit.len = 0//clean up
charge = 1
var/filter = src.filters[length(src.filters)]//force the visual to power down
animate(filter, size=((-(cos(180*(3/100))-1)/2)*32), time=1 SECONDS, flags = ANIMATION_PARALLEL)
charge_status = CHARGING
return
else
if(charge > 0)//if theres charge make it decrease with time
src.charge_status = LOSING_CHARGE
src.charge(-5)
else
if(icon_state != "sentinel") icon_state = "sentinel"//forgive me again
src.charge_status = NOT_CHARGED //out of juice its dead

/obj/flock_structure/sentinel/proc/charge(var/chargeamount = 0)
if(charge < 100)
src.charge = min(chargeamount + charge, 100)
else
charge_status = CHARGED


/obj/flock_structure/sentinel/proc/updatefilter()
var/filter = rays.filters[length(rays.filters)]
if(charge > 2)//else it just makes the sprite invisible, due to floats. this is small enough that it doesnt even showup anyway since its under the sprite
animate(filter, size=((-(cos(180*(charge/100))-1)/2)*32), time=10 SECONDS, flags = ANIMATION_PARALLEL)
else
animate(filter, size=((-(cos(180*(3/100))-1)/2)*32), time=10 SECONDS, flags = ANIMATION_PARALLEL)

/obj/effect/flock_sentinelrays
mouse_opacity = 0
plane = PLANE_NOSHADOW_BELOW
blend_mode = BLEND_ADD

New()
src.filters = filter(type="rays", x=-0.2, y=6, size=1, color=rgb(255,255,255), offset=rand(1000), density=20, threshold=0.2, factor=1)
var/f = src.filters[length(src.filters)]
animate(f, size=((-(cos(180*(3/100))-1)/2)*32), time=5 MINUTES, easing=LINEAR_EASING, loop=-1, offset=f:offset + 100, flags=ANIMATION_PARALLEL)
..()

#undef NOT_CHARGED
#undef LOSING_CHARGE
#undef CHARGING
#undef CHARGED
5 changes: 4 additions & 1 deletion code/turf/turf_flock.dm
Expand Up @@ -80,7 +80,7 @@
splitgroup()
for(var/obj/flock_structure/f in src)
if(f.usesgroups)
f.group.removestructure(f)
f.group?.removestructure(f)
f.group = null


Expand Down Expand Up @@ -193,8 +193,11 @@
for(var/turf/simulated/floor/feather/F in getneighbours(get_turf(src)))
count++ //enumerate nearby tiles
//TODO: fail safe for if there are more then 1 group.
if(!src) return
src.group.removetile(src)
src.group = null
for(var/obj/flock_structure/s in src)
s.group = null

if(count <= 1) //if theres only one tile nearby or it by itself dont bother splitting
if(count <=0) qdel(oldgroup)
Expand Down
1 change: 1 addition & 0 deletions goonstation.dme
Expand Up @@ -1258,6 +1258,7 @@ var/datum/preMapLoad/preMapLoad = new
#include "code\obj\flock\structure\flock_structure_parent.dm"
#include "code\obj\flock\structure\relay.dm"
#include "code\obj\flock\structure\rift.dm"
#include "code\obj\flock\structure\sentinel.dm"
#include "code\obj\item\ai_modules.dm"
#include "code\obj\item\basketball.dm"
#include "code\obj\item\book.dm"
Expand Down
Binary file modified icons/misc/featherzone.dmi
Binary file not shown.

0 comments on commit 8713b65

Please sign in to comment.