#include "StageEditor_Chara.h" #include "StageEditor_Event.h" #include "StageEditor_TopButton.h" #include "StageEditor_MoveButton.h" #include "ToolLib.h" // キャラ配置リストの座標と幅と高さ #define LIST_X (4) #define LIST_Y (TOPBUTTON_Y + TOPBUTTON_H + TOOL_WINDOW_NAME_HEIGHT + 4) #define LIST_W (256) #define LIST_H (200) // キャラの操作ボタンの基準座標 #define BUTTONS_X (0) #define BUTTONS_Y (4 + TOOL_SCROLLBAR_WIDTH + g_CEData.ButtonSpace.SpaceStart) // キャラの操作ボタンを配置する範囲の高さ #define BUTTONS_H (135) // キャラの移動ボタンの配置座標 #define MOVE_X (4) #define MOVE_Y (BUTTONS_Y + 50) // キャラリストの座標と幅と高さ #define CHARA_LIST_X (LIST_X) #define CHARA_LIST_Y (4) #define CHARA_LIST_W (256) #define CHARA_LIST_H (96) // キャラ配置編集情報 typedef struct _SCharaEditData { // 編集対象のキャラの配置番号 // ( -1 の場合はプレイヤーキャラが選択されているとみなす ) int Target; // スペース管理情報ハンドル int TSpaceManage; // 編集モード切替ボタン部分用のスペース情報 SToolSpace TopSpace; // キャラ配置リスト表示用ウインドウのハンドル int ListTWindow; // キャラ配置リストのハンドル int TList; // 操作ボタン部分用のスペース情報 SToolSpace ButtonSpace; // 配置キャラ追加ボタンのハンドル int AddTButton; // 配置キャラ削除ボタンのハンドル int DelTButton; // 選択キャラの角度操作用ボタンのハンドル int AnglePlusTButton; int AngleMinusTButton; // 選択キャラの移動ボタンの情報 SMoveButtonData MoveButton; // 選択キャラが何のキャラなのかを指定するためのリスト表示用ウインドウのハンドル int CharaListTWindow; // 選択キャラが何のキャラなのかを指定するためのリストのハンドル int CharaTList; // ステージエディターで使用するキャラクターの3Dモデルハンドル int CharaModelHandle[ EChara_Num ]; } SCharaEditData; SCharaEditData g_CEData; // キャラの配置情報を追加する // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_Add( void ); // 選択中のキャラの配置情報を削除する // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_Del( void ); // キャラ配置リストをセットアップする // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_SetupList( void ); // キャラリストの選択対象をセットアップする static void StageEditor_Chara_SetupInfo( void ); // キャラ配置情報編集処理の初期化を行う // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool StageEditor_Chara_Initialize( void ) { int i; int VisibleHandle; SCharaBaseInfo *CBInfo; // スペース管理情報の作成 g_CEData.TSpaceManage = ToolSpaceManage_Create( SCREEN_HEIGHT ); if( g_CEData.TSpaceManage == -1 ) { return false; } // 編集モード切替ボタン部分用のスペース情報を追加 if( !ToolSpaceManage_AddSpace( g_CEData.TSpaceManage, &g_CEData.TopSpace, TOPSPACE, true ) ) { return false; } // キャラ配置リスト表示用ウインドウの作成 g_CEData.ListTWindow = ToolWindow_Create( g_CEData.TSpaceManage, false, true, false, "キャラ一覧", LIST_X, LIST_Y, LIST_W, LIST_H, LIST_W, LIST_H ); if( g_CEData.ListTWindow == -1 ) { return false; } // キャラ配置リストの作成 g_CEData.TList = ToolList_Create(); if( g_CEData.TList == -1 ) { return false; } // キャラ配置リストを初期化 ToolList_Initialize( g_CEData.TList, g_CEData.ListTWindow ); // 操作ボタン部分用のスペース情報を追加 if( !ToolSpaceManage_AddSpace( g_CEData.TSpaceManage, &g_CEData.ButtonSpace, BUTTONS_H, true ) ) { return false; } // 配置キャラ追加ボタンの作成 g_CEData.AddTButton = ToolButton_Create( false, "キャラ追加", BUTTONS_X + 4, BUTTONS_Y + 0, 70, 20 ); if( g_CEData.AddTButton == -1 ) { return false; } // 配置キャラ削除ボタンの作成 g_CEData.DelTButton = ToolButton_Create( false, "キャラ削除", BUTTONS_X + 74, BUTTONS_Y + 0, 70, 20 ); if( g_CEData.DelTButton == -1 ) { return false; } // 選択キャラ角度操作用ボタンの作成 g_CEData.AnglePlusTButton = ToolButton_Create( false, "向き+", BUTTONS_X + 79, BUTTONS_Y + 26, 50, 20 ); if( g_CEData.AnglePlusTButton == -1 ) { return false; } g_CEData.AngleMinusTButton = ToolButton_Create( false, "向き-", BUTTONS_X + 129, BUTTONS_Y + 26, 50, 20 ); if( g_CEData.AngleMinusTButton == -1 ) { return false; } // 選択キャラ移動用ボタン情報の初期化 if( !MoveButton_Initialize( &g_CEData.MoveButton, MOVE_X, MOVE_Y ) ) { return false; } // 選択キャラが何のキャラなのかを指定するためのリスト表示用ウインドウの作成 g_CEData.CharaListTWindow = ToolWindow_Create( g_CEData.TSpaceManage, false, true, false, "キャラクタ一覧", CHARA_LIST_X, CHARA_LIST_Y, CHARA_LIST_W, CHARA_LIST_H, CHARA_LIST_W, CHARA_LIST_H ); if( g_CEData.CharaListTWindow == -1 ) { return false; } // 選択キャラが何のキャラなのかを指定するためのリストを作成 g_CEData.CharaTList = ToolList_Create(); if( g_CEData.CharaTList == -1 ) { return false; } // キャラ指定用リストを初期化 ToolList_Initialize( g_CEData.CharaTList, g_CEData.CharaListTWindow ); // 全てのキャラをリストに登録 for( i = 0; i < EChara_Num; i++ ) { ToolList_AddObj( g_CEData.CharaTList, CharaBase_GetInfo( ( EChara )i )->Name ); } // キャラ配置編集処理用の表示状態情報ハンドルを取得 VisibleHandle = StageEditor_TopButton_GetEditModeVisibleHandle( EEditMode_CharaEdit); // キャラ配置編集で使用するウインドウやボタンと表示状態情報ハンドルを関連付ける ToolWindow_SetVisibleHandle( g_CEData.ListTWindow, VisibleHandle ); ToolButton_SetVisibleHandle( g_CEData.AddTButton, VisibleHandle ); ToolButton_SetVisibleHandle( g_CEData.DelTButton, VisibleHandle ); ToolButton_SetVisibleHandle( g_CEData.AnglePlusTButton, VisibleHandle ); ToolButton_SetVisibleHandle( g_CEData.AngleMinusTButton, VisibleHandle ); MoveButton_SetVisibleHandle( &g_CEData.MoveButton, VisibleHandle ); ToolWindow_SetVisibleHandle( g_CEData.CharaListTWindow, VisibleHandle ); // ステージエディターで使用するキャラクターの3Dモデルを作成する for( i = 0; i < EChara_Num; i++ ) { // キャラクターの基本情報を取得する CBInfo = CharaBase_GetInfo( ( EChara )i ); // 3Dモデルの複製 g_CEData.CharaModelHandle[ i ] = MV1DuplicateModel( CBInfo->ModelHandle ); // ニュートラルアニメーションをアタッチ MV1AttachAnim( g_CEData.CharaModelHandle[ i ], 0, CBInfo->AnimInfo[ ECharaAnim_Neutral ].Handle ); } // 正常終了 return true; } // キャラ配置情報編集処理のステージ読み込み後の初期化処理を行う // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool StageEditor_Chara_StageLoadInitialize( void ) { // 選択対象を初期化 g_CEData.Target = -1; // キャラ配置リストを更新 if( !StageEditor_Chara_SetupList() ) { return false; } // 正常終了 return true; } // キャラ配置情報編集処理で選択されているキャラの座標を取得する void StagaEditor_Chara_GetTargetPos( // 座標を代入する変数のアドレス VECTOR *TargetPos ) { // -1の場合はプレイヤーキャラが選択されているとみなす if( g_CEData.Target == -1 ) { *TargetPos = g_StageData.Header.PlayerPosition; } else { *TargetPos = g_StageData.CharaInfo[ g_CEData.Target ].Position; } } // キャラの配置情報を追加する // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_Add( void ) { SStageCharaInfo *CInfo; // キャラ配置情報の数が既に最大数に達していたら何もせずに終了 if( g_StageData.Header.CharaInfoNum == STAGE_CHARA_MAX_NUM ) { return true; } // 新しいキャラ配置情報の初期化 CInfo = &g_StageData.CharaInfo[ g_StageData.Header.CharaInfoNum ]; CInfo->Chara = ( EChara )0; CInfo->Position = VAdd( g_SEData.Camera.Position, VScale( g_SEData.Camera.Direction, ADD_UNIT_DISTANCE ) ); CInfo->Angle = 0.0f; // 選択しているキャラ配置情報を追加したキャラ配置情報にする g_CEData.Target = g_StageData.Header.CharaInfoNum; // キャラ配置情報の数を増やす g_StageData.Header.CharaInfoNum++; // キャラ配置リストを更新する if( !StageEditor_Chara_SetupList() ) { return false; } // イベントの情報を更新する StageEditor_Event_SetupInfo(); // 正常終了 return true; } // 選択中のキャラの配置情報を削除する // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_Del( void ) { int DelIndex; // キャラ配置情報が1つも無いか、プレイヤーキャラが // 選択されている場合は何もせずに終了 if( g_CEData.Target < 0 || g_StageData.Header.CharaInfoNum == 0 ) { return true; } // 削除する対象の配置情報番号を保存 DelIndex = g_CEData.Target; // キャラ配置情報の数を減らす g_StageData.Header.CharaInfoNum--; // 削除処理後の選択対象のキャラ配置情報を決定 if( g_CEData.Target == g_StageData.Header.CharaInfoNum ) { g_CEData.Target = g_StageData.Header.CharaInfoNum - 1; } else { // 削除対象が配列の途中だった場合は情報を詰める memmove( &g_StageData.CharaInfo[ g_CEData.Target ], &g_StageData.CharaInfo[ g_CEData.Target + 1 ], sizeof( SStageCharaInfo ) * ( g_StageData.Header.CharaInfoNum - g_CEData.Target ) ); } // イベントで削除するキャラ配置情報が使用されている可能性があるので、 // イベント情報からも削除するキャラ配置情報の情報を削除する StageEditor_Event_DelObject( EStageEventType_CharaAppear, DelIndex ); // キャラ配置リストの情報を更新 if( !StageEditor_Chara_SetupList() ) { return false; } // 正常終了 return true; } // キャラ配置情報編集処理の状態推移処理を行う // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) bool StageEditor_Chara_Step( void ) { SStageCharaInfo *CInfo; VECTOR *TargetPosition; float *TargetAngle; int MouseClickChara; bool MouseClickCharaEnable; float MouseClickCharaDistanceSq; int i; float DistanceSq; VECTOR CapsulePos1; VECTOR CapsulePos2; SCharaBaseInfo *CBInfo; // 画面上に表示されているキャラがマウスカーソルでクリックされたかどうかを調べる if( ( g_SEData.Mouse.EdgeInput & MOUSE_INPUT_LEFT ) != 0 && Tool_GetBaseRightX() < g_SEData.Mouse.ClickPosX ) { // クリックされた座標で最も近いキャラを割り出す MouseClickCharaEnable = false; MouseClickCharaDistanceSq = 0.0f; for( i = -1; i < g_StageData.Header.CharaInfoNum; i++ ) { if( i == -1 ) { CBInfo = CharaBase_GetInfo( EChara_Player ); CharaBase_GetHitCapsulePos( &CBInfo->DamageHitInfo, &g_StageData.Header.PlayerPosition, &CapsulePos1, &CapsulePos2 ); } else { CBInfo = CharaBase_GetInfo( g_StageData.CharaInfo[ i ].Chara ); CharaBase_GetHitCapsulePos( &CBInfo->DamageHitInfo, &g_StageData.CharaInfo[ i ].Position, &CapsulePos1, &CapsulePos2 ); } // クリックされた点とカプセル形状との当たり判定 DistanceSq = Segment_Segment_MinLength_Square( g_SEData.Mouse.ClickPosNear, g_SEData.Mouse.ClickPosFar, CapsulePos1, CapsulePos2 ); // 当たっているか判定 if( DistanceSq < CBInfo->DamageHitInfo.Width * CBInfo->DamageHitInfo.Width ) { // 当たっていたら、今まで当たったキャラが居なかったか、 // 又は今まで当たったキャラより近かったら記録 if( MouseClickCharaEnable == false || DistanceSq < MouseClickCharaDistanceSq ) { MouseClickCharaEnable = true; MouseClickChara = i; MouseClickCharaDistanceSq = DistanceSq; } } } // キャラがクリックされた場合は編集対象のキャラの変更処理を行う if( MouseClickCharaEnable ) { g_CEData.Target = MouseClickChara; // キャラ配置リストの選択行を変更する ToolList_SetSelectIndex( g_CEData.TList, g_CEData.Target + 1 ); // 『選択キャラが何のキャラなのか』の情報の更新 StageEditor_Chara_SetupInfo(); } } // キャラ配置リストの状態が変化した場合は新しい編集対象を取得する if( ToolList_GetChange( g_CEData.TList, true ) ) { g_CEData.Target = ToolList_GetSelectIndex( g_CEData.TList ) - 1; // 『選択キャラが何のキャラなのか』の情報の更新 StageEditor_Chara_SetupInfo(); // カメラを選択キャラが見える位置に移動する SetupTargetLookAtCamera(); } // 編集対象の構造体・座標・向きのアドレスを取得 if( g_CEData.Target == -1 ) { // -1 の場合はプレイヤーキャラが編集対象 CInfo = NULL; TargetPosition = &g_StageData.Header.PlayerPosition; TargetAngle = &g_StageData.Header.PlayerAngle; // プレイヤーが編集対象の場合は // 『選択キャラが何のキャラなのか』を選択する為のリストは表示しない ToolWindow_SetVisible( g_CEData.CharaListTWindow, false ); } else { CInfo = &g_StageData.CharaInfo[ g_CEData.Target ]; TargetPosition = &CInfo->Position; TargetAngle = &CInfo->Angle; ToolWindow_SetVisible( g_CEData.CharaListTWindow, true ); } // 選択キャラの移動ボタンによる移動処理を行う if( MoveButton_Step( &g_CEData.MoveButton,TargetPosition,MOVE_BASE_SPEED * g_SEData.MoveSpeedF ) ) { // 移動が行われた場合はキャラ配置リストの情報更新を行う if( !StageEditor_Chara_SetupList() ) { return false; } } // 『選択キャラが何のキャラなのか』のリストの状態が変化しているか調べる if( ToolList_GetChange( g_CEData.CharaTList, true ) ) { // 状態が変化した場合は選択された行に従って選択キャラのキャラを変更する if( g_CEData.Target >= 0 ) { CInfo->Chara = ( EChara )ToolList_GetSelectIndex( g_CEData.CharaTList ); // キャラ配置リストの情報を更新する if( !StageEditor_Chara_SetupList() ) { return false; } } } // 選択キャラの角度操作用ボタンが押された場合は選択キャラの向きを変更する if( ToolButton_GetRepeatBottom( g_CEData.AngleMinusTButton ) ) { *TargetAngle -= ANGLE_BASE_SPEED * g_SEData.AngleSpeedF; if( *TargetAngle < 0.0f ) { *TargetAngle += DX_PI_F * 2.0f; } // キャラ配置リストの情報を更新する if( !StageEditor_Chara_SetupList() ) { return false; } } if( ToolButton_GetRepeatBottom( g_CEData.AnglePlusTButton ) ) { *TargetAngle += ANGLE_BASE_SPEED * g_SEData.AngleSpeedF; if( *TargetAngle >= DX_PI_F * 2.0f ) { *TargetAngle -= DX_PI_F * 2.0f; } // キャラ配置リストの情報を更新する if( !StageEditor_Chara_SetupList() ) { return false; } } // 配置キャラを追加するボタンが押されたら配置キャラを追加する if( ToolButton_GetClick( g_CEData.AddTButton, true ) ) { if( !StageEditor_Chara_Add() ) { return false; } } // 配置キャラを削除するボタンが押されたら選択されている配置キャラを削除する if( ToolButton_GetClick( g_CEData.DelTButton, true ) ) { if( !StageEditor_Chara_Del() ) { return false; } } // 正常終了 return true; } // キャラ配置情報編集処理の描画処理を行う void StageEditor_Chara_Render( void ) { SStageCharaInfo *CInfo; int i; int ModelHandle; // プレイヤーキャラを描画 ModelHandle = g_CEData.CharaModelHandle[ EChara_Player ]; MV1SetPosition( ModelHandle, g_StageData.Header.PlayerPosition ); MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, g_StageData.Header.PlayerAngle, 0.0f ) ); if( g_CEData.Target < 0 ) { MV1SetDifColorScale( ModelHandle, g_SEData.BrinkColor ); } else { MV1SetDifColorScale( ModelHandle, GetColorF( 1.0f,1.0f,1.0f,1.0f ) ); } MV1DrawModel( ModelHandle ); // プレイヤー以外の配置キャラを描画 CInfo = g_StageData.CharaInfo; for( i = 0; i < g_StageData.Header.CharaInfoNum; i++, CInfo++ ) { ModelHandle = g_CEData.CharaModelHandle[ CInfo->Chara ]; MV1SetPosition( ModelHandle, CInfo->Position ); MV1SetRotationXYZ( ModelHandle, VGet( 0.0f, CInfo->Angle, 0.0f ) ); if( g_SEData.EditMode == EEditMode_CharaEdit && g_CEData.Target == i ) { MV1SetDifColorScale( ModelHandle, g_SEData.BrinkColor ); } else { MV1SetDifColorScale( ModelHandle, GetColorF( 1.0f,1.0f,1.0f,1.0f ) ); } MV1DrawModel( ModelHandle ); } } // キャラ配置リストをセットアップする // 戻り値 : 処理が正常に終了したかどうか(true:正常に終了した false:エラーが発生した) static bool StageEditor_Chara_SetupList( void ) { int i; SStageCharaInfo *CInfo; // キャラ配置リストを初期化する ToolList_Initialize( g_CEData.TList, g_CEData.ListTWindow ); // プレイヤーキャラの情報をリストに追加する if( !ToolList_AddObj( g_CEData.TList, "No:-- Chara:プレイヤー Pos:( %.1f, %.1f, %.1f )", g_StageData.Header.PlayerPosition.x, g_StageData.Header.PlayerPosition.y, g_StageData.Header.PlayerPosition.z ) ) { return false; } // プレイヤーキャラ以外の配置キャラの情報をリストに追加する CInfo = g_StageData.CharaInfo; for( i = 0; i < g_StageData.Header.CharaInfoNum; i++, CInfo++ ) { if( !ToolList_AddObj( g_CEData.TList, "No:%d Chara:%s Pos:( %.1f, %.1f, %.1f )", i, CharaBase_GetInfo( CInfo->Chara )->Name, CInfo->Position.x, CInfo->Position.y, CInfo->Position.z )) { return false; } } // 編集対象のキャラの行を選択状態にする ToolList_SetSelectIndex( g_CEData.TList, g_CEData.Target + 1 ); // 『選択キャラが何のキャラなのか』の情報の更新 StageEditor_Chara_SetupInfo(); // 正常終了 return true; } // キャラリストの選択対象をセットアップする static void StageEditor_Chara_SetupInfo( void ) { SStageCharaInfo *CInfo; // 配置キャラが1体も無い場合は何もせずに終了 if( g_StageData.Header.CharaInfoNum == 0 ) { return; } // 選択キャラがプレイヤーキャラの場合は何もせずに終了 if( g_CEData.Target < 0 ) { return; } CInfo = &g_StageData.CharaInfo[ g_CEData.Target ]; // 『選択キャラが何のキャラなのか』のリストの // 選択されている配置キャラのキャラの行を選択状態にする ToolList_SetSelectIndex( g_CEData.CharaTList, CInfo->Chara ); }