struct world_instance
{
- /* This is a small flag we use to changelevel.
- * It will not be cleared until all sounds stop playing
- */
-
/* Fixed items
* -------------------------------------------------------
*/
* (world_gen.h)
* --------------------------------------------------------------------------
*/
+
/*
* Main world .mdl
*/
ent_gate *rendering_gate;
-#if 0
- /*
- * Named safe places to respawn
- */
- struct respawn_point
- {
- v3f co;
- v4f q;
- const char *name;
- }
- * spawns;
- u32 spawn_count;
-
- /*
- * Audio player entities
- */
- struct world_audio_thing
- {
- v3f pos;
- float volume, range;
- u32 flags;
- audio_clip temp_embedded_clip;
- }
- * audio_things;
- u32 audio_things_count;
-
- struct soundscape
- {
- /* locking */
- audio_channel *channels[4];
-
- /* accessable without locking */
- v3f spawn_position;
-
- u32 usage_count;
- u32 max_instances;
- u32 allow_transitions;
- float transition_duration;
- const char *label;
- }
- * soundscapes;
- u32 soundscape_count;
-
- /*
- * Box volume entities
- */
- struct world_volume
- {
- m4x3f transform, inv_transform;
- mdl_node *node;
- }
- * volumes;
- u32 volume_count;
-
- /*
- * Lights
- */
- struct world_light
- {
- mdl_node *node;
- struct classtype_world_light *inf;
- m4x3f inverse_world;
- v2f angle_sin_cos;
- }
- * lights;
- u32 light_count;
-
- /*
- * Routes (world_routes.h)
- * --------------------------------------------------------------------------
- */
-
- struct route_node
- {
- v3f co, right, up, h;
- u32 next[2];
-
- u32 special_type, special_id, current_refs, ref_count;
- u32 route_ids[4]; /* Gates can be linked into up to four routes */
- }
- *nodes;
- u32 node_count;
-
- struct route
- {
- u32 track_id;
- v4f colour;
-
- u32 start;
- mdl_submesh sm;
-
- int active;
- float factive;
-
- double best_lap, latest_pass; /* Session */
-
- m4x3f scoreboard_transform;
- }
- *routes;
- u32 route_count;
-
- struct route_gate
- {
- struct teleport_gate
- {
- v3f co[2];
- v4f q[2];
- v2f dims;
-
- m4x3f to_world, transport;
- }
- gate;
-
- u32 node_id;
-
- struct route_timing
- {
- u32 version; /* Incremented on every teleport */
- double time;
- }
- timing;
- }
- *gates;
- u32 gate_count;
-
- struct nonlocal_gate
- {
- struct teleport_gate gate;
- mdl_node *node;
-
- u32 target_map_index, working;
- }
- *nonlocal_gates;
- u32 nonlocalgate_count;
-
- struct route_collector
- {
- struct route_timing timing;
- }
- *collectors;
- u32 collector_count;
-#endif
-
-
/* logic
* ----------------------------------------------------
*/
call->ent = volume->target;
if( volume->type == k_volume_subtype_particle ){
- v3f co;
+ float *co = alloca( sizeof(float)*3 );
co[0] = vg_randf()*2.0f-1.0f;
co[1] = vg_randf()*2.0f-1.0f;
co[2] = vg_randf()*2.0f-1.0f;
call->function = k_ent_function_particle_spawn;
call->data = co;
-
entity_call( world, call );
}
- else if( volume->type == k_volume_subtype_trigger ){
- /* TODO */
- }
+ else
+ entity_call( world, call );
}
}
{
ent_audio *audio = mdl_arritm( &world->ent_audio, call->ent.index );
+ v3f sound_co;
+
if( call->function == k_ent_function_particle_spawn ){
- float chance = vg_randf()*100.0f,
- bar = 0.0f;
+ v3_copy( call->data, sound_co );
+ }
+ else if( call->function == k_ent_function_trigger ){
+ v3_copy( audio->transform.co, sound_co );
+ }
+ else
+ vg_fatal_exit_loop( "ent_audio_call (invalid function id)" );
+
+ float chance = vg_randf()*100.0f,
+ bar = 0.0f;
- for( u32 i=0; i<audio->clip_count; i++ ){
- ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip,
- audio->clip_start+i );
+ for( u32 i=0; i<audio->clip_count; i++ ){
+ ent_audio_clip *clip = mdl_arritm( &world->ent_audio_clip,
+ audio->clip_start+i );
- float mod = world->probabilities[ audio->probability_curve ],
- p = clip->probability * mod;
+ float mod = world->probabilities[ audio->probability_curve ],
+ p = clip->probability * mod;
- bar += p;
+ bar += p;
- if( chance < bar ){
- float *pos = call->data;
+ if( chance < bar ){
- audio_lock();
+ audio_lock();
- if( audio->behaviour == k_channel_behaviour_unlimited ){
- audio_oneshot_3d( &clip->clip, pos,
- audio->transform.s[0],
- audio->volume );
+ if( audio->behaviour == k_channel_behaviour_unlimited ){
+ audio_oneshot_3d( &clip->clip, sound_co,
+ audio->transform.s[0],
+ audio->volume );
+ }
+ else if( audio->behaviour == k_channel_behaviour_discard_if_full ){
+ audio_channel *ch =
+ audio_get_group_idle_channel( audio->group,
+ audio->max_channels );
+
+ if( ch ){
+ audio_channel_init( ch, &clip->clip, audio->flags );
+ audio_channel_group( ch, audio->group );
+ audio_channel_set_spacial( ch, sound_co, audio->transform.s[0] );
+ audio_channel_edit_volume( ch, audio->volume, 1 );
+ ch = audio_relinquish_channel( ch );
}
- else if( audio->behaviour == k_channel_behaviour_discard_if_full ){
- audio_channel *ch =
- audio_get_group_idle_channel( audio->group,
- audio->max_channels );
-
- if( ch ){
- audio_channel_init( ch, &clip->clip, audio->flags );
- audio_channel_group( ch, audio->group );
- audio_channel_set_spacial( ch, pos, audio->transform.s[0] );
- audio_channel_edit_volume( ch, audio->volume, 1 );
- ch = audio_relinquish_channel( ch );
+ }
+ else if( audio->behaviour == k_channel_behaviour_crossfade_if_full){
+ audio_channel *ch =
+ audio_get_group_idle_channel( audio->group,
+ audio->max_channels );
+
+ /* group is full */
+ if( !ch ){
+ audio_channel *existing =
+ audio_get_group_first_active_channel( audio->group );
+
+ if( existing ){
+ if( existing->source == &clip->clip ){
+ audio_unlock();
+ return;
+ }
+
+ existing->group = 0;
+ existing = audio_channel_fadeout(existing, audio->crossfade);
}
- }
- else if( audio->behaviour == k_channel_behaviour_crossfade_if_full){
-
- }
-
+ ch = audio_get_first_idle_channel();
+ }
- audio_unlock();
- break;
+ if( ch ){
+ audio_channel_init( ch, &clip->clip, audio->flags );
+ audio_channel_group( ch, audio->group );
+ audio_channel_fadein( ch, audio->crossfade );
+ ch = audio_relinquish_channel( ch );
+ }
}
+
+ audio_unlock();
+ return;
}
}
}
if( volume->type == k_volume_subtype_trigger ){
v3f local;
m4x3_mulv( volume->to_local, pos, local );
- vg_line_boxf_transformed( volume->to_world, cube, 0xff00ff00 );
if( (fabsf(local[0]) <= 1.0f) &&
(fabsf(local[1]) <= 1.0f) &&
(fabsf(local[2]) <= 1.0f) )
{
in_volume = 1;
+ vg_line_boxf_transformed( volume->to_world, cube, 0xff00ff00 );
if( !world_global.in_volume ){
ent_call basecall;
entity_call( world, &basecall );
}
}
+ else
+ vg_line_boxf_transformed( volume->to_world, cube, 0xff0000ff );
}
else if( volume->type == k_volume_subtype_particle ){
vg_line_boxf_transformed( volume->to_world, cube, 0xff00c0ff );