1 #ifndef ENT_OBJECTIVE_C
2 #define ENT_OBJECTIVE_C
5 #include "world_load.h"
10 VG_STATIC
void ent_objective_pass( world_instance
*world
,
11 ent_objective
*objective
){
12 if( objective
->id_next
){
13 world_static
.challenge_timer
+= objective
->filter
;
15 u32 index
= mdl_entity_id_id( objective
->id_next
);
16 ent_objective
*next
= mdl_arritm( &world
->ent_objective
, index
);
17 world_static
.challenge_target
= next
;
18 objective
->flags
|= k_ent_objective_passed
;
20 if( next
->filter
& k_ent_objective_filter_passthrough
)
21 ent_objective_pass( world
, next
);
23 vg_info( "pass challenge point\n" );
24 audio_oneshot_3d( &audio_challenge
[0], localplayer
.rb
.co
,
29 vg_success( "challenge win\n" );
30 audio_oneshot( &audio_challenge
[2], 1.0f
, 0.0f
);
31 world_static
.challenge_target
= NULL
;
32 world_static
.challenge_timer
= 0.0f
;
33 world_static
.focused_entity
= 0;
35 if( objective
->id_win
){
38 call
.function
= objective
->win_event
;
39 call
.id
= objective
->id_win
;
40 entity_call( world
, &call
);
43 u32 world_completed
= 1;
44 for( u32 i
=0; i
<mdl_arrcount(&world
->ent_challenge
); i
++ ){
45 ent_challenge
*challenge
= mdl_arritm( &world
->ent_challenge
, i
);
46 if( !challenge
->status
){
52 if( world_completed
){
53 const char *understate
= "Understate DIY park";
54 if( mdl_pstreq( &world
->meta
, world
->info
.pstr_name
,
55 understate
, vg_strdjb2( understate
))){
56 steam_set_achievement( "CITY_COMPLETE" );
62 VG_STATIC
int ent_objective_check_filter( ent_objective
*objective
){
63 if( objective
->filter
){
64 struct player_skate_state
*s
= &localplayer
._skate
.state
;
65 enum trick_type trick
= s
->trick_type
;
69 if( trick
== k_trick_type_shuvit
)
70 state
|= k_ent_objective_filter_trick_shuvit
;
71 if( trick
== k_trick_type_treflip
)
72 state
|= k_ent_objective_filter_trick_treflip
;
73 if( trick
== k_trick_type_kickflip
)
74 state
|= k_ent_objective_filter_trick_kickflip
;
76 if( s
->flip_rate
< -0.0001f
) state
|= k_ent_objective_filter_flip_back
;
77 if( s
->flip_rate
> 0.0001f
) state
|= k_ent_objective_filter_flip_front
;
79 if( s
->activity
== k_skate_activity_grind_5050
||
80 s
->activity
== k_skate_activity_grind_back50
||
81 s
->activity
== k_skate_activity_grind_front50
)
82 state
|= k_ent_objective_filter_grind_truck_any
;
84 if( s
->activity
== k_skate_activity_grind_boardslide
)
85 state
|= k_ent_objective_filter_grind_board_any
;
87 return ((objective
->filter
& state
) || !objective
->filter
) &&
88 ((objective
->filter2
& state
) || !objective
->filter2
);
95 VG_STATIC
void ent_objective_call( world_instance
*world
, ent_call
*call
){
96 u32 index
= mdl_entity_id_id( call
->id
);
97 ent_objective
*objective
= mdl_arritm( &world
->ent_objective
, index
);
99 if( call
->function
== 0 ){
100 if( objective
->flags
& (k_ent_objective_hidden
|
101 k_ent_objective_passed
)) return;
103 if( world_static
.challenge_target
){
104 if( (world_static
.challenge_target
== objective
) &&
105 ent_objective_check_filter( objective
)){
106 ent_objective_pass( world
, objective
);
109 audio_oneshot_3d( &audio_challenge
[6], localplayer
.rb
.co
,
111 vg_error( "challenge failed\n" );
112 world_static
.challenge_target
= NULL
;
113 world_static
.challenge_timer
= 0.0f
;
114 world_static
.focused_entity
= 0;
118 else if( call
->function
== 2 ){
119 objective
->flags
&= ~k_ent_objective_hidden
;
121 if( mdl_entity_id_type( objective
->id_next
) == k_ent_objective
){
122 call
->id
= objective
->id_next
;
123 entity_call( world
, call
);
126 else if( call
->function
== 3 ){
127 objective
->flags
|= k_ent_objective_hidden
;
129 if( mdl_entity_id_type( objective
->id_next
) == k_ent_objective
){
130 call
->id
= objective
->id_next
;
131 entity_call( world
, call
);
135 vg_print_backtrace();
136 vg_error( "Unhandled function id: %u\n", call
->function
);
140 #endif /* ENT_OBJECTIVE_C */