(50c0271)
[carveJwlIkooP6JGAAIwe30JlM.git] / ent_region.c
1 #include "ent_region.h"
2 #include "gui.h"
3 #include "network_common.h"
4 #include "network.h"
5
6 struct global_ent_region global_ent_region;
7
8 u32 region_spark_colour( u32 flags )
9 {
10 if( flags & k_ent_route_flag_achieve_gold )
11 return 0xff8ce0fa;
12 else if( flags & k_ent_route_flag_achieve_silver )
13 return 0xffc2c2c2;
14 else
15 return 0x00;
16 }
17
18 entity_call_result ent_region_call( world_instance *world, ent_call *call )
19 {
20 ent_region *region =
21 mdl_arritm( &world->ent_region, mdl_entity_id_id(call->id) );
22
23 if( !region->zone_volume )
24 return k_entity_call_result_invalid;
25
26 ent_volume *volume =
27 mdl_arritm( &world->ent_volume, mdl_entity_id_id(region->zone_volume) );
28
29 if( call->function == 0 ) /* enter */
30 {
31 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ )
32 {
33 ent_route *route = mdl_arritm( &world->ent_route, i );
34
35 v3f local;
36 m4x3_mulv( volume->to_local, route->board_transform[3], local );
37 if( (fabsf(local[0]) <= 1.0f) &&
38 (fabsf(local[1]) <= 1.0f) &&
39 (fabsf(local[2]) <= 1.0f) )
40 {
41 route->flags &= ~k_ent_route_flag_out_of_zone;
42 }
43 else
44 {
45 route->flags |= k_ent_route_flag_out_of_zone;
46 }
47 }
48
49 gui_location_print_ccmd( 1, (const char *[]){
50 mdl_pstr(&world->meta,region->pstr_title)} );
51
52 vg_strncpy( mdl_pstr(&world->meta,region->pstr_title),
53 global_ent_region.location, NETWORK_REGION_MAX,
54 k_strncpy_always_add_null );
55 global_ent_region.flags = region->flags;
56 network_send_region();
57
58 localplayer.effect_data.spark.colour = region_spark_colour(region->flags);
59 return k_entity_call_result_OK;
60 }
61 else if( call->function == 1 ) /* leave */
62 {
63 for( u32 i=0; i<mdl_arrcount(&world->ent_route); i ++ )
64 {
65 ent_route *route = mdl_arritm( &world->ent_route, i );
66 route->flags |= k_ent_route_flag_out_of_zone;
67 }
68 localplayer.effect_data.spark.colour = 0x00;
69 return k_entity_call_result_OK;
70 }
71 else
72 return k_entity_call_result_unhandled;
73 }
74
75 /*
76 * reevaluate all achievements to calculate the compiled achievement
77 */
78 void ent_region_re_eval( world_instance *world )
79 {
80 u32 world_total = k_ent_route_flag_achieve_gold |
81 k_ent_route_flag_achieve_silver;
82
83 for( u32 i=0; i<mdl_arrcount(&world->ent_region); i ++ ){
84 ent_region *region = mdl_arritm(&world->ent_region, i);
85
86 if( !region->zone_volume )
87 continue;
88
89 ent_volume *volume = mdl_arritm(&world->ent_volume,
90 mdl_entity_id_id(region->zone_volume));
91
92 u32 combined = k_ent_route_flag_achieve_gold |
93 k_ent_route_flag_achieve_silver;
94
95 for( u32 j=0; j<mdl_arrcount(&world->ent_route); j ++ ){
96 ent_route *route = mdl_arritm(&world->ent_route, j );
97
98 v3f local;
99 m4x3_mulv( volume->to_local, route->board_transform[3], local );
100 if( !((fabsf(local[0]) <= 1.0f) &&
101 (fabsf(local[1]) <= 1.0f) &&
102 (fabsf(local[2]) <= 1.0f)) ){
103 continue;
104 }
105
106 combined &= route->flags;
107 }
108
109 for( u32 j=0; j<mdl_arrcount(&world->ent_challenge); j ++ ){
110 ent_challenge *challenge = mdl_arritm( &world->ent_challenge, j );
111
112 v3f local;
113 m4x3_mulv( volume->to_local, challenge->transform.co, local );
114 if( !((fabsf(local[0]) <= 1.0f) &&
115 (fabsf(local[1]) <= 1.0f) &&
116 (fabsf(local[2]) <= 1.0f)) ){
117 continue;
118 }
119
120 u32 flags = 0x00;
121 if( challenge->status ){
122 flags |= k_ent_route_flag_achieve_gold;
123 flags |= k_ent_route_flag_achieve_silver;
124 }
125
126 combined &= flags;
127 }
128
129 region->flags = combined;
130 world_total &= combined;
131
132 /* run unlock triggers. v105+ */
133 if( world->meta.info.version >= 105 ){
134 if( region->flags & (k_ent_route_flag_achieve_gold|
135 k_ent_route_flag_achieve_silver) ){
136 if( region->target0[0] ){
137 ent_call call;
138 call.data = NULL;
139 call.id = region->target0[0];
140 call.function = region->target0[1];
141 entity_call( world, &call );
142 }
143 }
144 }
145 }
146
147 u32 instance_id = world - world_static.instances;
148
149 if( world_static.instance_addons[instance_id]->flags & ADDON_REG_MTZERO ){
150 if( world_total & k_ent_route_flag_achieve_gold ){
151 steam_set_achievement( "MTZERO_GOLD" );
152 steam_store_achievements();
153 }
154
155 if( world_total & k_ent_route_flag_achieve_silver ){
156 steam_set_achievement( "MTZERO_SILVER" );
157 steam_store_achievements();
158 }
159 }
160
161 if( world_static.instance_addons[instance_id]->flags & ADDON_REG_CITY ){
162 steam_set_achievement( "CITY_COMPLETE" );
163 steam_store_achievements();
164 }
165 }