6464#define SOUND_HIT_SLAP 8
6565#define SOUND_HIT_FLAIL 9
6666
67+ zNPCB_SB2* _singleton;
68+
6769namespace
6870{
6971 struct sound_data_type
@@ -82,15 +84,36 @@ namespace
8284 U32 flags;
8385 };
8486
87+ struct curve_node
88+ {
89+ F32 time;
90+ iColor_tag color;
91+ F32 scale;
92+ };
93+
94+ struct platform_hook
95+ {
96+ char * name;
97+ };
98+
8599 static U32 sound_asset_ids[10 ][4 ];
86100 static sound_data_type sound_data[10 ];
101+
102+ static response_curve rc_scale;
103+
104+ static xBinaryCamera boss_cam;
105+
87106 static const sound_asset sound_assets[12 ] = {
88107 { 0 , " RSB_laugh" , 0 , 0 }, { 1 , " RSB_kah" , 0 , 0 }, { 2 , " RSB_chop_windup" , 0 , 0 },
89108 { 3 , " RSB_chop_swing" , 0 , 0 }, { 4 , " RSB_swipe" , 0 , 0 }, { 5 , " RSB_foot_loop" , 0 , 1 },
90109 { 6 , " RSB_armhit1" , 0 , 0 }, { 6 , " RSB_armhit2" , 0 , 0 }, { 7 , " RSB_armhit1" , 0 , 0 },
91110 { 7 , " RSB_armhit2" , 0 , 0 }, { 8 , " RSB_armsmash" , 0 , 0 }, { 9 , " RSB_foor_impact" , 0 , 0 },
92111 };
93112
113+ static platform_hook platform_hooks[16 ];
114+
115+ static curve_node scale_curve[4 ];
116+
94117 void set_alpha_blend (xModelInstance* model)
95118 {
96119 model->PipeFlags &= ~0xFF0C ;
@@ -106,9 +129,8 @@ namespace
106129 return f1;
107130 }
108131
109- S32 tweak ()
132+ static void init_sound ()
110133 {
111- return 0 ; // to-do
112134 }
113135
114136 void reset_sound ()
@@ -224,6 +246,8 @@ namespace
224246 void register_tweaks (bool init, xModelAssetParam* ap, U32 apsize, const char *);
225247 };
226248
249+ static tweak_group tweak;
250+
227251 void tweak_group::load (xModelAssetParam* params, U32 size)
228252 {
229253 tweak_group::register_tweaks (true , params, size, NULL );
@@ -1110,6 +1134,83 @@ xAnimTable* ZNPC_AnimTable_BossSB2()
11101134 return table;
11111135}
11121136
1137+ void zNPCB_SB2::Init (xEntAsset* asset)
1138+ {
1139+ xModelInstance * m;
1140+
1141+ _singleton = this ;
1142+ boss_cam.init ();
1143+ init_sound ();
1144+ zNPCCommon::Init (asset);
1145+ this ->cfg_npc ->dst_castShadow = 30 .0f ;
1146+ memset ((void *)this ->flag .face_player , 0 , 0x10 );
1147+ this ->said_intro = 0 ;
1148+
1149+ m = this ->model ;
1150+ this ->models [0 ] = this ->model ;
1151+
1152+ this ->models [1 ] = m->Next ;
1153+ this ->models [2 ] = m->Next ;
1154+ this ->models [3 ] = m->Next ;
1155+
1156+ this ->models [0 ]->Data ->boundingSphere .radius = 100 .0f ;
1157+ this ->models [1 ]->Data ->boundingSphere .radius = 100 .0f ;
1158+ this ->models [2 ]->Data ->boundingSphere .radius = 100 .0f ;
1159+ this ->models [3 ]->Data ->boundingSphere .radius = 100 .0f ;
1160+
1161+ set_alpha_blend (this ->models [0 ]);
1162+ this ->init_hands ();
1163+ this ->init_bounds ();
1164+ this ->reset_bounds ();
1165+
1166+ this ->penby = FALSE ;
1167+ this ->bupdate = 0 ;
1168+ this ->bound .type = TRUE ;
1169+ this ->bound .sph .center .y = 1e38f;
1170+ this ->bound .sph .r = 0 .0f ;
1171+
1172+ response_curve::init ((U32)&rc_scale, 0 , 0 , 0 , 0 , 0 , 0 );
1173+
1174+ this ->init_slugs ();
1175+ }
1176+
1177+ void zNPCB_SB2::Setup ()
1178+ {
1179+ xEnt* ent;
1180+ xSphere o;
1181+
1182+ this ->create_glow_light ();
1183+ this ->init_nodes ();
1184+ zNPCBoss::Setup ();
1185+
1186+ for (S32 i = 0 ; i < 16 ; i++)
1187+ {
1188+ this ->platforms [i].ent = 0 ;
1189+ zSceneFindObject (xStrHash (platform_hooks[i].name ));
1190+ }
1191+
1192+ if (this ->models [3 ]->Surf == NULL )
1193+ {
1194+ this ->models [3 ]->Surf = &create_surface ();
1195+ }
1196+
1197+ if (this ->models [0 ]->Surf == NULL )
1198+ {
1199+ this ->models [0 ]->Surf = &create_surface ();
1200+ }
1201+
1202+ // models[3]->Surf->moprops = 0;
1203+ // models[0]->Surf->moprops = 7;
1204+
1205+ this ->scan_cronies ();
1206+ (xBase*)&this ->newsfish ->id = zSceneFindObject (xStrHash (" NPC_NEWSCASTER" ));
1207+
1208+ if (this ->newsfish ->id != NULL )
1209+ {
1210+ this ->newsfish ->TalkOnScreen (1 );
1211+ }
1212+ }
1213+
11131214void zNPCB_SB2::SelfSetup ()
11141215{
11151216 xBehaveMgr* bmgr = xBehaveMgr_GetSelf ();
@@ -1125,14 +1226,125 @@ void zNPCB_SB2::SelfSetup()
11251226 psy_instinct->SetSafety (NPC_GOAL_BOSSSB2IDLE);
11261227}
11271228
1229+ void zNPCB_SB2::Reset ()
1230+ {
1231+ if (this ->newsfish != 0 )
1232+ {
1233+ this ->newsfish ->Reset ();
1234+ }
1235+
1236+ reset_sound ();
1237+ zNPCCommon::Reset ();
1238+ memset (&flag.face_player , 0 , 0x10 );
1239+
1240+ for (S32 i = 0 ; i < 9 ; i++)
1241+ {
1242+ if (nodes[i].ent != NULL )
1243+ {
1244+ zEntDestructObj_Reset (nodes[i].ent , globals.sceneCur );
1245+ xEntShow (nodes[i].ent );
1246+ }
1247+ }
1248+
1249+ for (S32 i = 0 ; i < 16 ; i++)
1250+ {
1251+ if (platforms[i].ent != NULL )
1252+ {
1253+ zEntEvent (this , platforms[i].ent , 10 );
1254+ }
1255+ }
1256+
1257+ this ->life = 0 ;
1258+ this ->round = 0 ;
1259+
1260+ this ->check_life ();
1261+ this ->choose_hand ();
1262+ this ->reset_speed ();
1263+ this ->show_nodes ();
1264+
1265+ this ->turn .vel = 0 .0f ;
1266+ this ->node_pulse = 0 .0f ;
1267+ this ->flag .face_player = TRUE ;
1268+ this ->flag .move = MOVE_NONE;
1269+ this ->player_damage_timer = 0 .0f ;
1270+ this ->old_player_health = 0 ;
1271+
1272+ this ->reset_stage ();
1273+ this ->set_vulnerable (TRUE );
1274+ zCameraDisableTracking (CO_BOSS);
1275+ boss_cam.start (globals.camera );
1276+ psy_instinct->GoalSet (NPC_GOAL_BOSSSB2INTRO, 0 );
1277+
1278+ }
1279+
11281280void zNPCB_SB2::Destroy ()
11291281{
11301282 zNPCB_SB2::destroy_glow_light ();
11311283 zNPCCommon::Destroy ();
11321284}
11331285
1134- void zNPCB_SB2::NewTime (xScene* x , F32 y )
1286+ void zNPCB_SB2::Process (xScene* xscn , F32 dt )
11351287{
1288+ if (this ->flag .updated == FALSE )
1289+ {
1290+ boss_cam.set_targets ((xVec3&)globals.player .ent .model ->Mat ->pos , location (),
1291+ 5 .0f );
1292+ this ->flag .updated = TRUE ;
1293+ }
1294+
1295+ this ->check_life ();
1296+ this ->player_damage_timer = this ->player_damage_timer - dt;
1297+
1298+ if ((globals.player .Health < this ->old_player_health ) && this ->old_player_health != 0 )
1299+ {
1300+ this ->player_damage_timer = tweak.player_damage_time ;
1301+ say (1 );
1302+ }
1303+
1304+ this ->old_player_health = globals.player .Health ;
1305+
1306+ if ((SomethingWonderful () & 0x23 ) == 0 )
1307+ {
1308+ delay = delay + dt;
1309+ this ->psy_instinct ->Timestep (dt, 0 );
1310+ }
1311+
1312+ this ->update_nodes (dt);
1313+ this ->update_slugs (dt);
1314+ this ->update_move (dt);
1315+ this ->update_turn (dt);
1316+ this ->update_camera (dt);
1317+ this ->check_hit_fail ();
1318+ zNPCCommon::Process (xscn, dt);
1319+ }
1320+
1321+ void zNPCB_SB2::NewTime (xScene* xscn, F32 dt)
1322+ {
1323+ xVec3 tmp;
1324+
1325+ if (this ->flag .nodes_taken == NULL )
1326+ {
1327+ this ->move_nodes ();
1328+ }
1329+
1330+ for (S32 i = 0 ; i < 2 ; i++)
1331+ {
1332+ this ->move_hand (this ->hands [i], dt);
1333+ }
1334+
1335+ this ->update_bounds ();
1336+ this ->update_platforms (dt);
1337+ this ->update_slugs (dt);
1338+
1339+ this ->models [1 ]->Flags = this ->models [1 ]->Flags & 0xefff ;
1340+ this ->models [2 ]->Flags = this ->models [2 ]->Flags & 0xefff ;
1341+
1342+ this ->sound_loc .mouth = xModelGetBoneLocation (*model, 4 );
1343+ this ->sound_loc .body = this ->sound_loc .mouth ;
1344+ this ->sound_loc .hand [0 ] = xModelGetBoneLocation (*model, 16 );
1345+ this ->sound_loc .hand [1 ] = xModelGetBoneLocation (*model, 21 );
1346+
1347+ zNPCCommon::NewTime (xscn, dt);
11361348}
11371349
11381350void zNPCB_SB2::decompose ()
@@ -1165,8 +1377,6 @@ void zNPCB_SB2::ouchie()
11651377
11661378}
11671379
1168-
1169-
11701380void zNPCB_SB2::Render ()
11711381{
11721382 xNPCBasic::Render ();
@@ -1193,27 +1403,32 @@ void zNPCB_SB2::ThanksImDone()
11931403
11941404void zNPCB_SB2::reset_speed ()
11951405{
1196- turn.accel = 0 ;
1197- turn.max_vel = 0 ;
1406+ turn.accel = tweak. turn_accel ;
1407+ turn.max_vel = tweak. turn_max_vel ;
11981408}
11991409
12001410S32 zNPCB_SB2::player_platform ()
12011411{
1202- return 0 ; // TODO
1412+ if (((globals.player .ent .collis ->colls ->flags & 1 ) != 0 ))
1413+ {
1414+ return 1 ;
1415+ }
1416+
1417+ return NULL ;
12031418}
12041419
1205- void zNPCB_SB2::activate_hand (zNPCB_SB2::hand_enum, bool )
1420+ void zNPCB_SB2::activate_hand (zNPCB_SB2::hand_enum hand , bool )
12061421{
12071422 hands[0 ].hurt_player = 1 ;
12081423 hands[0 ].hit_platforms = 0x10 ;
1209- penby = 0x10 ;
1424+ hands[ 0 ]. ent -> penby = 0x10 ;
12101425}
12111426
1212- void zNPCB_SB2::deactivate_hand (zNPCB_SB2::hand_enum)
1427+ void zNPCB_SB2::deactivate_hand (zNPCB_SB2::hand_enum hand )
12131428{
12141429 hands[0 ].hit_platforms = 0 ;
12151430 hands[0 ].hurt_player = 0x10 ;
1216- penby = 0x10 ;
1431+ hands[ 0 ]. ent -> penby = 0 ;
12171432}
12181433
12191434S32 zNPCB_SB2::player_on_ground () const
@@ -1222,10 +1437,39 @@ S32 zNPCB_SB2::player_on_ground() const
12221437 // TODO
12231438}
12241439
1440+ void zNPCB_SB2::emit_slug (zNPCB_SB2::slug_enum which)
1441+ {
1442+ slug_data& slug = slugs[which];
1443+ F32 launch_ang;
1444+ F32 accel_time;
1445+
1446+ if (slug.ent ->id != 0 )
1447+ {
1448+ slug.stage = (zNPCB_SB2::slug_stage)1 ;
1449+ slug.time = 0 .0f ;
1450+ slug.stage_delay = tweak.karate .aim_time ;
1451+ slug.vel = 0 .0f ;
1452+ slug.dist = 0 .0f ;
1453+ slug.abandoned = 0 ;
1454+
1455+ xMat4x3Mul ((xMat4x3*)model->Mat , 0 , 0 );
1456+ xMat3x3RMulVec (&tweak.karate .emit_offset , 0 , 0 );
1457+ }
1458+ }
1459+
1460+ void zNPCB_SB2::fire_slug (zNPCB_SB2::slug_enum which, zNPCB_SB2::platform_data& target)
1461+ {
1462+ slug_data& slug = slugs[which];
1463+ xVec3 offset;
1464+ F32 idist;
1465+
1466+ slug.stage = SLUG_DELAY;
1467+ }
1468+
12251469void zNPCB_SB2::abandon_slugs ()
12261470{
1227- slug_data* pCurSlug = &slugs[0 ];
1228- slug_data* pLastSlug = &pCurSlug[3 ];
1471+ slug_data* pCurSlug = &slugs[0 ];
1472+ slug_data* pLastSlug = &pCurSlug[3 ];
12291473 for (; pCurSlug != pLastSlug; pCurSlug++)
12301474 {
12311475 pCurSlug->abandoned = 1 ;
0 commit comments