ID:842151
 
I'm trying to create a system to simulate soundwaves, and I know what I want it to do.

  • When a sound, like a gunshot, happens, a sound_center object should be created.
  • sound_center will store a list of mobs created by it.
  • From sound_center, small, invisible mobs should expand in a enclosed circle. This means that new mobs will have to be created to keep the expanding circle closed.
  • However, if the sound hits something (atoms will have a soundproof variable that cuts the sound's velocity by a percentage, things like walls cutting them by 100%) like a wall, they are deleted.
  • The circle should not create new mobs to replace deleted ones. If the sound hits something like a door, the sound will go through (although considerably slower) and keep expanding from there. If you have a vivid imagination, you can see this. Imagine a ripple in water, that is stopped in all but a small place - the ripple goes through the small place and continues to expand.

I can handle the rest, like alerting things and the other specifics. It's creating and managing this circle that has me stumped.


Can anyone provide any insight as to how I might create the circle and make it intelligently expand as explained above?
Don't even try. This is the kind of thing BYOND is not built for and won't let be feasible. You're better off making a raycaster.
Hmm. I didn't think that simply making some mobs move outward while creating new ones would cause that much trouble. What's a raycaster?
Of course, if the sound wave simulator is to have the waves moving around 1 pixel per second, it should run without dropping the frame rate too much.

Simply making mobs that all move simultaneously, constantly multiply at an increasingly larger rate, and accurately move and detect collisions is not something BYOND can do quickly, regardless of how simple you think it is.
Well I mean it wouldn't go very far. The sounds would gradually slow, and be deleted when they come to a halt. This is very unfortunate. Is there a way I can simulate this same effect? I just want an intelligent way to alert things around the sound's source. If that thing is behind a wall, though, then it wouldn't hear it.
If a tree falls with no one to hear it, does it make a sound? It probably does, and it is taking up valuable resources.

What would be better for you to do is check for mobs in view of the source and output the sound to them, kind of like this:
view(sound_source) << sound


That still doesn't solve my problem of it not going through walls, but still going through less...solid objects, like screen doors.
In response to Albro1
Okay, then loop through the people who can hear the sound and cast a ray to them from the sound source. That is, trace a line to them and check for obstructions that way. Instead of big circles of waves, all you need is a few rays. It's still not something BYOND likes, but it's relatively lighter than your first idea.
I've never delved into that subject. How exactly do I go about raycasting? I used a forum search but I only see things about first-person, not drawing lines.
If you're only tracing rays directly to each player, you're losing the idea that sounds can bounce off surfaces. You can do a breadth first search to find turfs that are connected to where the sound originates from. That way people around the corner from the source can hear a sound, but people on the other side of a wall cannot.

It could be much more costly, but you could use some type of pathfinding to get a path to each person who might be able to hear the sound. The cost of each turf would be higher if the turf blocks more sound. That way a high-cost path would be one that's a long distance or involves going through walls. That way you can hear sounds through walls, they're just muffled. If the door was open the sound would be louder. For example:

     src
\
#############
# \ #
# mob #
# #
#############

--src
/
/#############
|# #
+------mob #
# #
#############

In the first example the shortest path to the mob is through the wall, but since the wall carries a high cost the sound will be quiet. In the second example the door is open so even though the path is long, it's still lower cost than going through the wall and the sound is a little louder.
Just popped open my test environment after reading that Wiki and tried it out. I got something working, any comments on compressing it a bit? I feel it's way bulkier than it has to be.
EDIT: I just tested it with higher numbers, and once I sent about 14 to sound_start() it started showing lag, and at 17 it started suspecting an infinite loop. So obviously I'm not doing something right.
EDIT 2: I cleaned it up a bit, no more bad loops. I am still open to any constructive criticism on it.
turf/proc
get_directions_open()
. = list()
for(var/turf/t in oview(1, src))

if(!t.density)
. += get_dir(src, t)

mob/proc/sound_start(dist = 1)
var/list
queued_turfs = list()
dequeued_turfs = list()
checked_turfs = list()
var/turf/location = loc
var/list/l = location.get_directions_open()
for(var/o in l)
queued_turfs += get_step(location, o)
// also add these initial turfs to the checked list so they won't be checked again
checked_turfs += get_step(location, o)
var/dist_now = 1
while(dist_now <= dist)
dequeued_turfs = queued_turfs.Copy()
queued_turfs.Cut()
// alert all mobs in the turfs
for(var/turf/t in dequeued_turfs)
for(var/mob/m in t)
m.sound_alert(src)
t.icon_state = "end"

// now queue up the next set of turfs
l = t.get_directions_open()
for(var/o in l)
var/turf/check = get_step(t, o)
if(check in checked_turfs) continue
queued_turfs += check
checked_turfs += check
dist_now += 1


atom/proc/sound_alert(atom/a){if(a != src){world<<"[src]:[x],[y]"}}
mob/random/icon_state="mob"

atom/icon = 'icons.dmi'
turf/dense{icon_state = "balloon"; density = 1}

mob
icon_state = "mob"
Login()
..()
loc=locate(10,1,1)
verb/Start_Sound(n as num)
sound_start(n)
That looks fine. Here's an example I came up with. It doesn't handle diagonals well (it should probably return them from the neighbors() proc and weight their cost a little extra).

http://files.byondhome.com/Forumaccount/soundwaves.zip