Files
vgstation13/code/defines/procs/gamehelpers.dm
CIB123@gmail.com b687b75bca Optimized radio code broadcasting code.
Rather than calling a function on every single radio object which expensively collects hearers(in closets etc.), the proc will now instead build a list of radios. This list is then passed to another proc, which iterates through all clients in the world, and checks if the client's mob can hear the message.

Note that I did shallow testing, but deeper issues may still be present with stuff like pAIs which I wasn't able to test on my single player server. If any other problems are found, please notify me.


git-svn-id: http://tgstation13.googlecode.com/svn/trunk@4019 316c924e-a436-60f5-8080-3fe189b3f50e
2012-07-09 15:16:00 +00:00

308 lines
7.3 KiB
Plaintext

//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:31
/proc/dopage(src,target)
var/href_list
var/href
href_list = params2list("src=\ref[src]&[target]=1")
href = "src=\ref[src];[target]=1"
src:temphtml = null
src:Topic(href, href_list)
return null
/proc/get_area(O)
var/atom/location = O
var/i
for(i=1, i<=20, i++)
if(isarea(location))
return location
else if (istype(location))
location = location.loc
else
return null
return 0
/proc/get_area_name(N) //get area by its name
for(var/area/A in world)
if(A.name == N)
return A
return 0
/proc/in_range(source, user)
if(get_dist(source, user) <= 1)
return 1
return 0 //not in range and not telekinetic
//Magic constants obtained by using linear regression on right-angled triangles of sides 0<x<1, 0<y<1
//They should approximate pythagoras theorem well enough for our needs.
//In fact, less accuracy is kinda better for explosions anyway :P Maybe k1=1, k2=0.5?
#define k1 0.934
#define k2 0.427
/proc/approx_dist(center=usr, T) // T is just the second atom to check distance to center with
var/turf/centerturf = get_turf(center)
var/turf/targetturf = get_turf(T)
var/a = abs(targetturf.x - centerturf.x) //sides of right-angled triangle
var/b = abs(targetturf.y - centerturf.y)
if(a>=b)
return (k1*a) + (k2*b) //No sqrt or powers :)
else
return (k1*b) + (k2*a)
#undef k1
#undef k2
/proc/circlerange(center=usr,radius=3)
var/turf/centerturf = get_turf(center)
var/list/turfs = new/list()
var/rsq = radius * (radius+0.5)
for(var/atom/T in range(radius, centerturf))
var/dx = T.x - centerturf.x
var/dy = T.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
turfs += T
//turfs += centerturf
return turfs
/proc/circleview(center=usr,radius=3)
var/turf/centerturf = get_turf(center)
var/list/atoms = new/list()
var/rsq = radius * (radius+0.5)
for(var/atom/A in view(radius, centerturf))
var/dx = A.x - centerturf.x
var/dy = A.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
atoms += A
//turfs += centerturf
return atoms
/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj)
var/dx = Loc1.x - Loc2.x
var/dy = Loc1.y - Loc2.y
var/dist = sqrt(dx**2 + dy**2)
return dist
/proc/circlerangeturfs(center=usr,radius=3)
var/turf/centerturf = get_turf(center)
var/list/turfs = new/list()
var/rsq = radius * (radius+0.5)
for(var/turf/T in range(radius, centerturf))
var/dx = T.x - centerturf.x
var/dy = T.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
turfs += T
return turfs
/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circlerangeturfs()?
var/turf/centerturf = get_turf(center)
var/list/turfs = new/list()
var/rsq = radius * (radius+0.5)
for(var/turf/T in view(radius, centerturf))
var/dx = T.x - centerturf.x
var/dy = T.y - centerturf.y
if(dx*dx + dy*dy <= rsq)
turfs += T
return turfs
/proc/get_mobs_in_view(var/R, var/atom/source)
// Returns a list of mobs in range of R from source. Used in radio and say code.
var/turf/T = get_turf(source)
var/list/hear = hearers(R, T)
var/list/V = range(R, T)
// Search for closets:
for(var/obj/structure/closet/C in V)
for(var/mob/M in C.contents)
if(isInSight(source,C))
if(M.client)
hear += M
// Cryos:
for(var/obj/machinery/atmospherics/unary/cryo_cell/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
// Intelicards
for(var/obj/item/device/aicard/C in V)
for(var/mob/living/silicon/ai/M in C)
if(isInSight(source,C))
if(M.client)
hear += M
// Kind of a hacky fix, but should fix most cases without undo issues.
for(var/mob/M as mob in V)
for(var/obj/item/device/aicard/C in M.contents)
for(var/mob/living/silicon/ai/A in C)
if(isInSight(source,A))
if(A.client)
hear += A
// Soulstones
for(var/obj/item/device/soulstone/C in V)
for(var/mob/living/simple_animal/shade/M in C)
if(isInSight(source,C))
if(M.client)
hear += M
// Kind of a hacky fix, but should fix most cases without undo issues.
for(var/mob/M as mob in V)
for(var/obj/item/device/soulstone/C in M.contents)
for(var/mob/living/simple_animal/shade/A in C)
if(isInSight(source,A))
if(A.client)
hear += A
// Brains/MMIs/pAIs
for(var/mob/living/carbon/brain/C in world)
if(get_turf(C) in V)
if(isInSight(source,C))
hear += C
for(var/mob/living/silicon/pai/C in world)
if(get_turf(C) in V)
if(isInSight(source,C))
hear += C
/* -- Handled above. WHY IS THIS HERE? WHYYYYYYY
// Personal AIs
for(var/obj/item/device/paicard/C in V)
if(C.pai)
if(isInSight(source,C))
if(C.pai.client)
hear += C.pai
*/
// Exosuits
for(var/obj/mecha/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
// Disposal Machines
for(var/obj/machinery/disposal/C in V)
for(var/mob/M in C.contents)
if(isInSight(source,C))
if(M.client)
hear += M
//Borg rechargers
for(var/obj/machinery/recharge_station/C in V)
if(C.occupant)
if(isInSight(source,C))
if(C.occupant.client)
hear += C.occupant
for(var/obj/item/device/radio/theradio in V)
if(isInSight(source,theradio))
hear += theradio
return hear
/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
// Returns a list of mobs who can hear any of the radios given in @radios
var/list/hearers = list()
// Try to find all the players who can hear the message
for(var/key in client_list)
var/client/C = client_list[key]
var/mob/M = C.mob
if(!M) continue
var/atom/ear = M.get_ear()
if(!ear) continue
// Now see if they're near any broadcasting radio
for(var/obj/item/device/radio/R in radios)
var/turf/radio_loc = get_turf(R)
if(ear in view(R.canhear_range,radio_loc))
hearers += M
break
return hearers
#define SIGN(X) ((X<0)?-1:1)
proc
inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
var/turf/T
if(X1==X2)
if(Y1==Y2)
return 1 //Light cannot be blocked on same tile
else
var/s = SIGN(Y2-Y1)
Y1+=s
while(Y1!=Y2)
T=locate(X1,Y1,Z)
if(T.opacity)
return 0
Y1+=s
else
var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
var/signX = SIGN(X2-X1)
var/signY = SIGN(Y2-Y1)
if(X1<X2)
b+=m
while(X1!=X2 || Y1!=Y2)
if(round(m*X1+b-Y1))
Y1+=signY //Line exits tile vertically
else
X1+=signX //Line exits tile horizontally
T=locate(X1,Y1,Z)
if(T.opacity)
return 0
return 1
proc/isInSight(var/atom/A, var/atom/B)
var/turf/Aturf = get_turf(A)
var/turf/Bturf = get_turf(B)
if(!Aturf || !Bturf)
return 0
if(inLineOfSight(Aturf.x,Aturf.y, Bturf.x,Bturf.y,Aturf.z))
return 1
else
return 0
/*proc/doafterattack(obj/target , obj/source)
if (istype(target, /obj/item/weapon/storage/ ))
return 0
else if (locate (/obj/structure/table, source.loc))
return 0
else if (!istype(target.loc, /turf/))
return 0
else
return 1
{R}*/