X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。
| Revision | 2 (tree) |
|---|---|
| Time | 2015-01-10 02:26:25 |
| Author | |
初版コミット
| @@ -0,0 +1,95 @@ | ||
| 1 | +//! @file input.h | |
| 2 | +//! @brief InputControlクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef INPUT_H | |
| 33 | +#define INPUT_H | |
| 34 | + | |
| 35 | +#ifndef H_LAYERLEVEL | |
| 36 | + #define H_LAYERLEVEL 1 //!< Select include file. | |
| 37 | +#endif | |
| 38 | +#include "main.h" | |
| 39 | + | |
| 40 | +#include <windows.h> | |
| 41 | + | |
| 42 | +#ifdef INPUT_DIRECTINPUT | |
| 43 | + #define DIRECTINPUT_VERSION 0x0800 //!< 警告「DIRECTINPUT_VERSION undefined. Defaulting to version 0x0800」を防止 | |
| 44 | + #include <dinput.h> | |
| 45 | + | |
| 46 | + #pragma comment(lib, "dinput8.lib") | |
| 47 | + #pragma comment(lib, "dxguid.lib") | |
| 48 | +#endif | |
| 49 | + | |
| 50 | +//! @brief 入力デバイスを管理するクラス | |
| 51 | +//! @details マウスやキーボードなどの入力デバイスを管理しています。 | |
| 52 | +//! @details 内部ではDirectInputを使用しています。 | |
| 53 | +class InputControl | |
| 54 | +{ | |
| 55 | + HWND hWnd; //!< ウインドウハンドル | |
| 56 | +#ifdef INPUT_DIRECTINPUT | |
| 57 | + LPDIRECTINPUT8 pDI; //!< DIRECTINPUT8のポインタ | |
| 58 | + LPDIRECTINPUTDEVICE8 pDIDevice; //!< DIRECTINPUTDEVICE8のポインタ・キーボード用 | |
| 59 | + LPDIRECTINPUTDEVICE8 pMouse; //!< DIRECTINPUTDEVICE8のポインタ・マウス用 | |
| 60 | +#endif | |
| 61 | + char keys[256]; //!< キー情報を格納する配列 | |
| 62 | + char keys_lt[256]; //!< (前回の)キー情報を格納する配列 | |
| 63 | + int mx; //!< マウスのX座標 | |
| 64 | + int my; //!< マウスのY座標 | |
| 65 | + POINT point_lt; //!< (前回の)マウス座標 | |
| 66 | + bool mbl; //!< マウスの左ボタン | |
| 67 | + bool mbr; //!< マウスの右ボタン | |
| 68 | + bool mbl_lt; //!< (前回の)マウスの左ボタン | |
| 69 | + bool mbr_lt; //!< (前回の)マウスの右ボタン | |
| 70 | + | |
| 71 | +public: | |
| 72 | + InputControl(); | |
| 73 | + ~InputControl(); | |
| 74 | + int InitD3Dinput(HWND in_hWnd); | |
| 75 | + void GetInputState(bool mousemode); | |
| 76 | + void MoveMouseCenter(); | |
| 77 | + bool CheckKeyNow(int id); | |
| 78 | + bool CheckKeyDown(int id); | |
| 79 | + bool CheckKeyUp(int id); | |
| 80 | + void GetMouseMovement(int *x, int *y); | |
| 81 | + bool CheckMouseButtonNowL(); | |
| 82 | + bool CheckMouseButtonDownL(); | |
| 83 | + bool CheckMouseButtonUpL(); | |
| 84 | + bool CheckMouseButtonNowR(); | |
| 85 | + bool CheckMouseButtonDownR(); | |
| 86 | + bool CheckMouseButtonUpR(); | |
| 87 | +}; | |
| 88 | + | |
| 89 | +int OriginalkeycodeToDinputdef(int code); | |
| 90 | +bool GetDoubleKeyCode(int id, int *CodeL, int *CodeR); | |
| 91 | +int GetEscKeycode(); | |
| 92 | +int GetHomeKeycode(); | |
| 93 | +int GetFunctionKeycode(int key); | |
| 94 | + | |
| 95 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,135 @@ | ||
| 1 | +//! @file objectmanager.h | |
| 2 | +//! @brief ObjectManagerクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef OBJECTMANAGER_H | |
| 33 | +#define OBJECTMANAGER_H | |
| 34 | + | |
| 35 | +#define MAX_HUMAN 96 //!< 最大人数 | |
| 36 | +#define MAX_WEAPON 200 //!< 武器の最大数 | |
| 37 | +#define MAX_SMALLOBJECT 40 //!< 小物の最大数 | |
| 38 | + | |
| 39 | +#define MAX_BULLET 128 //!< 銃弾の最大数 | |
| 40 | +#define MAX_GRENADE 32 //!< 手榴弾の最大数 | |
| 41 | +#define MAX_EFFECT 256 //!< エフェクトの最大数 | |
| 42 | + | |
| 43 | +#define WEAPONSHOT_HEIGHT (VIEW_HEIGHT) //!< 弾を発射する高さ | |
| 44 | + | |
| 45 | +#define TOTAL_WEAPON_AUTOBULLET 3 //!< 初期化時に自動的に補てんされる弾数(装弾数の何倍か) | |
| 46 | + | |
| 47 | +#define SMALLOBJECT_SCALE 0.13f //!< 小物当たり判定の倍率 | |
| 48 | + | |
| 49 | +#ifndef H_LAYERLEVEL | |
| 50 | + #define H_LAYERLEVEL 3 //!< Select include file. | |
| 51 | +#endif | |
| 52 | +#include "main.h" | |
| 53 | + | |
| 54 | +//! エフェクト描画計算用構造体 | |
| 55 | +struct effectdata{ | |
| 56 | + int id; //!< データ番号 | |
| 57 | + float dist; //!< 距離 | |
| 58 | +}; | |
| 59 | + | |
| 60 | +//! @brief オブジェクト管理クラス | |
| 61 | +//! @details 各オブジェクトの初期化・計算・描画などを行い管理します。 | |
| 62 | +class ObjectManager | |
| 63 | +{ | |
| 64 | + class human *HumanIndex; //!< 人オブジェクト | |
| 65 | + class weapon *WeaponIndex; //!< 武器オブジェクト | |
| 66 | + class smallobject *SmallObjectIndex; //!< 小物オブジェクト | |
| 67 | + class bullet *BulletIndex; //!< 弾オブジェクト | |
| 68 | + class grenade *GrenadeIndex; //!< 手榴弾オブジェクト | |
| 69 | + class effect *EffectIndex; //!< 手榴弾オブジェクト | |
| 70 | + | |
| 71 | + unsigned int framecnt; //!< フレーム数のカウント | |
| 72 | + | |
| 73 | + int *Human_ontarget; //!< 命中数 | |
| 74 | + int *Human_kill; //!< 倒した敵の数 | |
| 75 | + int *Human_headshot; //!< 敵の頭部に命中した数 | |
| 76 | + | |
| 77 | + int Player_HumanID; //!< プレイヤーが操作する人オブジェクトのID | |
| 78 | + | |
| 79 | + int AddHumanIndex_TextureID; //!< 前回読み込んだテクスチャID | |
| 80 | + | |
| 81 | + ParameterInfo *GameParamInfo; //!< ゲームの設定値 | |
| 82 | + D3DGraphics *d3dg; //!< 描画クラス | |
| 83 | + ResourceManager *Resource; //!< リソース管理 | |
| 84 | + BlockDataInterface *BlockData; //!< ブロックデータ管理クラス | |
| 85 | + PointDataInterface *PointData; //!< ポイントデータ管理クラス | |
| 86 | + Collision *CollD; //!< 当たり判定管理クラス | |
| 87 | + SoundManager *GameSound; //!< ゲーム効果音管理クラス | |
| 88 | + MIFInterface *MIFdata; //!< MIFコントロールクラス | |
| 89 | + | |
| 90 | + int AddHumanIndex(pointdata data, pointdata infodata); | |
| 91 | + int AddWeaponIndex(pointdata data); | |
| 92 | + int AddSmallObjectIndex(pointdata data); | |
| 93 | + void SetHumanBlood(float x, float y, float z); | |
| 94 | + bool CollideHuman(human *in_humanA, human *in_humanB); | |
| 95 | + bool CollideBullet(bullet *in_bullet); | |
| 96 | + void HitBulletMap(float x, float y, float z); | |
| 97 | + void HitBulletHuman(int HitHuman_id, int Hit_id, float x, float y, float z, float brx, int attacks, int humanid); | |
| 98 | + void HitBulletSmallObject(int HitSmallObject_id, float x, float y, float z, int attacks); | |
| 99 | + void PickupWeapon(human *in_human, weapon *in_weapon); | |
| 100 | + void CleanupPointDataToObject(); | |
| 101 | + int SortEffect(float camera_x, float camera_y, float camera_z, effectdata data[]); | |
| 102 | + | |
| 103 | +public: | |
| 104 | + ObjectManager(); | |
| 105 | + ~ObjectManager(); | |
| 106 | + void SetClass(ParameterInfo *in_GameParamInfo, D3DGraphics *in_d3dg, ResourceManager *in_Resource, BlockDataInterface *in_BlockData, PointDataInterface *in_PointData, Collision *in_CollD, SoundManager *in_GameSound, MIFInterface *in_MIFdata); | |
| 107 | + int AddHumanIndex(float px, float py, float pz, float rx, int CharacterID, int TeamID, int WeaponID[]); | |
| 108 | + int AddVisualWeaponIndex(int WeaponID, bool loadbullet); | |
| 109 | + void LoadPointData(); | |
| 110 | + human* GetHumanList(); | |
| 111 | + weapon* GetWeaponList(); | |
| 112 | + smallobject* GetSmallObjectList(); | |
| 113 | + bullet* GetBulletList(); | |
| 114 | + int GetPlayerID(); | |
| 115 | + void SetPlayerID(int id); | |
| 116 | + human* GeHumanObject(int id); | |
| 117 | + human* GetPlayerHumanObject(); | |
| 118 | + weapon* GeWeaponObject(int id); | |
| 119 | + bullet* GeBulletObject(int id); | |
| 120 | + bullet* GetNewBulletObject(); | |
| 121 | + grenade* GetNewGrenadeObject(); | |
| 122 | + human* SearchHuman(signed char p4); | |
| 123 | + smallobject* SearchSmallobject(signed char p4); | |
| 124 | + int ShotWeapon(human *MyHuman); | |
| 125 | + void ReloadWeapon(human *in_human); | |
| 126 | + bool CheckZombieAttack(human* MyHuman, human* EnemyHuman); | |
| 127 | + void HitZombieAttack(human* EnemyHuman); | |
| 128 | + int CheckGameOverorComplete(); | |
| 129 | + int Process(int cmdF5id, float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry); | |
| 130 | + bool GetHumanShotInfo(int id, int *ontarget, int *kill, int *headshot); | |
| 131 | + void Render(float camera_x, float camera_y, float camera_z, int HidePlayer); | |
| 132 | + void Cleanup(); | |
| 133 | +}; | |
| 134 | + | |
| 135 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,188 @@ | ||
| 1 | +//! @file window.cpp | |
| 2 | +//! @brief メインウィンドウの作成・制御 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "window.h" | |
| 33 | + | |
| 34 | +LRESULT WINAPI WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); | |
| 35 | + | |
| 36 | +//! メインウィンドウ作成 | |
| 37 | +//! @param hInstance インスタンス ハンドル | |
| 38 | +//! @param title ウィンドウタイトル | |
| 39 | +//! @param width ウィンドウの幅 | |
| 40 | +//! @param height ウィンドウの高さ | |
| 41 | +//! @param nCmdShow ウィンドウの表示状態 | |
| 42 | +//! @param fullscreen false:ウィンドウ表示 true:フルスクリーン用表示 | |
| 43 | +//! @return ウィンドウハンドル | |
| 44 | +HWND InitWindow(HINSTANCE hInstance, char* title, int width, int height, int nCmdShow, bool fullscreen) | |
| 45 | +{ | |
| 46 | + WNDCLASS wc; | |
| 47 | + //int x, y; | |
| 48 | + //int w, h; | |
| 49 | + RECT Rect; | |
| 50 | + DWORD dwStyle; | |
| 51 | + HWND hWnd; | |
| 52 | + | |
| 53 | + //ウィンドウクラスの登録 | |
| 54 | + wc.style = CS_HREDRAW | CS_VREDRAW; | |
| 55 | + wc.lpfnWndProc = WindowProc; | |
| 56 | + wc.cbClsExtra = 0; | |
| 57 | + wc.cbWndExtra = 0; | |
| 58 | + wc.hInstance = hInstance; | |
| 59 | + wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(MAINICON)); | |
| 60 | + wc.hCursor = NULL; | |
| 61 | + wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); | |
| 62 | + wc.lpszMenuName = NULL; | |
| 63 | + wc.lpszClassName = "MainWindow"; | |
| 64 | + if( !RegisterClass(&wc) ){ | |
| 65 | + return NULL; | |
| 66 | + } | |
| 67 | + | |
| 68 | + if( fullscreen == false ){ | |
| 69 | + dwStyle = WS_OVERLAPPED | WS_SYSMENU | WS_CAPTION; | |
| 70 | + } | |
| 71 | + else{ | |
| 72 | + dwStyle = WS_POPUP; | |
| 73 | + } | |
| 74 | + | |
| 75 | + //ウィンドウサイズを計算 | |
| 76 | + Rect.left = 0; | |
| 77 | + Rect.top = 0; | |
| 78 | + Rect.right = width; | |
| 79 | + Rect.bottom = height; | |
| 80 | + AdjustWindowRect(&Rect, dwStyle, FALSE); | |
| 81 | + width = Rect.right - Rect.left; | |
| 82 | + height = Rect.bottom - Rect.top; | |
| 83 | + | |
| 84 | + //ウィンドウ作成 | |
| 85 | + hWnd = CreateWindow( "MainWindow", title, dwStyle, 0, 0, width, height, NULL, NULL, hInstance, NULL ); | |
| 86 | + if( hWnd == NULL ){ | |
| 87 | + return NULL; | |
| 88 | + } | |
| 89 | + | |
| 90 | + //表示 | |
| 91 | + ShowWindow( hWnd, nCmdShow ); | |
| 92 | + | |
| 93 | + return hWnd; | |
| 94 | + | |
| 95 | +} | |
| 96 | + | |
| 97 | +//! メインウィンドウのウィンドウプロシージャ | |
| 98 | +LRESULT WINAPI WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) | |
| 99 | +{ | |
| 100 | + switch( msg ){ | |
| 101 | + case WM_DESTROY: | |
| 102 | + PostQuitMessage(0); | |
| 103 | + return 0; | |
| 104 | + } | |
| 105 | + return DefWindowProc(hWnd, msg, wParam, lParam); | |
| 106 | +} | |
| 107 | + | |
| 108 | +//! fps(Frames Per Second:フレームレート)計算 | |
| 109 | +//! @param getcnt fpsを取得する周期(フレーム単位) | |
| 110 | +//! @return fps数 | |
| 111 | +float GetFps(int getcnt) | |
| 112 | +{ | |
| 113 | + static unsigned int ptimeg = 0; | |
| 114 | + unsigned int nowtime; | |
| 115 | + static float pfps = 0.0f; | |
| 116 | + static int cnt = 0; | |
| 117 | + | |
| 118 | + if( cnt == 0 ){ | |
| 119 | + ptimeg = GetTimeMS(); | |
| 120 | + } | |
| 121 | + if( cnt == getcnt ){ | |
| 122 | + nowtime = GetTimeMS(); | |
| 123 | + pfps = 1000.0f / ((nowtime - ptimeg)/getcnt); | |
| 124 | + cnt = 0; | |
| 125 | + } | |
| 126 | + else{ | |
| 127 | + cnt += 1; | |
| 128 | + } | |
| 129 | + | |
| 130 | + return pfps; | |
| 131 | +} | |
| 132 | + | |
| 133 | +//! fps(Frames Per Second:フレームレート)調整 | |
| 134 | +//! @return 調整を実施:true 調整を実施せず:false | |
| 135 | +bool ControlFps() | |
| 136 | +{ | |
| 137 | + static unsigned int ptimec = 0; | |
| 138 | + unsigned int nowtime; | |
| 139 | + int waittime; | |
| 140 | + | |
| 141 | + nowtime = GetTimeMS(); | |
| 142 | + waittime = GAMEFRAMEMS - (nowtime - ptimec); | |
| 143 | + if( waittime > 0 ){ | |
| 144 | + Sleep(waittime); | |
| 145 | + ptimec = GetTimeMS(); | |
| 146 | + return true; | |
| 147 | + } | |
| 148 | + | |
| 149 | + ptimec = nowtime; | |
| 150 | + return false; | |
| 151 | +} | |
| 152 | + | |
| 153 | +//! ミリ秒単位を返す | |
| 154 | +//! @return ミリ秒 | |
| 155 | +unsigned int GetTimeMS() | |
| 156 | +{ | |
| 157 | + unsigned int time; | |
| 158 | + | |
| 159 | + timeBeginPeriod(1); | |
| 160 | + time = timeGetTime(); | |
| 161 | + timeEndPeriod(1); | |
| 162 | + | |
| 163 | + return time; | |
| 164 | +} | |
| 165 | + | |
| 166 | +//! 乱数を初期化 | |
| 167 | +void InitRand() | |
| 168 | +{ | |
| 169 | + srand(GetTimeMS()); | |
| 170 | +} | |
| 171 | + | |
| 172 | +//! ランダムな整数値を返す | |
| 173 | +//! @param num 範囲 | |
| 174 | +//! @return 0〜num-1 | |
| 175 | +int GetRand(int num) | |
| 176 | +{ | |
| 177 | + return rand()%num; | |
| 178 | + | |
| 179 | + //return rand() / (RAND_MAX/num); | |
| 180 | + | |
| 181 | + //本家XOPSのアルゴリズム? | |
| 182 | + //static int memory = GetTimeMS(); | |
| 183 | + //int x; | |
| 184 | + //memory = memory * 214013 + 2745024; | |
| 185 | + //x = memory >> 16; | |
| 186 | + //x = x & 0x00007FFF; | |
| 187 | + //return x%num; | |
| 188 | +} |
| @@ -0,0 +1,97 @@ | ||
| 1 | +//! @file config.h | |
| 2 | +//! @brief configクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef CONFING_H | |
| 33 | +#define CONFING_H | |
| 34 | + | |
| 35 | +#define TOTAL_ControlKey 18 //!< 合計操作キー数 | |
| 36 | +#define MAX_PLAYERNAME 21 //!< プレイヤー名の最大文字数 | |
| 37 | + | |
| 38 | +#ifndef H_LAYERLEVEL | |
| 39 | + #define H_LAYERLEVEL 1 //!< Select include file. | |
| 40 | +#endif | |
| 41 | +#include "main.h" | |
| 42 | + | |
| 43 | +//! GetKeycode()用 定数 | |
| 44 | +enum ControlKey { | |
| 45 | + KEY_TURNUP = 0, | |
| 46 | + KEY_TURNDOWN, | |
| 47 | + KEY_TURNLEFT, | |
| 48 | + KEY_TURNRIGHT, | |
| 49 | + KEY_MOVEFORWARD, | |
| 50 | + KEY_MOVEBACKWARD, | |
| 51 | + KEY_MOVELEFT, | |
| 52 | + KEY_MOVERIGHT, | |
| 53 | + KEY_WALK, | |
| 54 | + KEY_JUMP, | |
| 55 | + KEY_RELOAD, | |
| 56 | + KEY_DROPWEAPON, | |
| 57 | + KEY_ZOOM, | |
| 58 | + KEY_ShotMODE, | |
| 59 | + KEY_SWITCHWEAPON, | |
| 60 | + KEY_WEAPON1, | |
| 61 | + KEY_WEAPON2, | |
| 62 | + KEY_Shot | |
| 63 | +}; | |
| 64 | + | |
| 65 | +//! @brief 設定ファイルを読み込むクラス | |
| 66 | +//! @details ファイルの参照と値の管理を行います。 | |
| 67 | +//! @details 参考資料:「みかん箱」http://mikan.the-ninja.jp/ ⇒ 技術資料 ⇒ config.datファイル解析資料 | |
| 68 | +class Config | |
| 69 | +{ | |
| 70 | + int Keycode[TOTAL_ControlKey]; //!< オリジナルキーコード | |
| 71 | + int MouseSensitivity; //!< マウス感度 | |
| 72 | + bool FullscreenFlag; //!< フルスクリーン有効 | |
| 73 | + bool SoundFlag; //!< 効果音有効 | |
| 74 | + bool BloodFlag; //!< 出血有効 | |
| 75 | + int Brightness; //!< 画面の明るさ | |
| 76 | + bool InvertMouseFlag; //!< マウス反転 | |
| 77 | + bool FrameskipFlag; //!< フレームスキップ | |
| 78 | + bool AnotherGunsightFlag; //!< 別の標準を使用 | |
| 79 | + char PlayerName[MAX_PLAYERNAME]; //!< プレイヤー名 | |
| 80 | + | |
| 81 | +public: | |
| 82 | + Config(); | |
| 83 | + ~Config(); | |
| 84 | + int LoadFile(char *fname); | |
| 85 | + int GetKeycode(int id); | |
| 86 | + int GetMouseSensitivity(); | |
| 87 | + bool GetFullscreenFlag(); | |
| 88 | + bool GetSoundFlag(); | |
| 89 | + bool GetBloodFlag(); | |
| 90 | + int GetBrightness(); | |
| 91 | + bool GetInvertMouseFlag(); | |
| 92 | + bool GetFrameskipFlag(); | |
| 93 | + bool GetAnotherGunsightFlag(); | |
| 94 | + int GetPlayerName(char *out_str); | |
| 95 | +}; | |
| 96 | + | |
| 97 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,79 @@ | ||
| 1 | +//! @file statemachine.h | |
| 2 | +//! @brief StateMachineクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef STATEMACHINE_H | |
| 33 | +#define STATEMACHINE_H | |
| 34 | + | |
| 35 | +#ifndef H_LAYERLEVEL | |
| 36 | + #define H_LAYERLEVEL 3 //!< Select include file. | |
| 37 | +#endif | |
| 38 | +#include "main.h" | |
| 39 | + | |
| 40 | +//! 状態を表す定数 | |
| 41 | +enum State { | |
| 42 | + STATE_NULL = 0, //!< [エラー]無効な状態 | |
| 43 | + STATE_CREATE_OPENING, //!< オープニング画面 初期化・準備 | |
| 44 | + STATE_NOW_OPENING, //!< オープニング画面 実行中 | |
| 45 | + STATE_DESTROY_OPENING, //!< オープニング画面 終了・廃棄 | |
| 46 | + STATE_CREATE_MENU, //!< メニュー画面 初期化・準備 | |
| 47 | + STATE_NOW_MENU, //!< メニュー画面 実行中 | |
| 48 | + STATE_DESTROY_MENU, //!< メニュー画面 終了・廃棄 | |
| 49 | + STATE_CREATE_BRIEFING, //!< ブリーフィング画面 初期化・準備 | |
| 50 | + STATE_NOW_BRIEFING, //!< ブリーフィング画面 実行中 | |
| 51 | + STATE_DESTROY_BRIEFING, //!< ブリーフィング画面 終了・廃棄 | |
| 52 | + STATE_CREATE_MAINGAME, //!< メイン画面 初期化・準備 | |
| 53 | + STATE_NOW_MAINGAME, //!< メイン画面 実行中 | |
| 54 | + STATE_DESTROY_MAINGAME, //!< メイン画面 終了・廃棄 | |
| 55 | + STATE_CREATE_RESULT, //!< 結果表示画面 初期化・準備 | |
| 56 | + STATE_NOW_RESULT, //!< 結果表示画面 実行中 | |
| 57 | + STATE_DESTROY_RESULT, //!< 結果表示画面 終了・廃棄 | |
| 58 | + STATE_EXIT //!< ゲーム終了 | |
| 59 | +}; | |
| 60 | + | |
| 61 | +//! @brief 状態遷移クラス | |
| 62 | +//! @details ゲーム全体の画面遷移に関わる管理を行います。 | |
| 63 | +class StateMachine | |
| 64 | +{ | |
| 65 | + int NowState; //!< 現在のステート | |
| 66 | + bool back; //!< ESCキーが押された | |
| 67 | + bool f12; //!< F12キーが押された | |
| 68 | + | |
| 69 | +public: | |
| 70 | + StateMachine(); | |
| 71 | + ~StateMachine(); | |
| 72 | + void NextState(); | |
| 73 | + void PushMouseButton(); | |
| 74 | + void PushBackSpaceKey(); | |
| 75 | + void PushF12Key(); | |
| 76 | + int GetState(); | |
| 77 | +}; | |
| 78 | + | |
| 79 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,353 @@ | ||
| 1 | +//! @file object.h | |
| 2 | +//! @brief objectクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef OBJECT_H | |
| 33 | +#define OBJECT_H | |
| 34 | + | |
| 35 | +// 注意:速度変更時は、当たり判定系の定数も要確認 | |
| 36 | +#define HUMAN_PROGRESSRUN_SPEED 1.40f //!< 人の前進(走り)速度 | |
| 37 | +#define HUMAN_SIDEWAYSRUN_SPEED 1.00f //!< 人の横走り速度 | |
| 38 | +#define HUMAN_REGRESSRUN_SPEED 0.75f //!< 人の後退速度 | |
| 39 | +//! 人が斜め前に進む速度 | |
| 40 | +#define HUMAN_PROGRESSRUN_SIDEWAYSRUN_SPEED ((HUMAN_PROGRESSRUN_SPEED + HUMAN_SIDEWAYSRUN_SPEED) / 2) | |
| 41 | +//! 人が斜め後ろに進む速度 | |
| 42 | +#define HUMAN_REGRESSRUN_SIDEWAYSRUN_SPEED (HUMAN_REGRESSRUN_SPEED) | |
| 43 | +#define HUMAN_PROGRESSWALK_SPEED 0.70f //!< 人が歩く速度 | |
| 44 | + | |
| 45 | +#define HUMAN_JUMP_SPEED (2.2f + (HUMAN_DAMAGE_SPEED)) //!< ジャンプする速度 | |
| 46 | + | |
| 47 | +#define HUMAN_HEIGTH 20.0f //!< 人の高さ | |
| 48 | +#define HUMAN_DAMAGE_HEAD 2.0f //!< 弾が 頭 に当たった場合のダメージ倍率 | |
| 49 | +#define HUMAN_DAMAGE_UP 1.0f //!< 弾が 上半身 に当たった場合のダメージ倍率 | |
| 50 | +#define HUMAN_DAMAGE_LEG 0.7f //!< 弾が 下半身 に当たった場合のダメージ倍率 | |
| 51 | +#define HUMAN_DAMAGE_ZOMBIEU 15 //!< ゾンビの攻撃を受けた場合の最低ダメージ | |
| 52 | +#define HUMAN_DAMAGE_ZOMBIEA 5 //!< ゾンビの攻撃を受けた場合の追加ダメージ量 | |
| 53 | +#define HUMAN_DAMAGE_SPEED (0.066f + 0.132f) //!< 落下量 | |
| 54 | +#define HUMAN_DAMAGE_MINSPEED -3.8f //!< 落下によりダメージを受けない速度 | |
| 55 | +#define HUMAN_DAMAGE_MAXSPEED -7.0f //!< 最大落下速度 | |
| 56 | +#define HUMAN_DAMAGE_MAXFALL 120 //!< 落下による最大ダメージ | |
| 57 | +#define MAX_DAMAGE_GRENADE_DISTANCE 80.0f //!< 手榴弾によりダメージを受ける最大距離 | |
| 58 | +#define HUMAN_DAMAGE_GRENADE_HEAD 100 //!< 手榴弾による 頭 への最大ダメージ | |
| 59 | +#define HUMAN_DAMAGE_GRENADE_LEG 80 //!< 手榴弾による 足 への最大ダメージ | |
| 60 | +#define SMALLOBJECT_DAMAGE_GRENADE 80 //!< 手榴弾による 小物 への最大ダメージ | |
| 61 | + | |
| 62 | +#define WEAPONERRORRANGE_SCALE 0.25f //!< 武器の反動角度の倍率(×0.25 = ÷4) | |
| 63 | + | |
| 64 | +#define ARMRAD_NOWEAPON ((float)M_PI/2*-1 + (float)M_PI/9) //!< 手ぶら時の腕の表示角度 | |
| 65 | +#define ARMRAD_RELOADWEAPON ((float)M_PI/2*-1 + (float)M_PI/3) //!< リロード時の腕の表示角度 | |
| 66 | + | |
| 67 | +#define HUMAN_MAPCOLLISION_R 5.0f //!< 人とマップの当たり判定 半径 | |
| 68 | +#define HUMAN_MAPCOLLISION_HEIGTH 10.2f //!< 人とマップの当たり判定 高さ(注:腰程度) | |
| 69 | +#define HUMAN_MAPCOLLISION_SLOPEANGLE ((float)M_PI/18*5) //!< 人とマップの当たり判定 登れない斜面の角度 | |
| 70 | +#define HUMAN_MAPCOLLISION_SLOPEFORCE 1.4f //!< 人とマップの当たり判定 登れない斜面が人を押し出す力 | |
| 71 | +#define HUMAN_DEADLINE -100.0f //!< 人が死亡するY座標(デッドライン) | |
| 72 | + | |
| 73 | +#define BULLET_SPEEDSCALE 3 //!< 弾速の倍率 | |
| 74 | +#define BULLET_DESTROYFRAME 40 //!< 弾の消滅フレーム数 | |
| 75 | +#define GRENADE_DESTROYFRAME 100 //!< 手榴弾の爆発フレーム数 | |
| 76 | + | |
| 77 | +#ifndef H_LAYERLEVEL | |
| 78 | + #define H_LAYERLEVEL 2 //!< Select include file. | |
| 79 | +#endif | |
| 80 | +#include "main.h" | |
| 81 | + | |
| 82 | +#define HUMAN_DEADBODY_COLLISION //!< @brief 人が倒れる際にマップと当たり判定を実施するか @details 定数宣言有効:当たり判定を実施 定数宣言無効(コメント化):そのまま倒すだけ | |
| 83 | + | |
| 84 | +//! @brief オブジェクト管理クラス(基底クラス) | |
| 85 | +//! @details 3Dで座標管理や描画を行うオブジェクト全般を管理するクラス群の基底クラスです。 | |
| 86 | +class object | |
| 87 | +{ | |
| 88 | +protected: | |
| 89 | + class ParameterInfo *Param; //!< 設定値を管理するクラスへのポインタ | |
| 90 | + float pos_x; //!< X座標 | |
| 91 | + float pos_y; //!< Y座標 | |
| 92 | + float pos_z; //!< Z座標 | |
| 93 | + float rotation_x; //!< 回転角度 | |
| 94 | + float model_size; //!< 表示サイズ | |
| 95 | + int id_parameter; //!< データの種類 | |
| 96 | + int id_model; //!< モデル認識番号 | |
| 97 | + int id_texture; //!< テクスチャ認識番号 | |
| 98 | + bool RenderFlag; //!< 表示フラグ | |
| 99 | + | |
| 100 | +public: | |
| 101 | + object(class ParameterInfo *in_Param = NULL, float x = 0.0f, float y = 0.0f, float z = 0.0f, float rx = 0.0f, float size = 1.0f, bool flag = true); | |
| 102 | + ~object(); | |
| 103 | + virtual void SetParameterInfoClass(class ParameterInfo *in_Param); | |
| 104 | + virtual void SetPosData(float x, float y, float z, float rx); | |
| 105 | + virtual void GetPosData(float *x, float *y, float *z, float *rx); | |
| 106 | + virtual void SetDrawFlag(bool flag); | |
| 107 | + virtual bool GetDrawFlag(); | |
| 108 | + virtual void SetModel(int id, float size); | |
| 109 | + virtual void SetTexture(int id); | |
| 110 | + virtual int RunFrame(); | |
| 111 | + virtual void Render(class D3DGraphics *d3dg); | |
| 112 | +}; | |
| 113 | + | |
| 114 | +//! @brief 人管理クラス | |
| 115 | +class human : public object | |
| 116 | +{ | |
| 117 | +protected: | |
| 118 | + int point_dataid; //!< ポイントのデータ番号 | |
| 119 | + signed char point_p4; //!< ポイントの認識番号 | |
| 120 | + int teamid; //!< チーム番号 | |
| 121 | + float move_x; //!< X軸速度 | |
| 122 | + float move_y; //!< Y軸(落下)速度 | |
| 123 | + float move_z; //!< Z軸速度 | |
| 124 | + bool move_y_flag; //!< Y軸移動フラグ | |
| 125 | + float rotation_y; //!< 全体の回転角度 | |
| 126 | + float armrotation_y; //!< 腕の回転角度 | |
| 127 | + float reaction_y; //!< 腕を上げ下げする角度 | |
| 128 | + float upmodel_size; //!< 上半身表示サイズ | |
| 129 | + float armmodel_size; //!< 腕表示サイズ | |
| 130 | + float legmodel_size; //!< 足表示サイズ | |
| 131 | + class weapon *weapon[TOTAL_HAVEWEAPON]; //!< 武器 | |
| 132 | + int selectweapon; //!< 武器A/Bの選択 | |
| 133 | + int selectweaponcnt; //!< 武器の切り替えカウント | |
| 134 | + int hp; //!< 体力 | |
| 135 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 136 | + int deadstate; //!< 死体になっているか | |
| 137 | +#endif | |
| 138 | + int id_upmodel; //!< 上半身 | |
| 139 | + int id_armmodel[TOTAL_ARMMODE]; //!< 腕 | |
| 140 | + int id_legmodel; //!< 足(静止) | |
| 141 | + int id_walkmodel[TOTAL_WALKMODE]; //!< 足(歩く) | |
| 142 | + int id_runmodel[TOTAL_RUNMODE]; //!< 足(走る) | |
| 143 | + float addposorder_x; //!< 要求するX軸移動量 | |
| 144 | + float addposorder_z; //!< 要求するZ軸移動量 | |
| 145 | + float move_rx; //!< 移動角度 | |
| 146 | + int MoveFlag; //!< 移動方向を表すフラグ | |
| 147 | + int MoveFlag_lt; //!< (前回の)移動方向を表すフラグ | |
| 148 | + int scopemode; //!< スコープ使用モード | |
| 149 | + bool HitFlag; //!< 被弾を表すフラグ | |
| 150 | + int legmode; //!< 足の状態 | |
| 151 | + int walkcnt; //!< 歩くモーションのカウント | |
| 152 | + int runcnt; //!< 走るモーションのカウント | |
| 153 | + float totalmove; //!< 合計移動量 | |
| 154 | + int StateGunsightErrorRange; //!< 照準の状態誤差 | |
| 155 | + int ReactionGunsightErrorRange; //!< 照準の反動誤差 | |
| 156 | + | |
| 157 | + void GunsightErrorRange(); | |
| 158 | + int CheckAndProcessDead(class Collision *CollD); | |
| 159 | + void ControlProcess(); | |
| 160 | + bool CheckBlockAngle(class BlockDataInterface *inblockdata, int bid, int fid, float vx, float vz); | |
| 161 | + bool MapCollisionDetection(class Collision *CollD, class BlockDataInterface *inblockdata, float *vx, float *vz, float speed, float *FallDist); | |
| 162 | + | |
| 163 | +public: | |
| 164 | + human(class ParameterInfo *in_Param = NULL, float x = 0.0f, float y = 0.0f, float z = 0.0f, float rx = 0.0f, int id_param = -1, int dataid = 0, signed char p4 = 0, int team = 0, bool flag = false); | |
| 165 | + ~human(); | |
| 166 | + virtual void SetParamData(int id_param, int dataid, signed char p4, int team, bool init); | |
| 167 | + virtual void GetParamData(int *id_param, int *dataid, signed char *p4, int *team); | |
| 168 | + virtual void GetMovePos(float *x, float *y, float *z); | |
| 169 | + virtual void SetModel(int upmodel, int armmodel[], int legmodel, int walkmodel[], int runmodel[]); | |
| 170 | + virtual int GetHP(); | |
| 171 | + virtual bool GetDeadFlag(); | |
| 172 | + virtual void SetTeamID(int id); | |
| 173 | + virtual void SetWeapon(class weapon *in_weapon[]); | |
| 174 | + virtual int PickupWeapon(class weapon *in_weapon); | |
| 175 | + virtual void ChangeWeapon(int id = -1); | |
| 176 | + virtual int GetChangeWeaponCnt(); | |
| 177 | + virtual void GetWeapon(int *out_selectweapon, class weapon *out_weapon[]); | |
| 178 | + virtual int GetMainWeaponTypeNO(); | |
| 179 | + virtual bool GetWeaponBlazingmode(); | |
| 180 | + virtual bool ShotWeapon(int *weapon_paramid, int *GunsightErrorRange); | |
| 181 | + virtual bool ReloadWeapon(); | |
| 182 | + virtual bool DumpWeapon(); | |
| 183 | + virtual int ChangeShotMode(); | |
| 184 | + virtual void SetMoveForward(); | |
| 185 | + virtual void SetMoveBack(); | |
| 186 | + virtual void SetMoveLeft(); | |
| 187 | + virtual void SetMoveRight(); | |
| 188 | + virtual void SetMoveWalk(); | |
| 189 | + virtual int GetMovemode(bool nowdata); | |
| 190 | + virtual bool SetEnableScope(); | |
| 191 | + virtual void SetDisableScope(); | |
| 192 | + virtual int GetScopeMode(); | |
| 193 | + virtual void GetRxRy(float *rx, float *ry); | |
| 194 | + virtual void SetRxRy(float rx, float ry); | |
| 195 | + virtual int Jump(); | |
| 196 | + virtual void AddPosOrder(float rx, float speed); | |
| 197 | + virtual void HitBulletHead(int attacks); | |
| 198 | + virtual void HitBulletUp(int attacks); | |
| 199 | + virtual void HitBulletLeg(int attacks); | |
| 200 | + virtual void HitZombieAttack(); | |
| 201 | + virtual int GrenadeExplosion(class Collision *CollD, class grenade *tGrenade); | |
| 202 | + virtual bool CheckHit(); | |
| 203 | + virtual float GetTotalMove(); | |
| 204 | + virtual int RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata, bool F5mode); | |
| 205 | + virtual int GetGunsightErrorRange(); | |
| 206 | + virtual void Render(class D3DGraphics *d3dg, class ResourceManager *Resource, bool DrawArm); | |
| 207 | +}; | |
| 208 | + | |
| 209 | +//! @brief 武器管理クラス | |
| 210 | +class weapon : public object | |
| 211 | +{ | |
| 212 | +protected: | |
| 213 | + float move_x; //!< X軸移動量 | |
| 214 | + float move_y; //!< Y軸移動量 | |
| 215 | + float move_z; //!< Z軸移動量 | |
| 216 | + bool usingflag; //!< 使用中を表すフラグ | |
| 217 | + int bullets; //!< 合計弾数 | |
| 218 | + int Loadbullets; //!< 装弾数 | |
| 219 | + int shotcnt; //!< 連射カウント | |
| 220 | + int reloadcnt; //!< リロードカウント | |
| 221 | + bool motionflag; //!< 座標移動中を表すフラグ | |
| 222 | + | |
| 223 | +public: | |
| 224 | + weapon(class ParameterInfo *in_Param = NULL, float x = 0.0f, float y = 0.0f, float z = 0.0f, float rx = 0.0f, int id_param = 0, int nbs = 0, bool flag = false); | |
| 225 | + ~weapon(); | |
| 226 | + virtual void SetPosData(float x, float y, float z, float rx); | |
| 227 | + virtual void SetParamData(int id_param, int lnbs, int nbs, bool init); | |
| 228 | + virtual void GetParamData(int *id_param, int *lnbs, int *nbs); | |
| 229 | + virtual bool GetUsingFlag(); | |
| 230 | + virtual int Pickup(); | |
| 231 | + virtual void Dropoff(float x, float y, float z, float rx, float speed); | |
| 232 | + virtual int Shot(); | |
| 233 | + virtual int StartReload(); | |
| 234 | + virtual int RunReload(); | |
| 235 | + virtual int GetReloadCnt(); | |
| 236 | + virtual bool ResetWeaponParam(class ResourceManager *Resource, int id_param, int lnbs, int nbs); | |
| 237 | + virtual int RunFrame(class Collision *CollD); | |
| 238 | + virtual void Render(class D3DGraphics *d3dg); | |
| 239 | +}; | |
| 240 | + | |
| 241 | +//! @brief 小物管理クラス | |
| 242 | +class smallobject : public object | |
| 243 | +{ | |
| 244 | +protected: | |
| 245 | + class MIFInterface *MIFdata; //!< 設定値を管理するクラスへのポインタ | |
| 246 | + float rotation_y; //!< 回転角度 | |
| 247 | + signed char point_p4; //!< ポイントの認識番号 | |
| 248 | + int hp; //!< 体力 | |
| 249 | + float jump_rx; //!< 飛ばす横軸角度 | |
| 250 | + float move_rx; //!< 飛ばす横軸移動量 | |
| 251 | + float add_rx; //!< 飛ばす横軸回転量 | |
| 252 | + float add_ry; //!< 飛ばす縦軸回転量 | |
| 253 | + int jump_cnt; //!< 飛ばす上昇カウント | |
| 254 | + | |
| 255 | +public: | |
| 256 | + smallobject(class ParameterInfo *in_Param = NULL, class MIFInterface *in_MIFdata = NULL, float x = 0.0f, float y = 0.0f, float z = 0.0f, float rx = 0.0f, int id_param = 0, signed char p4 = 0, bool flag = false); | |
| 257 | + ~smallobject(); | |
| 258 | + virtual void SetMIFInterfaceClass(class MIFInterface *in_MIFdata); | |
| 259 | + virtual void SetParamData(int id_param, signed char p4, bool init); | |
| 260 | + virtual void GetParamData(int *id_param, signed char *p4); | |
| 261 | + virtual int GetHP(); | |
| 262 | + virtual float CollisionMap(class Collision *CollD); | |
| 263 | + virtual void HitBullet(int attacks); | |
| 264 | + virtual int GrenadeExplosion(class Collision *CollD, class grenade *tGrenade); | |
| 265 | + virtual void Destruction(); | |
| 266 | + virtual int RunFrame(); | |
| 267 | + virtual void Render(D3DGraphics *d3dg); | |
| 268 | +}; | |
| 269 | + | |
| 270 | +//! @brief 弾丸管理クラス | |
| 271 | +class bullet : public object | |
| 272 | +{ | |
| 273 | +protected: | |
| 274 | + float rotation_y; //!< 回転角度 | |
| 275 | + int attacks; //!< 攻撃力 | |
| 276 | + int penetration; //!< 貫通力 | |
| 277 | + int speed; //!< 弾速 | |
| 278 | + int teamid; //!< チーム番号 | |
| 279 | + int humanid; //!< 人のデータ番号 | |
| 280 | + int cnt; //!< カウント | |
| 281 | + | |
| 282 | +public: | |
| 283 | + bullet(int modelid = -1, int textureid = -1); | |
| 284 | + ~bullet(); | |
| 285 | + virtual void SetPosData(float x, float y, float z, float rx, float ry); | |
| 286 | + virtual void SetParamData(int _attacks, int _penetration, int _speed, int _teamid, int _humanid, bool init); | |
| 287 | + virtual void GetPosData(float *x, float *y, float *z, float *rx, float *ry); | |
| 288 | + virtual void GetParamData(int *_attacks, int *_penetration, int *_speed, int *_teamid, int *_humanid); | |
| 289 | + virtual int RunFrame(); | |
| 290 | + virtual void Render(class D3DGraphics *d3dg); | |
| 291 | +}; | |
| 292 | + | |
| 293 | +//! @brief 手榴弾管理クラス | |
| 294 | +class grenade : public bullet | |
| 295 | +{ | |
| 296 | + float move_x; //!< X軸移動量 | |
| 297 | + float move_y; //!< Y軸移動量 | |
| 298 | + float move_z; //!< Y軸移動量 | |
| 299 | + | |
| 300 | +public: | |
| 301 | + grenade(int modelid = -1, int textureid = -1); | |
| 302 | + ~grenade(); | |
| 303 | + void SetParamData(float speed, int _humanid, bool init); | |
| 304 | + int RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata); | |
| 305 | + virtual void Render(D3DGraphics *d3dg); | |
| 306 | +}; | |
| 307 | + | |
| 308 | +//! @brief エフェクト管理クラス | |
| 309 | +class effect : public object | |
| 310 | +{ | |
| 311 | +protected: | |
| 312 | + int type; //!< 種類 | |
| 313 | + float camera_rx; //!< カメラ角度 | |
| 314 | + float camera_ry; //!< カメラ角度 | |
| 315 | + float rotation_texture; //!< 回転角度 | |
| 316 | + float alpha; //!< 透明度 | |
| 317 | + int cnt; //!< カウント | |
| 318 | + int setcnt; //!< 設定されたカウント | |
| 319 | + | |
| 320 | +public: | |
| 321 | + effect(float x = 0.0f, float y = 0.0f, float z = 0.0f, float size = 1.0f, float rotation = 0.0f, int count = 0, int texture = 0, int settype = 0); | |
| 322 | + ~effect(); | |
| 323 | + virtual void SetParamData(float size, float rotation, int count, int texture, int settype, bool init); | |
| 324 | + virtual int RunFrame(float in_camera_rx, float in_camera_ry); | |
| 325 | + virtual void Render(class D3DGraphics *d3dg); | |
| 326 | +}; | |
| 327 | + | |
| 328 | +//! 人の足の状態を示す定数 | |
| 329 | +enum Human_LegState { | |
| 330 | + LEG_STOP = 0, | |
| 331 | + LEG_WALK, | |
| 332 | + LEG_RUN | |
| 333 | +}; | |
| 334 | + | |
| 335 | +//! 人の移動操作を表すフラグ | |
| 336 | +enum Human_MoveFlag { | |
| 337 | + MOVEFLAG_FORWARD = 0x01, | |
| 338 | + MOVEFLAG_BACK = 0x02, | |
| 339 | + MOVEFLAG_LEFT = 0x04, | |
| 340 | + MOVEFLAG_RIGHT = 0x08, | |
| 341 | + MOVEFLAG_WALK = 0x10, | |
| 342 | +}; | |
| 343 | + | |
| 344 | +//! エフェクトの種類を表す定数 | |
| 345 | +enum Effect_Type { | |
| 346 | + EFFECT_NORMAL = 0x00, //!< ノーマル | |
| 347 | + EFFECT_DISAPPEAR = 0x01, //!< 消す | |
| 348 | + EFFECT_MAGNIFY = 0x02, //!< 拡大 | |
| 349 | + EFFECT_ROTATION = 0x04, //!< 回転 | |
| 350 | + EFFECT_FALL = 0x08 //!< 落下 | |
| 351 | +}; | |
| 352 | + | |
| 353 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,202 @@ | ||
| 1 | +//! @file datafile.h | |
| 2 | +//! @brief データ管理クラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef DATAFILE_H | |
| 33 | +#define DATAFILE_H | |
| 34 | + | |
| 35 | +#define MAX_BLOCKS 160 //!< 最大ブロック数 | |
| 36 | +#define TOTAL_BLOCKTEXTURE 10 //!< 合計テクスチャ数 | |
| 37 | + | |
| 38 | +#define MAX_POINTS 200 //!< 最大ポイント数 | |
| 39 | + | |
| 40 | +#define MAX_POINTMESSAGES 16 //!< .msgファイルの最大メッセージ数 | |
| 41 | +#define MAX_POINTMESSAGEBYTE (71+2) //!< .msgファイル 1行あたりの最大バイト数 | |
| 42 | + | |
| 43 | +#define LIGHT_RX ((float)M_PI/18*19) //!< ライトの横軸角度(ブロックの陰影計算用) | |
| 44 | +#define LIGHT_RY ((float)M_PI/18*12) //!< ライトの縦軸角度(ブロックの陰影計算用) | |
| 45 | + | |
| 46 | +#ifndef H_LAYERLEVEL | |
| 47 | + #define H_LAYERLEVEL 1 //!< Select include file. | |
| 48 | +#endif | |
| 49 | +#include "main.h" | |
| 50 | + | |
| 51 | +//! ブロックデータ用構造体 (blockdata構造体で使用) | |
| 52 | +struct b_material{ | |
| 53 | + int textureID; //!< textureID | |
| 54 | + float u[4]; //!< textureUV-U | |
| 55 | + float v[4]; //!< textureUV-V | |
| 56 | + float vx; //!< normal vector | |
| 57 | + float vy; //!< normal vector | |
| 58 | + float vz; //!< normal vector | |
| 59 | + float shadow; //!< shadow | |
| 60 | +}; | |
| 61 | +//! ブロックデータ用構造体 | |
| 62 | +struct blockdata{ | |
| 63 | + int id; //!< DataID | |
| 64 | + float x[8]; //!< Position | |
| 65 | + float y[8]; //!< Position | |
| 66 | + float z[8]; //!< Position | |
| 67 | + b_material material[6]; //!< Material data | |
| 68 | +}; | |
| 69 | + | |
| 70 | +//! ポイントデータ用構造体 | |
| 71 | +struct pointdata{ | |
| 72 | + int id; //!< DataID | |
| 73 | + float x; //!< Position | |
| 74 | + float y; //!< Position | |
| 75 | + float z; //!< Position | |
| 76 | + float r; //!< Rotation | |
| 77 | + signed char p1; //!< Param | |
| 78 | + signed char p2; //!< Param | |
| 79 | + signed char p3; //!< Param | |
| 80 | + signed char p4; //!< Param | |
| 81 | +}; | |
| 82 | + | |
| 83 | +//! @brief データを管理するクラス(基底クラス) | |
| 84 | +//! @details ゲームのデータを、ファイルから読み込み処理するクラス群の基底クラスです。 | |
| 85 | +class DataInterface | |
| 86 | +{ | |
| 87 | +protected: | |
| 88 | + int datas; //!< データ数 | |
| 89 | + | |
| 90 | +public: | |
| 91 | + DataInterface(); | |
| 92 | + ~DataInterface(); | |
| 93 | + virtual int LoadFiledata(char *fname); | |
| 94 | + virtual int GetTotaldatas(); | |
| 95 | + virtual int Getdata(void *out_data, int id); | |
| 96 | +}; | |
| 97 | + | |
| 98 | +//! @brief ブロックデータを管理するクラス | |
| 99 | +//! @details マップデータとして使う、ブロックデータファイルを管理します。 | |
| 100 | +//! @details ファイルの読み込みのほか、マップへの影(各面の明るさ表現)も計算します。 | |
| 101 | +class BlockDataInterface : public DataInterface | |
| 102 | +{ | |
| 103 | + blockdata *data; //!< ブロックデータを表す構造体 | |
| 104 | + char texture[TOTAL_BLOCKTEXTURE][_MAX_PATH]; //!< テクスチャ名 | |
| 105 | + | |
| 106 | +public: | |
| 107 | + BlockDataInterface(); | |
| 108 | + ~BlockDataInterface(); | |
| 109 | + int LoadFiledata(char *fname); | |
| 110 | + void CalculationBlockdata(bool screen); | |
| 111 | + int GetTexture(char *fname, int id); | |
| 112 | + int Getdata(blockdata *out_data, int id); | |
| 113 | +}; | |
| 114 | + | |
| 115 | +bool blockdataface(int faceID, int* vID, int* uvID); | |
| 116 | + | |
| 117 | +//! @brief ポイントデータを管理するクラス | |
| 118 | +//! @details ミッションデータとして使う、ポイントデータファイルを管理します。 | |
| 119 | +//! @details ファイルの読み込みのほか、ポイントの検索機能もあります。 | |
| 120 | +class PointDataInterface : public DataInterface | |
| 121 | +{ | |
| 122 | + pointdata *data; //!< ブロックデータを表す構造体 | |
| 123 | + char *text[MAX_POINTMESSAGES]; //!< イベントメッセージ | |
| 124 | + | |
| 125 | +public: | |
| 126 | + PointDataInterface(); | |
| 127 | + ~PointDataInterface(); | |
| 128 | + int LoadFiledata(char *fname); | |
| 129 | + int Getdata(pointdata *out_data, int id); | |
| 130 | + int SetParam(int id, signed char p1, signed char p2, signed char p3, signed char p4); | |
| 131 | + int GetMessageText(char *str, int id); | |
| 132 | + int SearchPointdata(int* id, unsigned char pmask, signed char p1, signed char p2, signed char p3, signed char p4, int offset = 0); | |
| 133 | + int SearchPointdata(pointdata *out_data, unsigned char pmask, signed char p1, signed char p2, signed char p3, signed char p4, int offset = 0); | |
| 134 | +}; | |
| 135 | + | |
| 136 | +//! @brief MIFを管理するクラス | |
| 137 | +//! @details MIF(MISSION INFORMATION FILE)を管理します。 | |
| 138 | +//! @details 標準ミッションのブリーフィングファイル(.txt)にも対応しています。 | |
| 139 | +class MIFInterface : public DataInterface | |
| 140 | +{ | |
| 141 | + bool mif; //!< ファイル形式が .mif | |
| 142 | + char mission_name[24]; //!< ミッション識別名 | |
| 143 | + char mission_fullname[64]; //!< ミッション正式名称 | |
| 144 | + char blockfile_path[_MAX_PATH]; //!< ブロックデータファイル | |
| 145 | + char pointfile_path[_MAX_PATH]; //!< ポイントデータファイル | |
| 146 | + int skynumber; //!< 背景空のID (なし:0) | |
| 147 | + char picturefileA_path[_MAX_PATH]; //!< ブリーフィング画像A | |
| 148 | + char picturefileB_path[_MAX_PATH]; //!< ブリーフィング画像B(追加分) | |
| 149 | + char addsmallobject_path[_MAX_PATH]; //!< 追加小物情報ファイルへのパス | |
| 150 | + char briefingtext[816]; //!< ブリーフィング文章・本文 | |
| 151 | + bool collision; //!< 当たり判定を多めに行う | |
| 152 | + bool screen; //!< 画面を暗めにする | |
| 153 | + char addsmallobject_modelpath[_MAX_PATH]; //!< 追加小物のモデルデータパス | |
| 154 | + char addsmallobject_texturepath[_MAX_PATH]; //!< 追加小物のテクスチャパス | |
| 155 | + int addsmallobject_decide; //!< 追加小物の当たり判定の大きさ | |
| 156 | + int addsmallobject_hp; //!< 追加小物の耐久力 | |
| 157 | + char addsmallobject_soundpath[_MAX_PATH]; //!< 追加小物のサウンドデータパス | |
| 158 | + int addsmallobject_jump; //!< 追加小物の飛び具合 | |
| 159 | + | |
| 160 | +public: | |
| 161 | + MIFInterface(); | |
| 162 | + ~MIFInterface(); | |
| 163 | + int LoadFiledata(char *fname); | |
| 164 | + bool GetFiletype(); | |
| 165 | + char* GetMissionName(); | |
| 166 | + char* GetMissionFullname(); | |
| 167 | + void GetDatafilePath(char *blockfile, char *pointfile); | |
| 168 | + int GetSkynumber(); | |
| 169 | + void GetPicturefilePath(char *picturefileA, char *picturefileB); | |
| 170 | + char* GetBriefingText(); | |
| 171 | + bool GetCollisionFlag(); | |
| 172 | + bool GetScreenFlag(); | |
| 173 | + char* GetAddSmallobjectModelPath(); | |
| 174 | + char* GetAddSmallobjectTexturePath(); | |
| 175 | + int GetAddSmallobjectDecide(); | |
| 176 | + int GetAddSmallobjectHP(); | |
| 177 | + char* GetAddSmallobjectSoundPath(); | |
| 178 | + int GetAddSmallobjectJump(); | |
| 179 | +}; | |
| 180 | + | |
| 181 | +//! @brief ADDONリストを管理するクラス | |
| 182 | +//! @details 特定のディレクトリに入った.mifをADDONリストとして管理します。 | |
| 183 | +class AddonList : public DataInterface | |
| 184 | +{ | |
| 185 | + char filename[MAX_ADDONLIST][_MAX_PATH]; //!< .mifファイル名 | |
| 186 | + char mission_name[MAX_ADDONLIST][24]; //!< ミッション識別名 | |
| 187 | + | |
| 188 | + void GetMIFlist(char *dir); | |
| 189 | + void GetMissionName(char *dir); | |
| 190 | + void Sort(); | |
| 191 | + | |
| 192 | +public: | |
| 193 | + AddonList(); | |
| 194 | + ~AddonList(); | |
| 195 | + int LoadFiledata(char *dir); | |
| 196 | + char *GetMissionName(int id); | |
| 197 | + char *GetFileName(int id); | |
| 198 | +}; | |
| 199 | + | |
| 200 | +int DeleteLinefeed(char str[]); | |
| 201 | + | |
| 202 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,1612 @@ | ||
| 1 | +//! @file parameter.cpp | |
| 2 | +//! @brief ParameterInfoクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +// 人・武器・小物 設定データの確認作業 | |
| 33 | +// Mandaさん (2014年12月〜) | |
| 34 | + | |
| 35 | +#include "parameter.h" | |
| 36 | + | |
| 37 | +//! コンストラクタ | |
| 38 | +ParameterInfo::ParameterInfo() | |
| 39 | +{ | |
| 40 | + Human = NULL; | |
| 41 | + for(int i=0; i<TOTAL_HUMANTEXTURE; i++){ | |
| 42 | + HumanTexturePath[i] = NULL; | |
| 43 | + } | |
| 44 | + Weapon = NULL; | |
| 45 | + SmallObject = NULL; | |
| 46 | + for(int i=0; i<TOTAL_OFFICIALMISSION; i++){ | |
| 47 | + missionname[i] = NULL; | |
| 48 | + missionfullname[i] = NULL; | |
| 49 | + missiondirectory[i] = NULL; | |
| 50 | + missiontxt[i] = NULL; | |
| 51 | + } | |
| 52 | + AIlevel = NULL; | |
| 53 | +} | |
| 54 | + | |
| 55 | +//! ディストラクタ | |
| 56 | +ParameterInfo::~ParameterInfo() | |
| 57 | +{ | |
| 58 | + //CleanupModelTextureWeapon(); | |
| 59 | + //CleanupModelTextureSmallObject(); | |
| 60 | + | |
| 61 | + if( Human != NULL ){ delete [] Human; } | |
| 62 | + if( Weapon != NULL ){ delete [] Weapon; } | |
| 63 | + if( SmallObject != NULL ){ delete [] SmallObject; } | |
| 64 | + if( AIlevel != NULL ){ delete [] AIlevel; } | |
| 65 | +} | |
| 66 | + | |
| 67 | +//! 初期化(パラメータの設定) | |
| 68 | +void ParameterInfo::InitInfo() | |
| 69 | +{ | |
| 70 | + Human = new HumanParameter[TOTAL_PARAMETERINFO_HUMAN]; | |
| 71 | + Weapon = new WeaponParameter[TOTAL_PARAMETERINFO_WEAPON]; | |
| 72 | + SmallObject = new SmallObjectParameter[TOTAL_PARAMETERINFO_SMALLOBJECT]; | |
| 73 | + AIlevel = new AIParameter[TOTAL_PARAMETERINFO_AILEVEL]; | |
| 74 | + | |
| 75 | + //特殊 黒 A | |
| 76 | + Human[0].texture = 14; | |
| 77 | + Human[0].model = 5; | |
| 78 | + Human[0].hp = 120; | |
| 79 | + Human[0].AIlevel = 3; | |
| 80 | + Human[0].Weapon[0] = 21; | |
| 81 | + Human[0].Weapon[1] = 8; | |
| 82 | + Human[0].type = 0; | |
| 83 | + //特殊 黒 B | |
| 84 | + Human[1].texture = 14; | |
| 85 | + Human[1].model = 5; | |
| 86 | + Human[1].hp = 120; | |
| 87 | + Human[1].AIlevel = 3; | |
| 88 | + Human[1].Weapon[0] = 21; | |
| 89 | + Human[1].Weapon[1] = 2; | |
| 90 | + Human[1].type = 0; | |
| 91 | + //特殊 緑 A | |
| 92 | + Human[2].texture = 16; | |
| 93 | + Human[2].model = 0; | |
| 94 | + Human[2].hp = 110; | |
| 95 | + Human[2].AIlevel = 2; | |
| 96 | + Human[2].Weapon[0] = 3; | |
| 97 | + Human[2].Weapon[1] = 6; | |
| 98 | + Human[2].type = 0; | |
| 99 | + //特殊 緑 B | |
| 100 | + Human[3].texture = 16; | |
| 101 | + Human[3].model = 0; | |
| 102 | + Human[3].hp = 110; | |
| 103 | + Human[3].AIlevel = 2; | |
| 104 | + Human[3].Weapon[0] = 3; | |
| 105 | + Human[3].Weapon[1] = 10; | |
| 106 | + Human[3].type = 0; | |
| 107 | + //特殊 緑 C | |
| 108 | + Human[4].texture = 16; | |
| 109 | + Human[4].model = 0; | |
| 110 | + Human[4].hp = 110; | |
| 111 | + Human[4].AIlevel = 2; | |
| 112 | + Human[4].Weapon[0] = 3; | |
| 113 | + Human[4].Weapon[1] = 2; | |
| 114 | + Human[4].type = 0; | |
| 115 | + //特殊 白 A | |
| 116 | + Human[5].texture = 18; | |
| 117 | + Human[5].model = 0; | |
| 118 | + Human[5].hp = 110; | |
| 119 | + Human[5].AIlevel = 2; | |
| 120 | + Human[5].Weapon[0] = 4; | |
| 121 | + Human[5].Weapon[1] = 7; | |
| 122 | + Human[5].type = 0; | |
| 123 | + //特殊 白 B | |
| 124 | + Human[6].texture = 18; | |
| 125 | + Human[6].model = 0; | |
| 126 | + Human[6].hp = 110; | |
| 127 | + Human[6].AIlevel = 2; | |
| 128 | + Human[6].Weapon[0] = 4; | |
| 129 | + Human[6].Weapon[1] = 2; | |
| 130 | + Human[6].type = 0; | |
| 131 | + //ハゲ | |
| 132 | + Human[7].texture = 5; | |
| 133 | + Human[7].model = 0; | |
| 134 | + Human[7].hp = 100; | |
| 135 | + Human[7].AIlevel = 3; | |
| 136 | + Human[7].Weapon[0] = 4; | |
| 137 | + Human[7].Weapon[1] = 0; | |
| 138 | + Human[7].type = 0; | |
| 139 | + //特殊 紫 | |
| 140 | + Human[8].texture = 17; | |
| 141 | + Human[8].model = 0; | |
| 142 | + Human[8].hp = 110; | |
| 143 | + Human[8].AIlevel = 3; | |
| 144 | + Human[8].Weapon[0] = 22; | |
| 145 | + Human[8].Weapon[1] = 14; | |
| 146 | + Human[8].type = 0; | |
| 147 | + //特殊 青 | |
| 148 | + Human[9].texture = 15; | |
| 149 | + Human[9].model = 5; | |
| 150 | + Human[9].hp = 120; | |
| 151 | + Human[9].AIlevel = 2; | |
| 152 | + Human[9].Weapon[0] = 3; | |
| 153 | + Human[9].Weapon[1] = 1; | |
| 154 | + Human[9].type = 0; | |
| 155 | + //戦闘用ロボット | |
| 156 | + Human[10].texture = 13; | |
| 157 | + Human[10].model = 0; | |
| 158 | + Human[10].hp = 2500; | |
| 159 | + Human[10].AIlevel = 4; | |
| 160 | + Human[10].Weapon[0] = 6; | |
| 161 | + Human[10].Weapon[1] = 12; | |
| 162 | + Human[10].type = 1; | |
| 163 | + //スーツ 黒 SG | |
| 164 | + Human[11].texture = 4; | |
| 165 | + Human[11].model = 1; | |
| 166 | + Human[11].hp = 100; | |
| 167 | + Human[11].AIlevel = 1; | |
| 168 | + Human[11].Weapon[0] = 18; | |
| 169 | + Human[11].Weapon[1] = 0; | |
| 170 | + Human[11].type = 0; | |
| 171 | + //スーツ 黒 | |
| 172 | + Human[12].texture = 4; | |
| 173 | + Human[12].model = 0; | |
| 174 | + Human[12].hp = 100; | |
| 175 | + Human[12].AIlevel = 1; | |
| 176 | + Human[12].Weapon[0] = 5; | |
| 177 | + Human[12].Weapon[1] = 0; | |
| 178 | + Human[12].type = 0; | |
| 179 | + //スーツ 灰 | |
| 180 | + Human[13].texture = 11; | |
| 181 | + Human[13].model = 0; | |
| 182 | + Human[13].hp = 100; | |
| 183 | + Human[13].AIlevel = 0; | |
| 184 | + Human[13].Weapon[0] = 0; | |
| 185 | + Human[13].Weapon[1] = 0; | |
| 186 | + Human[13].type = 0; | |
| 187 | + //警察官 | |
| 188 | + Human[14].texture = 8; | |
| 189 | + Human[14].model = 2; | |
| 190 | + Human[14].hp = 100; | |
| 191 | + Human[14].AIlevel = 1; | |
| 192 | + Human[14].Weapon[0] = 3; | |
| 193 | + Human[14].Weapon[1] = 0; | |
| 194 | + Human[14].type = 0; | |
| 195 | + //スーツ 茶 | |
| 196 | + Human[15].texture = 9; | |
| 197 | + Human[15].model = 0; | |
| 198 | + Human[15].hp = 100; | |
| 199 | + Human[15].AIlevel = 0; | |
| 200 | + Human[15].Weapon[0] = 0; | |
| 201 | + Human[15].Weapon[1] = 0; | |
| 202 | + Human[15].type = 0; | |
| 203 | + //シャツ男 1 | |
| 204 | + Human[16].texture = 23; | |
| 205 | + Human[16].model = 0; | |
| 206 | + Human[16].hp = 100; | |
| 207 | + Human[16].AIlevel = 0; | |
| 208 | + Human[16].Weapon[0] = 17; | |
| 209 | + Human[16].Weapon[1] = 0; | |
| 210 | + Human[16].type = 0; | |
| 211 | + //中東兵 | |
| 212 | + Human[17].texture = 6; | |
| 213 | + Human[17].model = 0; | |
| 214 | + Human[17].hp = 100; | |
| 215 | + Human[17].AIlevel = 1; | |
| 216 | + Human[17].Weapon[0] = 17; | |
| 217 | + Human[17].Weapon[1] = 10; | |
| 218 | + Human[17].type = 0; | |
| 219 | + //女 | |
| 220 | + Human[18].texture = 25; | |
| 221 | + Human[18].model = 3; | |
| 222 | + Human[18].hp = 90; | |
| 223 | + Human[18].AIlevel = 0; | |
| 224 | + Human[18].Weapon[0] = 0; | |
| 225 | + Human[18].Weapon[1] = 0; | |
| 226 | + Human[18].type = 0; | |
| 227 | + //金髪男 | |
| 228 | + Human[19].texture = 0; | |
| 229 | + Human[19].model = 0; | |
| 230 | + Human[19].hp = 100; | |
| 231 | + Human[19].AIlevel = 0; | |
| 232 | + Human[19].Weapon[0] = 0; | |
| 233 | + Human[19].Weapon[1] = 0; | |
| 234 | + Human[19].type = 0; | |
| 235 | + //市民 1 | |
| 236 | + Human[20].texture = 1; | |
| 237 | + Human[20].model = 0; | |
| 238 | + Human[20].hp = 100; | |
| 239 | + Human[20].AIlevel = 0; | |
| 240 | + Human[20].Weapon[0] = 0; | |
| 241 | + Human[20].Weapon[1] = 0; | |
| 242 | + Human[20].type = 0; | |
| 243 | + //市民 2 | |
| 244 | + Human[21].texture = 2; | |
| 245 | + Human[21].model = 0; | |
| 246 | + Human[21].hp = 100; | |
| 247 | + Human[21].AIlevel = 0; | |
| 248 | + Human[21].Weapon[0] = 0; | |
| 249 | + Human[21].Weapon[1] = 0; | |
| 250 | + Human[21].type = 0; | |
| 251 | + //シャツ男 1 SG | |
| 252 | + Human[22].texture = 23; | |
| 253 | + Human[22].model = 1; | |
| 254 | + Human[22].hp = 100; | |
| 255 | + Human[22].AIlevel = 0; | |
| 256 | + Human[22].Weapon[0] = 0; | |
| 257 | + Human[22].Weapon[1] = 0; | |
| 258 | + Human[22].type = 0; | |
| 259 | + //金髪男 SG | |
| 260 | + Human[23].texture = 0; | |
| 261 | + Human[23].model = 1; | |
| 262 | + Human[23].hp = 100; | |
| 263 | + Human[23].AIlevel = 0; | |
| 264 | + Human[23].Weapon[0] = 0; | |
| 265 | + Human[23].Weapon[1] = 0; | |
| 266 | + Human[23].type = 0; | |
| 267 | + //市民 1 SG | |
| 268 | + Human[24].texture = 1; | |
| 269 | + Human[24].model = 1; | |
| 270 | + Human[24].hp = 100; | |
| 271 | + Human[24].AIlevel = 0; | |
| 272 | + Human[24].Weapon[0] = 0; | |
| 273 | + Human[24].Weapon[1] = 0; | |
| 274 | + Human[24].type = 0; | |
| 275 | + //市民 2 SG | |
| 276 | + Human[25].texture = 2; | |
| 277 | + Human[25].model = 1; | |
| 278 | + Human[25].hp = 100; | |
| 279 | + Human[25].AIlevel = 0; | |
| 280 | + Human[25].Weapon[0] = 0; | |
| 281 | + Human[25].Weapon[1] = 0; | |
| 282 | + Human[25].type = 0; | |
| 283 | + //兵士 1 A | |
| 284 | + Human[26].texture = 19; | |
| 285 | + Human[26].model = 4; | |
| 286 | + Human[26].hp = 115; | |
| 287 | + Human[26].AIlevel = 2; | |
| 288 | + Human[26].Weapon[0] = 5; | |
| 289 | + Human[26].Weapon[1] = 9; | |
| 290 | + Human[26].type = 0; | |
| 291 | + //兵士 1 B | |
| 292 | + Human[27].texture = 20; | |
| 293 | + Human[27].model = 4; | |
| 294 | + Human[27].hp = 115; | |
| 295 | + Human[27].AIlevel = 2; | |
| 296 | + Human[27].Weapon[0] = 5; | |
| 297 | + Human[27].Weapon[1] = 12; | |
| 298 | + Human[27].type = 0; | |
| 299 | + //兵士 2 | |
| 300 | + Human[28].texture = 21; | |
| 301 | + Human[28].model = 4; | |
| 302 | + Human[28].hp = 115; | |
| 303 | + Human[28].AIlevel = 2; | |
| 304 | + Human[28].Weapon[0] = 13; | |
| 305 | + Human[28].Weapon[1] = 10; | |
| 306 | + Human[28].type = 0; | |
| 307 | + //ゾンビ 1 | |
| 308 | + Human[29].texture = 26; | |
| 309 | + Human[29].model = 0; | |
| 310 | + Human[29].hp = 1000; | |
| 311 | + Human[29].AIlevel = 0; | |
| 312 | + Human[29].Weapon[0] = 0; | |
| 313 | + Human[29].Weapon[1] = 0; | |
| 314 | + Human[29].type = 2; | |
| 315 | + //ゾンビ 2 | |
| 316 | + Human[30].texture = 27; | |
| 317 | + Human[30].model = 0; | |
| 318 | + Human[30].hp = 1000; | |
| 319 | + Human[30].AIlevel = 0; | |
| 320 | + Human[30].Weapon[0] = 0; | |
| 321 | + Human[30].Weapon[1] = 0; | |
| 322 | + Human[30].type = 2; | |
| 323 | + //ゾンビ 3 | |
| 324 | + Human[31].texture = 28; | |
| 325 | + Human[31].model = 0; | |
| 326 | + Human[31].hp = 1000; | |
| 327 | + Human[31].AIlevel = 0; | |
| 328 | + Human[31].Weapon[0] = 0; | |
| 329 | + Human[31].Weapon[1] = 0; | |
| 330 | + Human[31].type = 2; | |
| 331 | + //ゾンビ 4 | |
| 332 | + Human[32].texture = 29; | |
| 333 | + Human[32].model = 3; | |
| 334 | + Human[32].hp = 950; | |
| 335 | + Human[32].AIlevel = 0; | |
| 336 | + Human[32].Weapon[0] = 0; | |
| 337 | + Human[32].Weapon[1] = 0; | |
| 338 | + Human[32].type = 2; | |
| 339 | + //スーツ 紺 | |
| 340 | + Human[33].texture = 12; | |
| 341 | + Human[33].model = 0; | |
| 342 | + Human[33].hp = 100; | |
| 343 | + Human[33].AIlevel = 0; | |
| 344 | + Human[33].Weapon[0] = 0; | |
| 345 | + Human[33].Weapon[1] = 0; | |
| 346 | + Human[33].type = 0; | |
| 347 | + //スーツ 紺 SG | |
| 348 | + Human[34].texture = 12; | |
| 349 | + Human[34].model = 1; | |
| 350 | + Human[34].hp = 100; | |
| 351 | + Human[34].AIlevel = 1; | |
| 352 | + Human[34].Weapon[0] = 17; | |
| 353 | + Human[34].Weapon[1] = 0; | |
| 354 | + Human[34].type = 0; | |
| 355 | + //将軍 | |
| 356 | + Human[35].texture = 7; | |
| 357 | + Human[35].model = 0; | |
| 358 | + Human[35].hp = 95; | |
| 359 | + Human[35].AIlevel = 1; | |
| 360 | + Human[35].Weapon[0] = 17; | |
| 361 | + Human[35].Weapon[1] = 0; | |
| 362 | + Human[35].type = 0; | |
| 363 | + //スーツ 青 | |
| 364 | + Human[36].texture = 10; | |
| 365 | + Human[36].model = 0; | |
| 366 | + Human[36].hp = 100; | |
| 367 | + Human[36].AIlevel = 0; | |
| 368 | + Human[36].Weapon[0] = 0; | |
| 369 | + Human[36].Weapon[1] = 0; | |
| 370 | + Human[36].type = 0; | |
| 371 | + //スーツ 青 SG | |
| 372 | + Human[37].texture = 10; | |
| 373 | + Human[37].model = 1; | |
| 374 | + Human[37].hp = 100; | |
| 375 | + Human[37].AIlevel = 1; | |
| 376 | + Human[37].Weapon[0] = 18; | |
| 377 | + Human[37].Weapon[1] = 0; | |
| 378 | + Human[37].type = 0; | |
| 379 | + //シャツ男 2 SG | |
| 380 | + Human[38].texture = 24; | |
| 381 | + Human[38].model = 1; | |
| 382 | + Human[38].hp = 100; | |
| 383 | + Human[38].AIlevel = 1; | |
| 384 | + Human[38].Weapon[0] = 6; | |
| 385 | + Human[38].Weapon[1] = 0; | |
| 386 | + Human[38].type = 0; | |
| 387 | + //兵士 3 | |
| 388 | + Human[39].texture = 22; | |
| 389 | + Human[39].model = 0; | |
| 390 | + Human[39].hp = 105; | |
| 391 | + Human[39].AIlevel = 3; | |
| 392 | + Human[39].Weapon[0] = 5; | |
| 393 | + Human[39].Weapon[1] = 20; | |
| 394 | + Human[39].type = 0; | |
| 395 | + //兵士 3 SG | |
| 396 | + Human[40].texture = 22; | |
| 397 | + Human[40].model = 1; | |
| 398 | + Human[40].hp = 105; | |
| 399 | + Human[40].AIlevel = 3; | |
| 400 | + Human[40].Weapon[0] = 21; | |
| 401 | + Human[40].Weapon[1] = 0; | |
| 402 | + Human[40].type = 0; | |
| 403 | + //ゲイツ | |
| 404 | + Human[41].texture = 3; | |
| 405 | + Human[41].model = 0; | |
| 406 | + Human[41].hp = 100; | |
| 407 | + Human[41].AIlevel = 0; | |
| 408 | + Human[41].Weapon[0] = 0; | |
| 409 | + Human[41].Weapon[1] = 0; | |
| 410 | + Human[41].type = 0; | |
| 411 | + //ゲイツ SG | |
| 412 | + Human[42].texture = 3; | |
| 413 | + Human[42].model = 1; | |
| 414 | + Human[42].hp = 100; | |
| 415 | + Human[42].AIlevel = 4; | |
| 416 | + Human[42].Weapon[0] = 22; | |
| 417 | + Human[42].Weapon[1] = 0; | |
| 418 | + Human[42].type = 0; | |
| 419 | + | |
| 420 | + HumanTexturePath[0] = "./data/model/civ1.bmp"; | |
| 421 | + HumanTexturePath[1] = "./data/model/civ2.bmp"; | |
| 422 | + HumanTexturePath[2] = "./data/model/civ3.bmp"; | |
| 423 | + HumanTexturePath[3] = "./data/model/gates.bmp"; | |
| 424 | + HumanTexturePath[4] = "./data/model/gs.bmp"; | |
| 425 | + HumanTexturePath[5] = "./data/model/hage.bmp"; | |
| 426 | + HumanTexturePath[6] = "./data/model/islam.bmp"; | |
| 427 | + HumanTexturePath[7] = "./data/model/islam2.bmp"; | |
| 428 | + HumanTexturePath[8] = "./data/model/police.bmp"; | |
| 429 | + HumanTexturePath[9] = "./data/model/riiman.bmp"; | |
| 430 | + HumanTexturePath[10] = "./data/model/riiman_b.bmp"; | |
| 431 | + HumanTexturePath[11] = "./data/model/riiman_g.bmp"; | |
| 432 | + HumanTexturePath[12] = "./data/model/riiman_k.bmp"; | |
| 433 | + HumanTexturePath[13] = "./data/model/robot.bmp"; | |
| 434 | + HumanTexturePath[14] = "./data/model/soldier_black.bmp"; | |
| 435 | + HumanTexturePath[15] = "./data/model/soldier_blue.bmp"; | |
| 436 | + HumanTexturePath[16] = "./data/model/soldier_green.bmp"; | |
| 437 | + HumanTexturePath[17] = "./data/model/soldier_violet.bmp"; | |
| 438 | + HumanTexturePath[18] = "./data/model/soldier_white.bmp"; | |
| 439 | + HumanTexturePath[19] = "./data/model/soldier0.bmp"; | |
| 440 | + HumanTexturePath[20] = "./data/model/soldier1.bmp"; | |
| 441 | + HumanTexturePath[21] = "./data/model/soldier2.bmp"; | |
| 442 | + HumanTexturePath[22] = "./data/model/soldier3.bmp"; | |
| 443 | + HumanTexturePath[23] = "./data/model/syatu.bmp"; | |
| 444 | + HumanTexturePath[24] = "./data/model/syatu2.bmp"; | |
| 445 | + HumanTexturePath[25] = "./data/model/woman.bmp"; | |
| 446 | + HumanTexturePath[26] = "./data/model/zombie1.bmp"; | |
| 447 | + HumanTexturePath[27] = "./data/model/zombie2.bmp"; | |
| 448 | + HumanTexturePath[28] = "./data/model/zombie3.bmp"; | |
| 449 | + HumanTexturePath[29] = "./data/model/zombie4.bmp"; | |
| 450 | + | |
| 451 | + | |
| 452 | + Weapon[0].name = "NONE"; // ID_WEAPON_NONE 定数を要設定 | |
| 453 | + Weapon[0].model = ""; | |
| 454 | + Weapon[0].texture= ""; | |
| 455 | + Weapon[0].attacks = 0; | |
| 456 | + Weapon[0].penetration = 0; | |
| 457 | + Weapon[0].blazings = 0; | |
| 458 | + Weapon[0].speed = 0; | |
| 459 | + Weapon[0].nbsmax = 0; | |
| 460 | + Weapon[0].reloads = 0; | |
| 461 | + Weapon[0].reaction = 0; | |
| 462 | + Weapon[0].ErrorRangeMIN = 0; | |
| 463 | + Weapon[0].ErrorRangeMAX = 0; | |
| 464 | + Weapon[0].mx = 0.0f; | |
| 465 | + Weapon[0].my = 0.0f; | |
| 466 | + Weapon[0].mz = 0.0f; | |
| 467 | + Weapon[0].flashx = 0.0f; | |
| 468 | + Weapon[0].flashy = 0.0f; | |
| 469 | + Weapon[0].flashz = 0.0f; | |
| 470 | + Weapon[0].yakkyou_px = 0.0f; | |
| 471 | + Weapon[0].yakkyou_py = 0.0f; | |
| 472 | + Weapon[0].yakkyou_pz = 0.0f; | |
| 473 | + Weapon[0].yakkyou_sx = 0.0f; | |
| 474 | + Weapon[0].yakkyou_sy = 0.0f; | |
| 475 | + Weapon[0].blazingmode = true; | |
| 476 | + Weapon[0].scopemode = 0; | |
| 477 | + Weapon[0].size = 9.0f; | |
| 478 | + Weapon[0].soundid = 0; | |
| 479 | + Weapon[0].soundvolume = 0; | |
| 480 | + Weapon[0].silencer = false; | |
| 481 | + Weapon[0].WeaponP = 2; | |
| 482 | + Weapon[0].ChangeWeapon = -1; | |
| 483 | + Weapon[0].burst = 0; | |
| 484 | + Weapon[1].name = "MP5"; | |
| 485 | + Weapon[1].model = "./data/model/weapon/mp5.x"; | |
| 486 | + Weapon[1].texture= "./data/model/weapon/mp5.bmp"; | |
| 487 | + Weapon[1].attacks = 44; | |
| 488 | + Weapon[1].penetration = 0; | |
| 489 | + Weapon[1].blazings = 4; | |
| 490 | + Weapon[1].speed = 10; | |
| 491 | + Weapon[1].nbsmax = 30; | |
| 492 | + Weapon[1].reloads = 50; | |
| 493 | + Weapon[1].reaction = 6; | |
| 494 | + Weapon[1].ErrorRangeMIN = 2; | |
| 495 | + Weapon[1].ErrorRangeMAX = 21; | |
| 496 | + Weapon[1].mx = 8.0f; | |
| 497 | + Weapon[1].my = 9.0f; | |
| 498 | + Weapon[1].mz = 35.0f; | |
| 499 | + Weapon[1].flashx = 8.0f; | |
| 500 | + Weapon[1].flashy = 15.0f; | |
| 501 | + Weapon[1].flashz = 68.0f; | |
| 502 | + Weapon[1].yakkyou_px = 8.0f; | |
| 503 | + Weapon[1].yakkyou_py = 12.0f; | |
| 504 | + Weapon[1].yakkyou_pz = 35.0f; | |
| 505 | + Weapon[1].yakkyou_sx = 5.0f; | |
| 506 | + Weapon[1].yakkyou_sy = 7.0f; | |
| 507 | + Weapon[1].blazingmode = true; | |
| 508 | + Weapon[1].scopemode = 0; | |
| 509 | + Weapon[1].size = 7.5f; | |
| 510 | + Weapon[1].soundid = 0; | |
| 511 | + Weapon[1].soundvolume = 92; | |
| 512 | + Weapon[1].silencer = false; | |
| 513 | + Weapon[1].WeaponP = 0; | |
| 514 | + Weapon[1].ChangeWeapon = -1; | |
| 515 | + Weapon[1].burst = 1; | |
| 516 | + Weapon[2].name = "PSG1"; | |
| 517 | + Weapon[2].model = "./data/model/weapon/psg1.x"; | |
| 518 | + Weapon[2].texture= "./data/model/weapon/psg1.bmp"; | |
| 519 | + Weapon[2].attacks = 70; | |
| 520 | + Weapon[2].penetration = 2; | |
| 521 | + Weapon[2].blazings = 7; | |
| 522 | + Weapon[2].speed = 14; | |
| 523 | + Weapon[2].nbsmax = 5; | |
| 524 | + Weapon[2].reloads = 58; | |
| 525 | + Weapon[2].reaction = 15; | |
| 526 | + Weapon[2].ErrorRangeMIN = 0; | |
| 527 | + Weapon[2].ErrorRangeMAX = 19; | |
| 528 | + Weapon[2].mx = 8.0f; | |
| 529 | + Weapon[2].my = 8.0f; | |
| 530 | + Weapon[2].mz = 44.0f; | |
| 531 | + Weapon[2].flashx = 8.0f; | |
| 532 | + Weapon[2].flashy = 13.0f; | |
| 533 | + Weapon[2].flashz = 108.0f; | |
| 534 | + Weapon[2].yakkyou_px = 8.0f; | |
| 535 | + Weapon[2].yakkyou_py = 13.0f; | |
| 536 | + Weapon[2].yakkyou_pz = 38.0f; | |
| 537 | + Weapon[2].yakkyou_sx = 6.0f; | |
| 538 | + Weapon[2].yakkyou_sy = 6.0f; | |
| 539 | + Weapon[2].blazingmode = false; | |
| 540 | + Weapon[2].scopemode = 2; | |
| 541 | + Weapon[2].size = 8.0f; | |
| 542 | + Weapon[2].soundid = 1; | |
| 543 | + Weapon[2].soundvolume = 98; | |
| 544 | + Weapon[2].silencer = false; | |
| 545 | + Weapon[2].WeaponP = 0; | |
| 546 | + Weapon[2].ChangeWeapon = -1; | |
| 547 | + Weapon[2].burst = 1; | |
| 548 | + Weapon[3].name = "M92F"; | |
| 549 | + Weapon[3].model = "./data/model/weapon/m92f.x"; | |
| 550 | + Weapon[3].texture= "./data/model/weapon/m92f.bmp"; | |
| 551 | + Weapon[3].attacks = 41; | |
| 552 | + Weapon[3].penetration = 0; | |
| 553 | + Weapon[3].blazings = 5; | |
| 554 | + Weapon[3].speed = 9; | |
| 555 | + Weapon[3].nbsmax = 15; | |
| 556 | + Weapon[3].reloads = 40; | |
| 557 | + Weapon[3].reaction = 10; | |
| 558 | + Weapon[3].ErrorRangeMIN = 4; | |
| 559 | + Weapon[3].ErrorRangeMAX = 26; | |
| 560 | + Weapon[3].mx = 2.0f; | |
| 561 | + Weapon[3].my = 7.0f; | |
| 562 | + Weapon[3].mz = 57.0f; | |
| 563 | + Weapon[3].flashx = 2.0f; | |
| 564 | + Weapon[3].flashy = 15.0f; | |
| 565 | + Weapon[3].flashz = 73.0f; | |
| 566 | + Weapon[3].yakkyou_px = 2.0f; | |
| 567 | + Weapon[3].yakkyou_py = 15.0f; | |
| 568 | + Weapon[3].yakkyou_pz = 56.0f; | |
| 569 | + Weapon[3].yakkyou_sx = 4.0f; | |
| 570 | + Weapon[3].yakkyou_sy = 4.0f; | |
| 571 | + Weapon[3].blazingmode = false; | |
| 572 | + Weapon[3].scopemode = 0; | |
| 573 | + Weapon[3].size = 7.0f; | |
| 574 | + Weapon[3].soundid = 1; | |
| 575 | + Weapon[3].soundvolume = 90; | |
| 576 | + Weapon[3].silencer = false; | |
| 577 | + Weapon[3].WeaponP = 1; | |
| 578 | + Weapon[3].ChangeWeapon = -1; | |
| 579 | + Weapon[3].burst = 1; | |
| 580 | + Weapon[4].name = "GLOCK18 SEMI"; | |
| 581 | + Weapon[4].model = "./data/model/weapon/glock18.x"; | |
| 582 | + Weapon[4].texture= "./data/model/weapon/glock18.bmp"; | |
| 583 | + Weapon[4].attacks = 38; | |
| 584 | + Weapon[4].penetration = 0; | |
| 585 | + Weapon[4].blazings = 5; | |
| 586 | + Weapon[4].speed = 9; | |
| 587 | + Weapon[4].nbsmax = 19; | |
| 588 | + Weapon[4].reloads = 38; | |
| 589 | + Weapon[4].reaction = 9; | |
| 590 | + Weapon[4].ErrorRangeMIN = 4; | |
| 591 | + Weapon[4].ErrorRangeMAX = 26; | |
| 592 | + Weapon[4].mx = 2.0f; | |
| 593 | + Weapon[4].my = 8.0f; | |
| 594 | + Weapon[4].mz = 56.0f; | |
| 595 | + Weapon[4].flashx = 2.0f; | |
| 596 | + Weapon[4].flashy = 13.0f; | |
| 597 | + Weapon[4].flashz = 70.0f; | |
| 598 | + Weapon[4].yakkyou_px = 2.0f; | |
| 599 | + Weapon[4].yakkyou_py = 14.0f; | |
| 600 | + Weapon[4].yakkyou_pz = 54.0f; | |
| 601 | + Weapon[4].yakkyou_sx = 4.0f; | |
| 602 | + Weapon[4].yakkyou_sy = 4.0f; | |
| 603 | + Weapon[4].blazingmode = false; | |
| 604 | + Weapon[4].scopemode = 0; | |
| 605 | + Weapon[4].size = 5.0f; | |
| 606 | + Weapon[4].soundid = 0; | |
| 607 | + Weapon[4].soundvolume = 90; | |
| 608 | + Weapon[4].silencer = false; | |
| 609 | + Weapon[4].WeaponP = 1; | |
| 610 | + Weapon[4].ChangeWeapon = 16; | |
| 611 | + Weapon[4].burst = 1; | |
| 612 | + Weapon[5].name = "DESERT EAGLE"; | |
| 613 | + Weapon[5].model = "./data/model/weapon/de.x"; | |
| 614 | + Weapon[5].texture= "./data/model/weapon/de.bmp"; | |
| 615 | + Weapon[5].attacks = 68; | |
| 616 | + Weapon[5].penetration = 1; | |
| 617 | + Weapon[5].blazings = 5; | |
| 618 | + Weapon[5].speed = 10; | |
| 619 | + Weapon[5].nbsmax = 7; | |
| 620 | + Weapon[5].reloads = 41; | |
| 621 | + Weapon[5].reaction = 13; | |
| 622 | + Weapon[5].ErrorRangeMIN = 4; | |
| 623 | + Weapon[5].ErrorRangeMAX = 26; | |
| 624 | + Weapon[5].mx = 2.0f; | |
| 625 | + Weapon[5].my = 11.0f; | |
| 626 | + Weapon[5].mz = 59.0f; | |
| 627 | + Weapon[5].flashx = 2.0f; | |
| 628 | + Weapon[5].flashy = 14.0f; | |
| 629 | + Weapon[5].flashz = 75.0f; | |
| 630 | + Weapon[5].yakkyou_px = 2.0f; | |
| 631 | + Weapon[5].yakkyou_py = 15.0f; | |
| 632 | + Weapon[5].yakkyou_pz = 56.0f; | |
| 633 | + Weapon[5].yakkyou_sx = 5.0f; | |
| 634 | + Weapon[5].yakkyou_sy = 4.0f; | |
| 635 | + Weapon[5].blazingmode = false; | |
| 636 | + Weapon[5].scopemode = 0; | |
| 637 | + Weapon[5].size = 11.0f; | |
| 638 | + Weapon[5].soundid = 2; | |
| 639 | + Weapon[5].soundvolume = 96; | |
| 640 | + Weapon[5].silencer = false; | |
| 641 | + Weapon[5].WeaponP = 1; | |
| 642 | + Weapon[5].ChangeWeapon = -1; | |
| 643 | + Weapon[5].burst = 1; | |
| 644 | + Weapon[6].name = "MAC10"; | |
| 645 | + Weapon[6].model = "./data/model/weapon/mac10.x"; | |
| 646 | + Weapon[6].texture= "./data/model/weapon/mac10.bmp"; | |
| 647 | + Weapon[6].attacks = 47; | |
| 648 | + Weapon[6].penetration = 0; | |
| 649 | + Weapon[6].blazings = 3; | |
| 650 | + Weapon[6].speed = 10; | |
| 651 | + Weapon[6].nbsmax = 30; | |
| 652 | + Weapon[6].reloads = 45; | |
| 653 | + Weapon[6].reaction = 9; | |
| 654 | + Weapon[6].ErrorRangeMIN = 4; | |
| 655 | + Weapon[6].ErrorRangeMAX = 25; | |
| 656 | + Weapon[6].mx = 2.0f; | |
| 657 | + Weapon[6].my = 4.0f; | |
| 658 | + Weapon[6].mz = 54.0f; | |
| 659 | + Weapon[6].flashx = 2.0f; | |
| 660 | + Weapon[6].flashy = 15.0f; | |
| 661 | + Weapon[6].flashz = 73.0f; | |
| 662 | + Weapon[6].yakkyou_px = 2.0f; | |
| 663 | + Weapon[6].yakkyou_py = 16.0f; | |
| 664 | + Weapon[6].yakkyou_pz = 52.0f; | |
| 665 | + Weapon[6].yakkyou_sx = 2.0f; | |
| 666 | + Weapon[6].yakkyou_sy = 5.0f; | |
| 667 | + Weapon[6].blazingmode = true; | |
| 668 | + Weapon[6].scopemode = 0; | |
| 669 | + Weapon[6].size = 5.5f; | |
| 670 | + Weapon[6].soundid = 3; | |
| 671 | + Weapon[6].soundvolume = 90; | |
| 672 | + Weapon[6].silencer = false; | |
| 673 | + Weapon[6].WeaponP = 1; | |
| 674 | + Weapon[6].ChangeWeapon = -1; | |
| 675 | + Weapon[6].burst = 1; | |
| 676 | + Weapon[7].name = "UMP"; | |
| 677 | + Weapon[7].model = "./data/model/weapon/ump.x"; | |
| 678 | + Weapon[7].texture= "./data/model/weapon/ump.bmp"; | |
| 679 | + Weapon[7].attacks = 50; | |
| 680 | + Weapon[7].penetration = 0; | |
| 681 | + Weapon[7].blazings = 5; | |
| 682 | + Weapon[7].speed = 10; | |
| 683 | + Weapon[7].nbsmax = 25; | |
| 684 | + Weapon[7].reloads = 50; | |
| 685 | + Weapon[7].reaction = 7; | |
| 686 | + Weapon[7].ErrorRangeMIN = 2; | |
| 687 | + Weapon[7].ErrorRangeMAX = 19; | |
| 688 | + Weapon[7].mx = 8.0f; | |
| 689 | + Weapon[7].my = 6.0f; | |
| 690 | + Weapon[7].mz = 28.0f; | |
| 691 | + Weapon[7].flashx = 8.0f; | |
| 692 | + Weapon[7].flashy = 13.0f; | |
| 693 | + Weapon[7].flashz = 64.0f; | |
| 694 | + Weapon[7].yakkyou_px = 8.0f; | |
| 695 | + Weapon[7].yakkyou_py = 11.0f; | |
| 696 | + Weapon[7].yakkyou_pz = 41.0f; | |
| 697 | + Weapon[7].yakkyou_sx = 4.0f; | |
| 698 | + Weapon[7].yakkyou_sy = 4.0f; | |
| 699 | + Weapon[7].blazingmode = true; | |
| 700 | + Weapon[7].scopemode = 0; | |
| 701 | + Weapon[7].size = 6.0f; | |
| 702 | + Weapon[7].soundid = 4; | |
| 703 | + Weapon[7].soundvolume = 94; | |
| 704 | + Weapon[7].silencer = false; | |
| 705 | + Weapon[7].WeaponP = 0; | |
| 706 | + Weapon[7].ChangeWeapon = -1; | |
| 707 | + Weapon[7].burst = 1; | |
| 708 | + Weapon[8].name = "P90"; | |
| 709 | + Weapon[8].model = "./data/model/weapon/p90.x"; | |
| 710 | + Weapon[8].texture= "./data/model/weapon/p90.bmp"; | |
| 711 | + Weapon[8].attacks = 42; | |
| 712 | + Weapon[8].penetration = 1; | |
| 713 | + Weapon[8].blazings = 4; | |
| 714 | + Weapon[8].speed = 11; | |
| 715 | + Weapon[8].nbsmax = 50; | |
| 716 | + Weapon[8].reloads = 68; | |
| 717 | + Weapon[8].reaction = 6; | |
| 718 | + Weapon[8].ErrorRangeMIN = 3; | |
| 719 | + Weapon[8].ErrorRangeMAX = 18; | |
| 720 | + Weapon[8].mx = 8.0f; | |
| 721 | + Weapon[8].my = 10.0f; | |
| 722 | + Weapon[8].mz = 30.0f; | |
| 723 | + Weapon[8].flashx = 8.0f; | |
| 724 | + Weapon[8].flashy = 12.0f; | |
| 725 | + Weapon[8].flashz = 59.0f; | |
| 726 | + Weapon[8].yakkyou_px = 8.0f; | |
| 727 | + Weapon[8].yakkyou_py = 4.0f; | |
| 728 | + Weapon[8].yakkyou_pz = 18.0f; | |
| 729 | + Weapon[8].yakkyou_sx = -1.0f; | |
| 730 | + Weapon[8].yakkyou_sy = 0.0f; | |
| 731 | + Weapon[8].blazingmode = true; | |
| 732 | + Weapon[8].scopemode = 0; | |
| 733 | + Weapon[8].size = 6.5f; | |
| 734 | + Weapon[8].soundid = 3; | |
| 735 | + Weapon[8].soundvolume = 92; | |
| 736 | + Weapon[8].silencer = false; | |
| 737 | + Weapon[8].WeaponP = 0; | |
| 738 | + Weapon[8].ChangeWeapon = -1; | |
| 739 | + Weapon[8].burst = 1; | |
| 740 | + Weapon[9].name = "M4"; | |
| 741 | + Weapon[9].model = "./data/model/weapon/m4.x"; | |
| 742 | + Weapon[9].texture= "./data/model/weapon/m4.bmp"; | |
| 743 | + Weapon[9].attacks = 61; | |
| 744 | + Weapon[9].penetration = 1; | |
| 745 | + Weapon[9].blazings = 4; | |
| 746 | + Weapon[9].speed = 11; | |
| 747 | + Weapon[9].nbsmax = 30; | |
| 748 | + Weapon[9].reloads = 54; | |
| 749 | + Weapon[9].reaction = 8; | |
| 750 | + Weapon[9].ErrorRangeMIN = 3; | |
| 751 | + Weapon[9].ErrorRangeMAX = 19; | |
| 752 | + Weapon[9].mx = 9.0f; | |
| 753 | + Weapon[9].my = 6.0f; | |
| 754 | + Weapon[9].mz = 37.0f; | |
| 755 | + Weapon[9].flashx = 9.0f; | |
| 756 | + Weapon[9].flashy = 13.0f; | |
| 757 | + Weapon[9].flashz = 91.0f; | |
| 758 | + Weapon[9].yakkyou_px = 10.0f; | |
| 759 | + Weapon[9].yakkyou_py = 12.0f; | |
| 760 | + Weapon[9].yakkyou_pz = 40.0f; | |
| 761 | + Weapon[9].yakkyou_sx = 4.0f; | |
| 762 | + Weapon[9].yakkyou_sy = 6.0f; | |
| 763 | + Weapon[9].blazingmode = true; | |
| 764 | + Weapon[9].scopemode = 0; | |
| 765 | + Weapon[9].size = 6.8f; | |
| 766 | + Weapon[9].soundid = 3; | |
| 767 | + Weapon[9].soundvolume = 96; | |
| 768 | + Weapon[9].silencer = false; | |
| 769 | + Weapon[9].WeaponP = 0; | |
| 770 | + Weapon[9].ChangeWeapon = -1; | |
| 771 | + Weapon[9].burst = 1; | |
| 772 | + Weapon[10].name = "AK47"; | |
| 773 | + Weapon[10].model = "./data/model/weapon/ak47.x"; | |
| 774 | + Weapon[10].texture= "./data/model/weapon/ak47.bmp"; | |
| 775 | + Weapon[10].attacks = 65; | |
| 776 | + Weapon[10].penetration = 1; | |
| 777 | + Weapon[10].blazings = 4; | |
| 778 | + Weapon[10].speed = 11; | |
| 779 | + Weapon[10].nbsmax = 30; | |
| 780 | + Weapon[10].reloads = 52; | |
| 781 | + Weapon[10].reaction = 9; | |
| 782 | + Weapon[10].ErrorRangeMIN = 3; | |
| 783 | + Weapon[10].ErrorRangeMAX = 20; | |
| 784 | + Weapon[10].mx = 9.0f; | |
| 785 | + Weapon[10].my = 11.0f; | |
| 786 | + Weapon[10].mz = 39.0f; | |
| 787 | + Weapon[10].flashx = 9.0f; | |
| 788 | + Weapon[10].flashy = 9.0f; | |
| 789 | + Weapon[10].flashz = 86.0f; | |
| 790 | + Weapon[10].yakkyou_px = 9.0f; | |
| 791 | + Weapon[10].yakkyou_py = 12.0f; | |
| 792 | + Weapon[10].yakkyou_pz = 41.0f; | |
| 793 | + Weapon[10].yakkyou_sx = 5.0f; | |
| 794 | + Weapon[10].yakkyou_sy = 5.0f; | |
| 795 | + Weapon[10].blazingmode = true; | |
| 796 | + Weapon[10].scopemode = 0; | |
| 797 | + Weapon[10].size = 6.0f; | |
| 798 | + Weapon[10].soundid = 1; | |
| 799 | + Weapon[10].soundvolume = 96; | |
| 800 | + Weapon[10].silencer = false; | |
| 801 | + Weapon[10].WeaponP = 0; | |
| 802 | + Weapon[10].ChangeWeapon = -1; | |
| 803 | + Weapon[10].burst = 1; | |
| 804 | + Weapon[11].name = "AUG"; | |
| 805 | + Weapon[11].model = "./data/model/weapon/aug.x"; | |
| 806 | + Weapon[11].texture= "./data/model/weapon/aug.bmp"; | |
| 807 | + Weapon[11].attacks = 60; | |
| 808 | + Weapon[11].penetration = 1; | |
| 809 | + Weapon[11].blazings = 5; | |
| 810 | + Weapon[11].speed = 11; | |
| 811 | + Weapon[11].nbsmax = 30; | |
| 812 | + Weapon[11].reloads = 56; | |
| 813 | + Weapon[11].reaction = 7; | |
| 814 | + Weapon[11].ErrorRangeMIN = 2; | |
| 815 | + Weapon[11].ErrorRangeMAX = 18; | |
| 816 | + Weapon[11].mx = 8.0f; | |
| 817 | + Weapon[11].my = 10.0f; | |
| 818 | + Weapon[11].mz = 37.0f; | |
| 819 | + Weapon[11].flashx = 8.0f; | |
| 820 | + Weapon[11].flashy = 12.0f; | |
| 821 | + Weapon[11].flashz = 77.0f; | |
| 822 | + Weapon[11].yakkyou_px = 8.0f; | |
| 823 | + Weapon[11].yakkyou_py = 11.0f; | |
| 824 | + Weapon[11].yakkyou_pz = 15.0f; | |
| 825 | + Weapon[11].yakkyou_sx = 3.0f; | |
| 826 | + Weapon[11].yakkyou_sy = 5.0f; | |
| 827 | + Weapon[11].blazingmode = true; | |
| 828 | + Weapon[11].scopemode = 1; | |
| 829 | + Weapon[11].size = 7.8f; | |
| 830 | + Weapon[11].soundid = 4; | |
| 831 | + Weapon[11].soundvolume = 98; | |
| 832 | + Weapon[11].silencer = false; | |
| 833 | + Weapon[11].WeaponP = 0; | |
| 834 | + Weapon[11].ChangeWeapon = -1; | |
| 835 | + Weapon[11].burst = 1; | |
| 836 | + Weapon[12].name = "M249"; | |
| 837 | + Weapon[12].model = "./data/model/weapon/m249.x"; | |
| 838 | + Weapon[12].texture= "./data/model/weapon/m249.bmp"; | |
| 839 | + Weapon[12].attacks = 59; | |
| 840 | + Weapon[12].penetration = 1; | |
| 841 | + Weapon[12].blazings = 4; | |
| 842 | + Weapon[12].speed = 11; | |
| 843 | + Weapon[12].nbsmax = 100; | |
| 844 | + Weapon[12].reloads = 85; | |
| 845 | + Weapon[12].reaction = 7; | |
| 846 | + Weapon[12].ErrorRangeMIN = 4; | |
| 847 | + Weapon[12].ErrorRangeMAX = 22; | |
| 848 | + Weapon[12].mx = 8.0f; | |
| 849 | + Weapon[12].my = 12.0f; | |
| 850 | + Weapon[12].mz = 44.0f; | |
| 851 | + Weapon[12].flashx = 9.0f; | |
| 852 | + Weapon[12].flashy = 13.0f; | |
| 853 | + Weapon[12].flashz = 102.0f; | |
| 854 | + Weapon[12].yakkyou_px = 9.0f; | |
| 855 | + Weapon[12].yakkyou_py = 11.0f; | |
| 856 | + Weapon[12].yakkyou_pz = 45.0f; | |
| 857 | + Weapon[12].yakkyou_sx = 5.0f; | |
| 858 | + Weapon[12].yakkyou_sy = 4.0f; | |
| 859 | + Weapon[12].blazingmode = true; | |
| 860 | + Weapon[12].scopemode = 0; | |
| 861 | + Weapon[12].size = 7.5f; | |
| 862 | + Weapon[12].soundid = 3; | |
| 863 | + Weapon[12].soundvolume = 98; | |
| 864 | + Weapon[12].silencer = false; | |
| 865 | + Weapon[12].WeaponP = 0; | |
| 866 | + Weapon[12].ChangeWeapon = -1; | |
| 867 | + Weapon[12].burst = 1; | |
| 868 | + Weapon[13].name = "GRENADE"; // ID_WEAPON_GRENADE 定数を要設定 | |
| 869 | + Weapon[13].model = "./data/model/weapon/grenade.x"; | |
| 870 | + Weapon[13].texture= "./data/model/weapon/grenade.bmp"; | |
| 871 | + Weapon[13].attacks = 0; | |
| 872 | + Weapon[13].penetration = 0; | |
| 873 | + Weapon[13].blazings = 35; | |
| 874 | + Weapon[13].speed = 0; | |
| 875 | + Weapon[13].nbsmax = 1; | |
| 876 | + Weapon[13].reloads = 0; | |
| 877 | + Weapon[13].reaction = 0; | |
| 878 | + Weapon[13].ErrorRangeMIN = 6; | |
| 879 | + Weapon[13].ErrorRangeMAX = 20; | |
| 880 | + Weapon[13].mx = 1.0f; | |
| 881 | + Weapon[13].my = 6.0f; | |
| 882 | + Weapon[13].mz = 57.0f; | |
| 883 | + Weapon[13].flashx = 1.0f; | |
| 884 | + Weapon[13].flashy = 6.0f; | |
| 885 | + Weapon[13].flashz = 57.0f; | |
| 886 | + Weapon[13].yakkyou_px = 0.0f; | |
| 887 | + Weapon[13].yakkyou_py = 0.0f; | |
| 888 | + Weapon[13].yakkyou_pz = 0.0f; | |
| 889 | + Weapon[13].yakkyou_sx = 0.0f; | |
| 890 | + Weapon[13].yakkyou_sy = 0.0f; | |
| 891 | + Weapon[13].blazingmode = false; | |
| 892 | + Weapon[13].scopemode = 0; | |
| 893 | + Weapon[13].size = 8.0f; | |
| 894 | + Weapon[13].soundid = 0; | |
| 895 | + Weapon[13].soundvolume = 0; | |
| 896 | + Weapon[13].silencer = false; | |
| 897 | + Weapon[13].WeaponP = 1; | |
| 898 | + Weapon[13].ChangeWeapon = -1; | |
| 899 | + Weapon[13].burst = 1; | |
| 900 | + Weapon[14].name = "MP5SD"; | |
| 901 | + Weapon[14].model = "./data/model/weapon/mp5sd.x"; | |
| 902 | + Weapon[14].texture= "./data/model/weapon/mp5sd.bmp"; | |
| 903 | + Weapon[14].attacks = 37; | |
| 904 | + Weapon[14].penetration = 0; | |
| 905 | + Weapon[14].blazings = 4; | |
| 906 | + Weapon[14].speed = 9; | |
| 907 | + Weapon[14].nbsmax = 30; | |
| 908 | + Weapon[14].reloads = 50; | |
| 909 | + Weapon[14].reaction = 6; | |
| 910 | + Weapon[14].ErrorRangeMIN = 2; | |
| 911 | + Weapon[14].ErrorRangeMAX = 21; | |
| 912 | + Weapon[14].mx = 7.0f; | |
| 913 | + Weapon[14].my = 8.0f; | |
| 914 | + Weapon[14].mz = 35.0f; | |
| 915 | + Weapon[14].flashx = 8.0f; | |
| 916 | + Weapon[14].flashy = 12.0f; | |
| 917 | + Weapon[14].flashz = 84.0f; | |
| 918 | + Weapon[14].yakkyou_px = 8.0f; | |
| 919 | + Weapon[14].yakkyou_py = 12.0f; | |
| 920 | + Weapon[14].yakkyou_pz = 35.0f; | |
| 921 | + Weapon[14].yakkyou_sx = 5.0f; | |
| 922 | + Weapon[14].yakkyou_sy = 6.0f; | |
| 923 | + Weapon[14].blazingmode = true; | |
| 924 | + Weapon[14].scopemode = 0; | |
| 925 | + Weapon[14].size = 7.5f; | |
| 926 | + Weapon[14].soundid = 13; | |
| 927 | + Weapon[14].soundvolume = 84; | |
| 928 | + Weapon[14].silencer = true; | |
| 929 | + Weapon[14].WeaponP = 0; | |
| 930 | + Weapon[14].ChangeWeapon = -1; | |
| 931 | + Weapon[14].burst = 1; | |
| 932 | + Weapon[15].name = "CASE"; // ID_WEAPON_CASE 定数を要設定 | |
| 933 | + Weapon[15].model = "./data/model/weapon/case.x"; | |
| 934 | + Weapon[15].texture= "./data/model/weapon/case.bmp"; | |
| 935 | + Weapon[15].attacks = 0; | |
| 936 | + Weapon[15].penetration = 0; | |
| 937 | + Weapon[15].blazings = 0; | |
| 938 | + Weapon[15].speed = 0; | |
| 939 | + Weapon[15].nbsmax = 0; | |
| 940 | + Weapon[15].reloads = 0; | |
| 941 | + Weapon[15].reaction = 0; | |
| 942 | + Weapon[15].ErrorRangeMIN = 0; | |
| 943 | + Weapon[15].ErrorRangeMAX = 0; | |
| 944 | + Weapon[15].mx = 15.0f; | |
| 945 | + Weapon[15].my = -2.0f; | |
| 946 | + Weapon[15].mz = 35.0f; | |
| 947 | + Weapon[15].flashx = 0.0f; | |
| 948 | + Weapon[15].flashy = 0.0f; | |
| 949 | + Weapon[15].flashz = 0.0f; | |
| 950 | + Weapon[15].yakkyou_px = 0.0f; | |
| 951 | + Weapon[15].yakkyou_py = 0.0f; | |
| 952 | + Weapon[15].yakkyou_pz = 0.0f; | |
| 953 | + Weapon[15].yakkyou_sx = 0.0f; | |
| 954 | + Weapon[15].yakkyou_sy = 0.0f; | |
| 955 | + Weapon[15].blazingmode = true; | |
| 956 | + Weapon[15].scopemode = 0; | |
| 957 | + Weapon[15].size = 5.0f; | |
| 958 | + Weapon[15].soundid = 0; | |
| 959 | + Weapon[15].soundvolume = 0; | |
| 960 | + Weapon[15].silencer = false; | |
| 961 | + Weapon[15].WeaponP = 2; | |
| 962 | + Weapon[15].ChangeWeapon = -1; | |
| 963 | + Weapon[15].burst = 1; | |
| 964 | + Weapon[16].name = "GLOCK18 FULL"; | |
| 965 | + Weapon[16].model = "./data/model/weapon/glock18.x"; | |
| 966 | + Weapon[16].texture= "./data/model/weapon/glock18.bmp"; | |
| 967 | + Weapon[16].attacks = 38; | |
| 968 | + Weapon[16].penetration = 0; | |
| 969 | + Weapon[16].blazings = 3; | |
| 970 | + Weapon[16].speed = 9; | |
| 971 | + Weapon[16].nbsmax = 19; | |
| 972 | + Weapon[16].reloads = 38; | |
| 973 | + Weapon[16].reaction = 9; | |
| 974 | + Weapon[16].ErrorRangeMIN = 4; | |
| 975 | + Weapon[16].ErrorRangeMAX = 26; | |
| 976 | + Weapon[16].mx = 2.0f; | |
| 977 | + Weapon[16].my = 8.0f; | |
| 978 | + Weapon[16].mz = 56.0f; | |
| 979 | + Weapon[16].flashx = 2.0f; | |
| 980 | + Weapon[16].flashy = 13.0f; | |
| 981 | + Weapon[16].flashz = 70.0f; | |
| 982 | + Weapon[16].yakkyou_px = 2.0f; | |
| 983 | + Weapon[16].yakkyou_py = 14.0f; | |
| 984 | + Weapon[16].yakkyou_pz = 54.0f; | |
| 985 | + Weapon[16].yakkyou_sx = 4.0f; | |
| 986 | + Weapon[16].yakkyou_sy = 4.0f; | |
| 987 | + Weapon[16].blazingmode = true; | |
| 988 | + Weapon[16].scopemode = 0; | |
| 989 | + Weapon[16].size = 5.0f; | |
| 990 | + Weapon[16].soundid = 0; | |
| 991 | + Weapon[16].soundvolume = 90; | |
| 992 | + Weapon[16].silencer = false; | |
| 993 | + Weapon[16].WeaponP = 1; | |
| 994 | + Weapon[16].ChangeWeapon = 4; | |
| 995 | + Weapon[16].burst = 1; | |
| 996 | + Weapon[17].name = "M1911"; | |
| 997 | + Weapon[17].model = "./data/model/weapon/cg.x"; | |
| 998 | + Weapon[17].texture= "./data/model/weapon/cg.bmp"; | |
| 999 | + Weapon[17].attacks = 46; | |
| 1000 | + Weapon[17].penetration = 0; | |
| 1001 | + Weapon[17].blazings = 5; | |
| 1002 | + Weapon[17].speed = 9; | |
| 1003 | + Weapon[17].nbsmax = 7; | |
| 1004 | + Weapon[17].reloads = 35; | |
| 1005 | + Weapon[17].reaction = 11; | |
| 1006 | + Weapon[17].ErrorRangeMIN = 5; | |
| 1007 | + Weapon[17].ErrorRangeMAX = 26; | |
| 1008 | + Weapon[17].mx = 2.0f; | |
| 1009 | + Weapon[17].my = 7.0f; | |
| 1010 | + Weapon[17].mz = 61.0f; | |
| 1011 | + Weapon[17].flashx = 2.0f; | |
| 1012 | + Weapon[17].flashy = 14.0f; | |
| 1013 | + Weapon[17].flashz = 74.0f; | |
| 1014 | + Weapon[17].yakkyou_px = 2.0f; | |
| 1015 | + Weapon[17].yakkyou_py = 16.0f; | |
| 1016 | + Weapon[17].yakkyou_pz = 57.0f; | |
| 1017 | + Weapon[17].yakkyou_sx = 4.0f; | |
| 1018 | + Weapon[17].yakkyou_sy = 3.0f; | |
| 1019 | + Weapon[17].blazingmode = false; | |
| 1020 | + Weapon[17].scopemode = 0; | |
| 1021 | + Weapon[17].size = 6.8f; | |
| 1022 | + Weapon[17].soundid = 3; | |
| 1023 | + Weapon[17].soundvolume = 94; | |
| 1024 | + Weapon[17].silencer = false; | |
| 1025 | + Weapon[17].WeaponP = 1; | |
| 1026 | + Weapon[17].ChangeWeapon = -1; | |
| 1027 | + Weapon[17].burst = 1; | |
| 1028 | + Weapon[18].name = "GLOCK17"; | |
| 1029 | + Weapon[18].model = "./data/model/weapon/glock18.x"; | |
| 1030 | + Weapon[18].texture= "./data/model/weapon/glock17.bmp"; | |
| 1031 | + Weapon[18].attacks = 38; | |
| 1032 | + Weapon[18].penetration = 0; | |
| 1033 | + Weapon[18].blazings = 5; | |
| 1034 | + Weapon[18].speed = 9; | |
| 1035 | + Weapon[18].nbsmax = 17; | |
| 1036 | + Weapon[18].reloads = 37; | |
| 1037 | + Weapon[18].reaction = 9; | |
| 1038 | + Weapon[18].ErrorRangeMIN = 4; | |
| 1039 | + Weapon[18].ErrorRangeMAX = 26; | |
| 1040 | + Weapon[18].mx = 2.0f; | |
| 1041 | + Weapon[18].my = 8.0f; | |
| 1042 | + Weapon[18].mz = 56.0f; | |
| 1043 | + Weapon[18].flashx = 2.0f; | |
| 1044 | + Weapon[18].flashy = 13.0f; | |
| 1045 | + Weapon[18].flashz = 70.0f; | |
| 1046 | + Weapon[18].yakkyou_px = 2.0f; | |
| 1047 | + Weapon[18].yakkyou_py = 14.0f; | |
| 1048 | + Weapon[18].yakkyou_pz = 54.0f; | |
| 1049 | + Weapon[18].yakkyou_sx = 4.0f; | |
| 1050 | + Weapon[18].yakkyou_sy = 4.0f; | |
| 1051 | + Weapon[18].blazingmode = false; | |
| 1052 | + Weapon[18].scopemode = 0; | |
| 1053 | + Weapon[18].size = 5.0f; | |
| 1054 | + Weapon[18].soundid = 0; | |
| 1055 | + Weapon[18].soundvolume = 90; | |
| 1056 | + Weapon[18].silencer = false; | |
| 1057 | + Weapon[18].WeaponP = 1; | |
| 1058 | + Weapon[18].ChangeWeapon = -1; | |
| 1059 | + Weapon[18].burst = 1; | |
| 1060 | + Weapon[19].name = "M1"; | |
| 1061 | + Weapon[19].model = "./data/model/weapon/m1.x"; | |
| 1062 | + Weapon[19].texture= "./data/model/weapon/m1.bmp"; | |
| 1063 | + Weapon[19].attacks = 90; | |
| 1064 | + Weapon[19].penetration = 0; | |
| 1065 | + Weapon[19].blazings = 8; | |
| 1066 | + Weapon[19].speed = 9; | |
| 1067 | + Weapon[19].nbsmax = 7; | |
| 1068 | + Weapon[19].reloads = 100; | |
| 1069 | + Weapon[19].reaction = 18; | |
| 1070 | + Weapon[19].ErrorRangeMIN = 5; | |
| 1071 | + Weapon[19].ErrorRangeMAX = 23; | |
| 1072 | + Weapon[19].mx = 8.0f; | |
| 1073 | + Weapon[19].my = 7.0f; | |
| 1074 | + Weapon[19].mz = 45.0f; | |
| 1075 | + Weapon[19].flashx = 8.0f; | |
| 1076 | + Weapon[19].flashy = 11.0f; | |
| 1077 | + Weapon[19].flashz = 94.0f; | |
| 1078 | + Weapon[19].yakkyou_px = 8.0f; | |
| 1079 | + Weapon[19].yakkyou_py = 11.0f; | |
| 1080 | + Weapon[19].yakkyou_pz = 42.0f; | |
| 1081 | + Weapon[19].yakkyou_sx = 2.0f; | |
| 1082 | + Weapon[19].yakkyou_sy = 4.0f; | |
| 1083 | + Weapon[19].blazingmode = false; | |
| 1084 | + Weapon[19].scopemode = 0; | |
| 1085 | + Weapon[19].size = 7.7f; | |
| 1086 | + Weapon[19].soundid = 2; | |
| 1087 | + Weapon[19].soundvolume = 98; | |
| 1088 | + Weapon[19].silencer = false; | |
| 1089 | + Weapon[19].WeaponP = 0; | |
| 1090 | + Weapon[19].ChangeWeapon = -1; | |
| 1091 | + Weapon[19].burst = 6; | |
| 1092 | + Weapon[20].name = "FAMAS"; | |
| 1093 | + Weapon[20].model = "./data/model/weapon/famas.x"; | |
| 1094 | + Weapon[20].texture= "./data/model/weapon/famas.bmp"; | |
| 1095 | + Weapon[20].attacks = 55; | |
| 1096 | + Weapon[20].penetration = 1; | |
| 1097 | + Weapon[20].blazings = 3; | |
| 1098 | + Weapon[20].speed = 11; | |
| 1099 | + Weapon[20].nbsmax = 25; | |
| 1100 | + Weapon[20].reloads = 55; | |
| 1101 | + Weapon[20].reaction = 7; | |
| 1102 | + Weapon[20].ErrorRangeMIN = 3; | |
| 1103 | + Weapon[20].ErrorRangeMAX = 19; | |
| 1104 | + Weapon[20].mx = 9.0f; | |
| 1105 | + Weapon[20].my = 10.0f; | |
| 1106 | + Weapon[20].mz = 32.0f; | |
| 1107 | + Weapon[20].flashx = 9.0f; | |
| 1108 | + Weapon[20].flashy = 12.0f; | |
| 1109 | + Weapon[20].flashz = 70.0f; | |
| 1110 | + Weapon[20].yakkyou_px = 9.0f; | |
| 1111 | + Weapon[20].yakkyou_py = 11.0f; | |
| 1112 | + Weapon[20].yakkyou_pz = 14.0f; | |
| 1113 | + Weapon[20].yakkyou_sx = 3.0f; | |
| 1114 | + Weapon[20].yakkyou_sy = 5.0f; | |
| 1115 | + Weapon[20].blazingmode = true; | |
| 1116 | + Weapon[20].scopemode = 0; | |
| 1117 | + Weapon[20].size = 8.0f; | |
| 1118 | + Weapon[20].soundid = 4; | |
| 1119 | + Weapon[20].soundvolume = 96; | |
| 1120 | + Weapon[20].silencer = false; | |
| 1121 | + Weapon[20].WeaponP = 0; | |
| 1122 | + Weapon[20].ChangeWeapon = -1; | |
| 1123 | + Weapon[20].burst = 1; | |
| 1124 | + Weapon[21].name = "MK23"; | |
| 1125 | + Weapon[21].model = "./data/model/weapon/mk23.x"; | |
| 1126 | + Weapon[21].texture= "./data/model/weapon/mk23.bmp"; | |
| 1127 | + Weapon[21].attacks = 48; | |
| 1128 | + Weapon[21].penetration = 0; | |
| 1129 | + Weapon[21].blazings = 5; | |
| 1130 | + Weapon[21].speed = 9; | |
| 1131 | + Weapon[21].nbsmax = 12; | |
| 1132 | + Weapon[21].reloads = 42; | |
| 1133 | + Weapon[21].reaction = 10; | |
| 1134 | + Weapon[21].ErrorRangeMIN = 2; | |
| 1135 | + Weapon[21].ErrorRangeMAX = 26; | |
| 1136 | + Weapon[21].mx = 2.0f; | |
| 1137 | + Weapon[21].my = 11.0f; | |
| 1138 | + Weapon[21].mz = 60.0f; | |
| 1139 | + Weapon[21].flashx = 2.0f; | |
| 1140 | + Weapon[21].flashy = 15.0f; | |
| 1141 | + Weapon[21].flashz = 74.0f; | |
| 1142 | + Weapon[21].yakkyou_px = 1.0f; | |
| 1143 | + Weapon[21].yakkyou_py = 16.0f; | |
| 1144 | + Weapon[21].yakkyou_pz = 60.0f; | |
| 1145 | + Weapon[21].yakkyou_sx = 5.0f; | |
| 1146 | + Weapon[21].yakkyou_sy = 4.0f; | |
| 1147 | + Weapon[21].blazingmode = false; | |
| 1148 | + Weapon[21].scopemode = 0; | |
| 1149 | + Weapon[21].size = 5.0f; | |
| 1150 | + Weapon[21].soundid = 4; | |
| 1151 | + Weapon[21].soundvolume = 92; | |
| 1152 | + Weapon[21].silencer = false; | |
| 1153 | + Weapon[21].WeaponP = 1; | |
| 1154 | + Weapon[21].ChangeWeapon = -1; | |
| 1155 | + Weapon[21].burst = 1; | |
| 1156 | + Weapon[22].name = "MK23 SD"; | |
| 1157 | + Weapon[22].model = "./data/model/weapon/mk23sd.x"; | |
| 1158 | + Weapon[22].texture= "./data/model/weapon/mk23.bmp"; | |
| 1159 | + Weapon[22].attacks = 39; | |
| 1160 | + Weapon[22].penetration = 0; | |
| 1161 | + Weapon[22].blazings = 5; | |
| 1162 | + Weapon[22].speed = 9; | |
| 1163 | + Weapon[22].nbsmax = 12; | |
| 1164 | + Weapon[22].reloads = 43; | |
| 1165 | + Weapon[22].reaction = 9; | |
| 1166 | + Weapon[22].ErrorRangeMIN = 3; | |
| 1167 | + Weapon[22].ErrorRangeMAX = 26; | |
| 1168 | + Weapon[22].mx = 2.0f; | |
| 1169 | + Weapon[22].my = 11.0f; | |
| 1170 | + Weapon[22].mz = 60.0f; | |
| 1171 | + Weapon[22].flashx = 2.0f; | |
| 1172 | + Weapon[22].flashy = 15.0f; | |
| 1173 | + Weapon[22].flashz = 96.0f; | |
| 1174 | + Weapon[22].yakkyou_px = 1.0f; | |
| 1175 | + Weapon[22].yakkyou_py = 16.0f; | |
| 1176 | + Weapon[22].yakkyou_pz = 60.0f; | |
| 1177 | + Weapon[22].yakkyou_sx = 5.0f; | |
| 1178 | + Weapon[22].yakkyou_sy = 4.0f; | |
| 1179 | + Weapon[22].blazingmode = false; | |
| 1180 | + Weapon[22].scopemode = 0; | |
| 1181 | + Weapon[22].size = 5.0f; | |
| 1182 | + Weapon[22].soundid = 13; | |
| 1183 | + Weapon[22].soundvolume = 86; | |
| 1184 | + Weapon[22].silencer = true; | |
| 1185 | + Weapon[22].WeaponP = 1; | |
| 1186 | + Weapon[22].ChangeWeapon = -1; | |
| 1187 | + Weapon[22].burst = 1; | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + //缶 | |
| 1191 | + SmallObject[0].model = "./data/article/can.x"; | |
| 1192 | + SmallObject[0].texture = "./data/article/can.bmp"; | |
| 1193 | + SmallObject[0].decide = 10; | |
| 1194 | + SmallObject[0].hp = 6; | |
| 1195 | + SmallObject[0].sound = 0; | |
| 1196 | + SmallObject[0].jump = 10; | |
| 1197 | + //パソコン | |
| 1198 | + SmallObject[1].model = "./data/article/pc.x"; | |
| 1199 | + SmallObject[1].texture = "./data/article/pc.bmp"; | |
| 1200 | + SmallObject[1].decide = 29; | |
| 1201 | + SmallObject[1].hp = 60; | |
| 1202 | + SmallObject[1].sound = 0; | |
| 1203 | + SmallObject[1].jump = 5; | |
| 1204 | + //パソコン キーボード上 | |
| 1205 | + SmallObject[2].model = "./data/article/pc2.x"; | |
| 1206 | + SmallObject[2].texture = "./data/article/pc.bmp"; | |
| 1207 | + SmallObject[2].decide = 29; | |
| 1208 | + SmallObject[2].hp = 60; | |
| 1209 | + SmallObject[2].sound = 0; | |
| 1210 | + SmallObject[2].jump = 5; | |
| 1211 | + //パソコン 本体逆 | |
| 1212 | + SmallObject[3].model = "./data/article/pc3.x"; | |
| 1213 | + SmallObject[3].texture = "./data/article/pc.bmp"; | |
| 1214 | + SmallObject[3].decide = 29; | |
| 1215 | + SmallObject[3].hp = 60; | |
| 1216 | + SmallObject[3].sound = 0; | |
| 1217 | + SmallObject[3].jump = 5; | |
| 1218 | + //パソコン ワイド | |
| 1219 | + SmallObject[4].model = "./data/article/pc_w.x"; | |
| 1220 | + SmallObject[4].texture = "./data/article/pc.bmp"; | |
| 1221 | + SmallObject[4].decide = 29; | |
| 1222 | + SmallObject[4].hp = 60; | |
| 1223 | + SmallObject[4].sound = 0; | |
| 1224 | + SmallObject[4].jump = 5; | |
| 1225 | + //パソコン ワイド キーボード上 | |
| 1226 | + SmallObject[5].model = "./data/article/pc2_w.x"; | |
| 1227 | + SmallObject[5].texture = "./data/article/pc.bmp"; | |
| 1228 | + SmallObject[5].decide = 29; | |
| 1229 | + SmallObject[5].hp = 60; | |
| 1230 | + SmallObject[5].sound = 0; | |
| 1231 | + SmallObject[5].jump = 5; | |
| 1232 | + //パソコン ワイド 本体逆 | |
| 1233 | + SmallObject[6].model = "./data/article/pc3_w.x"; | |
| 1234 | + SmallObject[6].texture = "./data/article/pc.bmp"; | |
| 1235 | + SmallObject[6].decide = 29; | |
| 1236 | + SmallObject[6].hp = 60; | |
| 1237 | + SmallObject[6].sound = 0; | |
| 1238 | + SmallObject[6].jump = 5; | |
| 1239 | + //椅子 | |
| 1240 | + SmallObject[7].model = "./data/article/isu.x"; | |
| 1241 | + SmallObject[7].texture = "./data/article/isu.bmp"; | |
| 1242 | + SmallObject[7].decide = 56; | |
| 1243 | + SmallObject[7].hp = 50; | |
| 1244 | + SmallObject[7].sound = 1; | |
| 1245 | + SmallObject[7].jump = 6; | |
| 1246 | + //ダンボール | |
| 1247 | + SmallObject[8].model = "./data/article/dan.x"; | |
| 1248 | + SmallObject[8].texture = "./data/article/dan.bmp"; | |
| 1249 | + SmallObject[8].decide = 28; | |
| 1250 | + SmallObject[8].hp = 35; | |
| 1251 | + SmallObject[8].sound = 1; | |
| 1252 | + SmallObject[8].jump = 8; | |
| 1253 | + //パソコン 起動中 | |
| 1254 | + SmallObject[9].model = "./data/article/pc.x"; | |
| 1255 | + SmallObject[9].texture = "./data/article/pc_sw.bmp"; | |
| 1256 | + SmallObject[9].decide = 29; | |
| 1257 | + SmallObject[9].hp = 60; | |
| 1258 | + SmallObject[9].sound = 0; | |
| 1259 | + SmallObject[9].jump = 5; | |
| 1260 | + //パソコン 起動中 暗 | |
| 1261 | + SmallObject[10].model = "./data/article/pc.x"; | |
| 1262 | + SmallObject[10].texture = "./data/article/pc_d.bmp"; | |
| 1263 | + SmallObject[10].decide = 29; | |
| 1264 | + SmallObject[10].hp = 60; | |
| 1265 | + SmallObject[10].sound = 0; | |
| 1266 | + SmallObject[10].jump = 5; | |
| 1267 | + //パイロン | |
| 1268 | + SmallObject[11].model = "./data/article/cone.x"; | |
| 1269 | + SmallObject[11].texture = "./data/article/cone.bmp"; | |
| 1270 | + SmallObject[11].decide = 35; | |
| 1271 | + SmallObject[11].hp = 30; | |
| 1272 | + SmallObject[11].sound = 1; | |
| 1273 | + SmallObject[11].jump = 7; | |
| 1274 | + | |
| 1275 | + | |
| 1276 | + missionname[0] = "TRAINING YARD"; | |
| 1277 | + missionfullname[0] = "TRAINING YARD training"; | |
| 1278 | + missiondirectory[0] = "data\\map0\\"; | |
| 1279 | + missiontxt[0] = "tr"; | |
| 1280 | + missionname[1] = "UNDERGROUND_EXT"; | |
| 1281 | + missionfullname[1] = "UNDERGROUND extermination"; | |
| 1282 | + missiondirectory[1] = "data\\map5\\"; | |
| 1283 | + missiontxt[1] = "ext"; | |
| 1284 | + missionname[2] = "BUILDING_EXT"; | |
| 1285 | + missionfullname[2] = "BUILDING extermination"; | |
| 1286 | + missiondirectory[2] = "data\\map1\\"; | |
| 1287 | + missiontxt[2] = "ext"; | |
| 1288 | + missionname[3] = "SNOW BASE_EXT"; | |
| 1289 | + missionfullname[3] = "SNOW BASE extermination"; | |
| 1290 | + missiondirectory[3] = "data\\map2\\"; | |
| 1291 | + missiontxt[3] = "ext"; | |
| 1292 | + missionname[4] = "MBASE_EXT"; | |
| 1293 | + missionfullname[4] = "MILITARY BASE extermination"; | |
| 1294 | + missiondirectory[4] = "data\\map4\\"; | |
| 1295 | + missiontxt[4] = "ext"; | |
| 1296 | + missionname[5] = "WAREHOUSE_EXT"; | |
| 1297 | + missionfullname[5] = "WAREHOUSE AREA extermination"; | |
| 1298 | + missiondirectory[5] = "data\\map7\\"; | |
| 1299 | + missiontxt[5] = "ext"; | |
| 1300 | + missionname[6] = "DUEL_EXT"; | |
| 1301 | + missionfullname[6] = "DUEL extermination"; | |
| 1302 | + missiondirectory[6] = "data\\map9\\"; | |
| 1303 | + missiontxt[6] = "ext"; | |
| 1304 | + missionname[7] = "STATION_EXT"; | |
| 1305 | + missionfullname[7] = "SUBWAY STATION extermination"; | |
| 1306 | + missiondirectory[7] = "data\\map6\\"; | |
| 1307 | + missiontxt[7] = "ext"; | |
| 1308 | + missionname[8] = "MAZE_EXT"; | |
| 1309 | + missionfullname[8] = "MAZE extermination"; | |
| 1310 | + missiondirectory[8] = "data\\map13\\"; | |
| 1311 | + missiontxt[8] = "ext"; | |
| 1312 | + missionname[9] = "RUINS_EXT"; | |
| 1313 | + missionfullname[9] = "RUINS extermination"; | |
| 1314 | + missiondirectory[9] = "data\\map14\\"; | |
| 1315 | + missiontxt[9] = "ext"; | |
| 1316 | + missionname[10] = "URBAN_EXT"; | |
| 1317 | + missionfullname[10] = "URBAN extermination"; | |
| 1318 | + missiondirectory[10]= "data\\map8\\"; | |
| 1319 | + missiontxt[10] = "ext"; | |
| 1320 | + missionname[11] = "UNDERGROUND_EXT2"; | |
| 1321 | + missionfullname[11] = "UNDERGROUND extermination2"; | |
| 1322 | + missiondirectory[11]= "data\\map5\\"; | |
| 1323 | + missiontxt[11] = "ext2"; | |
| 1324 | + missionname[12] = "TUNNEL_EXT"; | |
| 1325 | + missionfullname[12] = "TUNNEL extermination"; | |
| 1326 | + missiondirectory[12]= "data\\map12\\"; | |
| 1327 | + missiontxt[12] = "ext"; | |
| 1328 | + missionname[13] = "URBAN_DEF"; | |
| 1329 | + missionfullname[13] = "URBAN defend target"; | |
| 1330 | + missiondirectory[13]= "data\\map8\\"; | |
| 1331 | + missiontxt[13] = "def"; | |
| 1332 | + missionname[14] = "DTOWN_EXT"; | |
| 1333 | + missionfullname[14] = "DESERT TOWN extermination"; | |
| 1334 | + missiondirectory[14]= "data\\map3\\"; | |
| 1335 | + missiontxt[14] = "ext"; | |
| 1336 | + missionname[15] = "URBAN_DEF2"; | |
| 1337 | + missionfullname[15] = "URBAN defend target2"; | |
| 1338 | + missiondirectory[15]= "data\\map8\\"; | |
| 1339 | + missiontxt[15] = "def2"; | |
| 1340 | + missionname[16] = "WAREHOUSE_KT"; | |
| 1341 | + missionfullname[16] = "WAREHOUSE AREA kill the target"; | |
| 1342 | + missiondirectory[16]= "data\\map7\\"; | |
| 1343 | + missiontxt[16] = "kt"; | |
| 1344 | + missionname[17] = "RUINS_RE"; | |
| 1345 | + missionfullname[17] = "RUINS release"; | |
| 1346 | + missiondirectory[17]= "data\\map14\\"; | |
| 1347 | + missiontxt[17] = "re"; | |
| 1348 | + missionname[18] = "RELIC_CAP"; | |
| 1349 | + missionfullname[18] = "RELIC capture"; | |
| 1350 | + missiondirectory[18]= "data\\map16\\"; | |
| 1351 | + missiontxt[18] = "cap"; | |
| 1352 | + missionname[19] = "MBASE_DE"; | |
| 1353 | + missionfullname[19] = "MILITARY BASE destroy"; | |
| 1354 | + missiondirectory[19]= "data\\map4\\"; | |
| 1355 | + missiontxt[19] = "de"; | |
| 1356 | + missionname[20] = "RUINS_CAP"; | |
| 1357 | + missionfullname[20] = "RUINS capture"; | |
| 1358 | + missiondirectory[20]= "data\\map14\\"; | |
| 1359 | + missiontxt[20] = "cap"; | |
| 1360 | + missionname[21] = "DTOWN_KT"; | |
| 1361 | + missionfullname[21] = "DESERT TOWN kill the target"; | |
| 1362 | + missiondirectory[21]= "data\\map3\\"; | |
| 1363 | + missiontxt[21] = "kt"; | |
| 1364 | + missionname[22] = "SNOW BASE_RE"; | |
| 1365 | + missionfullname[22] = "SNOW BASE release"; | |
| 1366 | + missiondirectory[22]= "data\\map2\\"; | |
| 1367 | + missiontxt[22] = "re"; | |
| 1368 | + missionname[23] = "UNDERGROUND_DEF"; | |
| 1369 | + missionfullname[23] = "UNDERGROUND defend target"; | |
| 1370 | + missiondirectory[23]= "data\\map5\\"; | |
| 1371 | + missiontxt[23] = "def"; | |
| 1372 | + missionname[24] = "TUNNEL_EXT2"; | |
| 1373 | + missionfullname[24] = "TUNNEL extermination2"; | |
| 1374 | + missiondirectory[24]= "data\\map12\\"; | |
| 1375 | + missiontxt[24] = "ext2"; | |
| 1376 | + missionname[25] = "RELIC_DEF"; | |
| 1377 | + missionfullname[25] = "RELIC defend target"; | |
| 1378 | + missiondirectory[25]= "data\\map16\\"; | |
| 1379 | + missiontxt[25] = "def"; | |
| 1380 | + missionname[26] = "URBAN_KT"; | |
| 1381 | + missionfullname[26] = "URBAN kill the target"; | |
| 1382 | + missiondirectory[26]= "data\\map8\\"; | |
| 1383 | + missiontxt[26] = "kt"; | |
| 1384 | + missionname[27] = "ALLEY_KT"; | |
| 1385 | + missionfullname[27] = "ALLEY kill the target"; | |
| 1386 | + missiondirectory[27]= "data\\map10\\"; | |
| 1387 | + missiontxt[27] = "kt"; | |
| 1388 | + missionname[28] = "STATION_KT"; | |
| 1389 | + missionfullname[28] = "SUBWAY STATION kill the target"; | |
| 1390 | + missiondirectory[28]= "data\\map6\\"; | |
| 1391 | + missiontxt[28] = "kt"; | |
| 1392 | + missionname[29] = "WAREHOUSE_DEF"; | |
| 1393 | + missionfullname[29] = "WAREHOUSE AREA defend target"; | |
| 1394 | + missiondirectory[29]= "data\\map7\\"; | |
| 1395 | + missiontxt[29] = "def"; | |
| 1396 | + missionname[30] = "URBAN_KT2"; | |
| 1397 | + missionfullname[30] = "URBAN kill the target2"; | |
| 1398 | + missiondirectory[30]= "data\\map8\\"; | |
| 1399 | + missiontxt[30] = "kt2"; | |
| 1400 | + missionname[31] = "OFFICE_DEF"; | |
| 1401 | + missionfullname[31] = "OFFICE defend target"; | |
| 1402 | + missiondirectory[31]= "data\\map15\\"; | |
| 1403 | + missiontxt[31] = "def"; | |
| 1404 | + missionname[32] = "URBAN_CAP"; | |
| 1405 | + missionfullname[32] = "URBAN capture"; | |
| 1406 | + missiondirectory[32]= "data\\map8\\"; | |
| 1407 | + missiontxt[32] = "cap"; | |
| 1408 | + missionname[33] = "ALLEY_EXT"; | |
| 1409 | + missionfullname[33] = "ALLEY extermination"; | |
| 1410 | + missiondirectory[33]= "data\\map10\\"; | |
| 1411 | + missiontxt[33] = "ext"; | |
| 1412 | + missionname[34] = "TUNNEL_ESC"; | |
| 1413 | + missionfullname[34] = "TUNNEL escape"; | |
| 1414 | + missiondirectory[34]= "data\\map12\\"; | |
| 1415 | + missiontxt[34] = "esc"; | |
| 1416 | + missionname[35] = "MAZE_CAP"; | |
| 1417 | + missionfullname[35] = "MAZE capture"; | |
| 1418 | + missiondirectory[35]= "data\\map13\\"; | |
| 1419 | + missiontxt[35] = "cap"; | |
| 1420 | + missionname[36] = "WAREHOUSE_DEF2"; | |
| 1421 | + missionfullname[36] = "WAREHOUSE AREA defend target2"; | |
| 1422 | + missiondirectory[36]= "data\\map7\\"; | |
| 1423 | + missiontxt[36] = "def2"; | |
| 1424 | + missionname[37] = "RUINS_DE"; | |
| 1425 | + missionfullname[37] = "RUINS destroy"; | |
| 1426 | + missiondirectory[37]= "data\\map14\\"; | |
| 1427 | + missiontxt[37] = "de"; | |
| 1428 | + missionname[38] = "URBAN_KT3"; | |
| 1429 | + missionfullname[38] = "URBAN kill the target3"; | |
| 1430 | + missiondirectory[38]= "data\\map8\\"; | |
| 1431 | + missiontxt[38] = "kt3"; | |
| 1432 | + missionname[39] = "DUEL_EXT2"; | |
| 1433 | + missionfullname[39] = "DUEL extermination2"; | |
| 1434 | + missiondirectory[39]= "data\\map9\\"; | |
| 1435 | + missiontxt[39] = "ext2"; | |
| 1436 | + missionname[40] = "RELIC_EXT"; | |
| 1437 | + missionfullname[40] = "RELIC extermination"; | |
| 1438 | + missiondirectory[40]= "data\\map16\\"; | |
| 1439 | + missiontxt[40] = "ext"; | |
| 1440 | + missionname[41] = "SNOW BASE_DEF"; | |
| 1441 | + missionfullname[41] = "SNOW BASE defend target"; | |
| 1442 | + missiondirectory[41]= "data\\map2\\"; | |
| 1443 | + missiontxt[41] = "def"; | |
| 1444 | + missionname[42] = "BUILDING_KT"; | |
| 1445 | + missionfullname[42] = "BUILDING kill the target"; | |
| 1446 | + missiondirectory[42]= "data\\map1\\"; | |
| 1447 | + missiontxt[42] = "kt"; | |
| 1448 | + missionname[43] = "MAZE_ESC"; | |
| 1449 | + missionfullname[43] = "MAZE escape"; | |
| 1450 | + missiondirectory[43]= "data\\map13\\"; | |
| 1451 | + missiontxt[43] = "esc"; | |
| 1452 | + missionname[44] = "ALLEY_EXT2"; | |
| 1453 | + missionfullname[44] = "ALLEY extermination2"; | |
| 1454 | + missiondirectory[44]= "data\\map10\\"; | |
| 1455 | + missiontxt[44] = "ext2"; | |
| 1456 | + missionname[45] = "MBASE_ESC"; | |
| 1457 | + missionfullname[45] = "MILITARY BASE escape"; | |
| 1458 | + missiondirectory[45]= "data\\map4\\"; | |
| 1459 | + missiontxt[45] = "esc"; | |
| 1460 | + missionname[46] = "DTOWN_DEF"; | |
| 1461 | + missionfullname[46] = "DESERT TOWN defend target"; | |
| 1462 | + missiondirectory[46]= "data\\map3\\"; | |
| 1463 | + missiontxt[46] = "def"; | |
| 1464 | + missionname[47] = "OFFICE_KT"; | |
| 1465 | + missionfullname[47] = "OFFICE kill the target"; | |
| 1466 | + missiondirectory[47]= "data\\map15\\"; | |
| 1467 | + missiontxt[47] = "kt"; | |
| 1468 | + missionname[48] = "BUILDING_DEF"; | |
| 1469 | + missionfullname[48] = "BUILDING defend target"; | |
| 1470 | + missiondirectory[48]= "data\\map1\\"; | |
| 1471 | + missiontxt[48] = "def"; | |
| 1472 | + missionname[49] = "OFFICE_KT2"; | |
| 1473 | + missionfullname[49] = "OFFICE kill the target2"; | |
| 1474 | + missiondirectory[49]= "data\\map15\\"; | |
| 1475 | + missiontxt[49] = "kt2"; | |
| 1476 | + missionname[50] = "MBASE_CAP"; | |
| 1477 | + missionfullname[50] = "MILITARY BASE capture"; | |
| 1478 | + missiondirectory[50]= "data\\map4\\"; | |
| 1479 | + missiontxt[50] = "cap"; | |
| 1480 | + missionname[51] = "TUNNEL_KT"; | |
| 1481 | + missionfullname[51] = "TUNNEL kill the target"; | |
| 1482 | + missiondirectory[51]= "data\\map12\\"; | |
| 1483 | + missiontxt[51] = "kt"; | |
| 1484 | + missionname[52] = "OFFICE_RE"; | |
| 1485 | + missionfullname[52] = "OFFICE release"; | |
| 1486 | + missiondirectory[52]= "data\\map15\\"; | |
| 1487 | + missiontxt[52] = "re"; | |
| 1488 | + missionname[53] = "URBAN_KT4"; | |
| 1489 | + missionfullname[53] = "URBAN kill the target4"; | |
| 1490 | + missiondirectory[53]= "data\\map8\\"; | |
| 1491 | + missiontxt[53] = "kt4"; | |
| 1492 | + missionname[54] = "UNDERGROUND_EXT3"; | |
| 1493 | + missionfullname[54] = "UNDERGROUND extermination3"; | |
| 1494 | + missiondirectory[54]= "data\\map5\\"; | |
| 1495 | + missiontxt[54] = "ext3"; | |
| 1496 | + missionname[55] = "SCHOOL_EXT"; | |
| 1497 | + missionfullname[55] = "SCHOOL extermination"; | |
| 1498 | + missiondirectory[55]= "data\\map11\\"; | |
| 1499 | + missiontxt[55] = "ext"; | |
| 1500 | + missionname[56] = "SCHOOL_EXT2"; | |
| 1501 | + missionfullname[56] = "SCHOOL extermination2"; | |
| 1502 | + missiondirectory[56]= "data\\map11\\"; | |
| 1503 | + missiontxt[56] = "ext2"; | |
| 1504 | + missionname[57] = "SCHOOL_DE"; | |
| 1505 | + missionfullname[57] = "SCHOOL destroy"; | |
| 1506 | + missiondirectory[57]= "data\\map11\\"; | |
| 1507 | + missiontxt[57] = "de"; | |
| 1508 | + | |
| 1509 | + | |
| 1510 | + AIlevel[0].aiming = 1; | |
| 1511 | + AIlevel[0].attack = 99; | |
| 1512 | + AIlevel[0].search = 1; | |
| 1513 | + AIlevel[0].limitserror = 0; | |
| 1514 | + AIlevel[1].aiming = 1; | |
| 1515 | + AIlevel[1].attack = 18; | |
| 1516 | + AIlevel[1].search = 2; | |
| 1517 | + AIlevel[1].limitserror = 2; | |
| 1518 | + AIlevel[2].aiming = 2; | |
| 1519 | + AIlevel[2].attack = 16; | |
| 1520 | + AIlevel[2].search = 3; | |
| 1521 | + AIlevel[2].limitserror = 0; | |
| 1522 | + AIlevel[3].aiming = 3; | |
| 1523 | + AIlevel[3].attack = 14; | |
| 1524 | + AIlevel[3].search = 4; | |
| 1525 | + AIlevel[3].limitserror = 255; | |
| 1526 | + AIlevel[4].aiming = 4; | |
| 1527 | + AIlevel[4].attack = 12; | |
| 1528 | + AIlevel[4].search = 5; | |
| 1529 | + AIlevel[4].limitserror = 254; | |
| 1530 | + AIlevel[5].aiming = 5; | |
| 1531 | + AIlevel[5].attack = 10; | |
| 1532 | + AIlevel[5].search = 6; | |
| 1533 | + AIlevel[5].limitserror = 253; | |
| 1534 | +} | |
| 1535 | + | |
| 1536 | +//! 人の設定を取得 | |
| 1537 | +//! @param id 番号 | |
| 1538 | +//! @param out_data 受け取るHumanParameter型ポインタ | |
| 1539 | +//! @return 成功:0 失敗:1 | |
| 1540 | +int ParameterInfo::GetHuman(int id, HumanParameter *out_data) | |
| 1541 | +{ | |
| 1542 | + if( (id < 0)||((TOTAL_PARAMETERINFO_HUMAN -1) < id ) ){ return 1; } | |
| 1543 | + | |
| 1544 | + *out_data = Human[id]; | |
| 1545 | + return 0; | |
| 1546 | +} | |
| 1547 | + | |
| 1548 | +//! 人のテクスチャファイルのパスを取得 | |
| 1549 | +//! @param id 番号 | |
| 1550 | +//! @param *out_str 受け取るポインタ | |
| 1551 | +//! @return 成功:0 失敗:1 | |
| 1552 | +int ParameterInfo::GetHumanTexturePath(int id, char *out_str) | |
| 1553 | +{ | |
| 1554 | + if( (id < 0)||((TOTAL_HUMANTEXTURE -1) < id ) ){ return 1; } | |
| 1555 | + | |
| 1556 | + strcpy(out_str, HumanTexturePath[id]); | |
| 1557 | + return 0; | |
| 1558 | +} | |
| 1559 | + | |
| 1560 | +//! 武器の設定を取得 | |
| 1561 | +//! @param id 番号 | |
| 1562 | +//! @param out_data 受け取るWeaponParameter型ポインタ | |
| 1563 | +//! @return 成功:0 失敗:1 | |
| 1564 | +int ParameterInfo::GetWeapon(int id, WeaponParameter *out_data) | |
| 1565 | +{ | |
| 1566 | + if( (id < 0)||((TOTAL_PARAMETERINFO_WEAPON -1) < id ) ){ return 1; } | |
| 1567 | + | |
| 1568 | + *out_data = Weapon[id]; | |
| 1569 | + return 0; | |
| 1570 | +} | |
| 1571 | + | |
| 1572 | +//! 小物の設定を取得 | |
| 1573 | +//! @param id 番号 | |
| 1574 | +//! @param out_data 受け取るSmallObjectParameter型ポインタ | |
| 1575 | +//! @return 成功:0 失敗:1 | |
| 1576 | +int ParameterInfo::GetSmallObject(int id, SmallObjectParameter *out_data) | |
| 1577 | +{ | |
| 1578 | + if( (id < 0)||((TOTAL_PARAMETERINFO_SMALLOBJECT -1) < id ) ){ return 1; } | |
| 1579 | + | |
| 1580 | + *out_data = SmallObject[id]; | |
| 1581 | + return 0; | |
| 1582 | +} | |
| 1583 | + | |
| 1584 | +//! 標準ミッションを取得 | |
| 1585 | +//! @param id 番号 | |
| 1586 | +//! @param name ミッション識別名を受け取るポインタ (NULL可) | |
| 1587 | +//! @param fullname ミッション正式名称を受け取るポインタ (NULL可) | |
| 1588 | +//! @param directory データの格納先を受け取るポインタ (NULL可) | |
| 1589 | +//! @param txt ファイル名を受け取るポインタ (NULL可) | |
| 1590 | +//! @return 成功:0 失敗:1 | |
| 1591 | +//! @note ファイル名・・・ミッション情報ファイル(.txt)とポイントデータファイル(.pd1)に使われる名前 | |
| 1592 | +int ParameterInfo::GetOfficialMission(int id, char *name, char *fullname, char* directory, char *txt) | |
| 1593 | +{ | |
| 1594 | + if( (id < 0)||((TOTAL_OFFICIALMISSION -1) < id ) ){ return 1; } | |
| 1595 | + | |
| 1596 | + if( name != NULL ){ strcpy(name, missionname[id]); } | |
| 1597 | + if( fullname != NULL ){ strcpy(fullname, missionfullname[id]); } | |
| 1598 | + if( directory != NULL ){ strcpy(directory, missiondirectory[id]); } | |
| 1599 | + if( txt != NULL ){ strcpy(txt, missiontxt[id]); } | |
| 1600 | + return 0; | |
| 1601 | +} | |
| 1602 | + | |
| 1603 | +//! AIレベルの設定(性能値)を取得 | |
| 1604 | +//! @param level AIレベル | |
| 1605 | +//! @param out_AIlevel 受け取るAIParameter型ポインタのポインタ(2重ポインタ) | |
| 1606 | +//! @return 成功:0 失敗:1 | |
| 1607 | +int ParameterInfo::GetAIlevel(int level, AIParameter **out_AIlevel) | |
| 1608 | +{ | |
| 1609 | + if( (level < 0)||((TOTAL_PARAMETERINFO_AILEVEL -1) < level ) ){ return 1; } | |
| 1610 | + *out_AIlevel = &(AIlevel[level]); | |
| 1611 | + return 0; | |
| 1612 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,54 @@ | ||
| 1 | +//! @file doxygen.h | |
| 2 | +//! @brief Doxygen設定ファイル | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef DOXYGEN_H | |
| 33 | +#define DOXYGEN_H | |
| 34 | + | |
| 35 | +/*! | |
| 36 | +@mainpage | |
| 37 | + | |
| 38 | +<p> | |
| 39 | +<b>OpenXOPS</b>は、X operations(略称:XOPS)との互換性を目指しリメイクした、オープンソースのFPSゲームです。 | |
| 40 | +</p> | |
| 41 | + | |
| 42 | +<br> | |
| 43 | + | |
| 44 | +@section website 公式サイト | |
| 45 | +<p> | |
| 46 | +本プロジェクトに関する基本的な情報は、以下のサイトから確認してください。 | |
| 47 | +</p> | |
| 48 | +<p> | |
| 49 | +<b>OpenXOPS公式サイト</b><br> | |
| 50 | + <a href="http://openxops.net/" target="blank">http://openxops.net/</a><br> | |
| 51 | +</p> | |
| 52 | +*/ | |
| 53 | + | |
| 54 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,192 @@ | ||
| 1 | +//! @file gamemain.h | |
| 2 | +//! @brief ゲームメイン処理のサンプルコードのヘッダー | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef GAMEMAIN_H | |
| 33 | +#define GAMEMAIN_H | |
| 34 | + | |
| 35 | +#define MAINMENU_X 280 //!< メニューの表示 X座標(左上基準) | |
| 36 | +#define MAINMENU_Y 140 //!< メニューの表示 Y座標(〃) | |
| 37 | +#define TOTAL_MENUITEMS 8 //!< メニュー1画面に表示するミッション数 | |
| 38 | +#define MAINMENU_H (TOTAL_MENUITEMS+2)*30 + 25 //!< メニューの表示サイズ・高さ | |
| 39 | + | |
| 40 | +#define HUDA_WEAPON_POSX (SCREEN_WIDTH - 255) //!< 武器情報を表示する領域・X座標 | |
| 41 | +#define HUDA_WEAPON_POSY (SCREEN_HEIGTH - 98) //!< 武器情報を表示する領域・Y座標 | |
| 42 | +#define HUDA_WEAPON_SIZEW 8 //!< 武器情報を表示する領域・横サイズ(32ピクセルの配置個数) | |
| 43 | +#define HUDA_WEAPON_SIZEH 3 //!< 武器情報を表示する領域・縦サイズ(32ピクセルの配置個数) | |
| 44 | + | |
| 45 | +#define VIEW_HEIGHT 19.0f //!< 視点の高さ | |
| 46 | +#define VIEWANGLE_NORMAL ((float)M_PI/180*65) //!< 視野角 標準 | |
| 47 | +#define VIEWANGLE_SCOPE_1 ((float)M_PI/180*30) //!< 視野角 スコープ1 | |
| 48 | +#define VIEWANGLE_SCOPE_2 ((float)M_PI/180*15) //!< 視野角 スコープ2 | |
| 49 | + | |
| 50 | +#define TOTAL_EVENTLINE 3 //!< イベントのライン数 | |
| 51 | +#define TOTAL_EVENTENTRYPOINT_0 -100 //!< ライン 0 の開始認識番号 | |
| 52 | +#define TOTAL_EVENTENTRYPOINT_1 -110 //!< ライン 1 の開始認識番号 | |
| 53 | +#define TOTAL_EVENTENTRYPOINT_2 -120 //!< ライン 2 の開始認識番号 | |
| 54 | + | |
| 55 | +#define TOTAL_EVENTENT_SHOWMESCNT (5*(int)GAMEFPS) //!< イベントメッセージを表示するカウント数 | |
| 56 | + | |
| 57 | +#ifndef H_LAYERLEVEL | |
| 58 | + #define H_LAYERLEVEL 3 //!< Select include file. | |
| 59 | +#endif | |
| 60 | +#include "main.h" | |
| 61 | + | |
| 62 | +int InitGame(HWND hWnd); | |
| 63 | + | |
| 64 | +//! ゲームの状態を受け渡しする構造体 | |
| 65 | +struct GameInfo{ | |
| 66 | + bool selectaddon; //!< addonを選択 | |
| 67 | + int selectmission_id; //!< 選択されたミッション | |
| 68 | + bool missioncomplete; //!< ミッション完了 | |
| 69 | + unsigned int framecnt; //!< フレーム数 | |
| 70 | + int fire; //!< 射撃回数 | |
| 71 | + int ontarget; //!< 命中数 | |
| 72 | + int kill; //!< 倒した敵の数 | |
| 73 | + int headshot; //!< 敵の頭部に命中した数 | |
| 74 | +}; | |
| 75 | + | |
| 76 | +//! @brief オープニング画面管理クラス | |
| 77 | +//! @details オープニング画面を管理します。 | |
| 78 | +class opening : public D3Dscene | |
| 79 | +{ | |
| 80 | + //int opening_banner; //!< オープニングで表示するテクスチャID | |
| 81 | + void Render3D(); | |
| 82 | + void Render2D(); | |
| 83 | + | |
| 84 | +public: | |
| 85 | + opening(); | |
| 86 | + ~opening(); | |
| 87 | + int Create(); | |
| 88 | + void Process(); | |
| 89 | + void Destroy(); | |
| 90 | +}; | |
| 91 | + | |
| 92 | +//! @brief メニュー画面管理クラス | |
| 93 | +//! @details メニュー画面を管理します。 | |
| 94 | +class mainmenu : public D3Dscene | |
| 95 | +{ | |
| 96 | + int mainmenu_mouseX; //!< メニュー画面マウスX座標 | |
| 97 | + int mainmenu_mouseY; //!< メニュー画面マウスY座標 | |
| 98 | + int mainmenu_scrollitems_official; //!< メニュー画面のスクロールしたアイテム数 | |
| 99 | + int mainmenu_scrollitems_addon; //!< メニュー画面のスクロールしたアイテム数 | |
| 100 | + float mainmenu_scrollbar_official_height; //!< メニュー画面のスクロールバーの高さ | |
| 101 | + float mainmenu_scrollbar_official_scale; //!< メニュー画面のスクロールバーの目盛 | |
| 102 | + int mainmenu_scrollbar_official_y; //!< メニュー画面のスクロールバーのY座標 | |
| 103 | + float mainmenu_scrollbar_addon_height; //!< メニュー画面のスクロールバーの高さ | |
| 104 | + float mainmenu_scrollbar_addon_scale; //!< メニュー画面のスクロールバーの目盛 | |
| 105 | + int mainmenu_scrollbar_addon_y; //!< メニュー画面のスクロールバーのY座標 | |
| 106 | + bool mainmenu_scrollbar_flag; //!< メニュー画面のスクロールバーを操作中を示すフラグ | |
| 107 | + int gametitle; //!< ゲームタイトル画像 | |
| 108 | + void Render3D(); | |
| 109 | + void Render2D(); | |
| 110 | + | |
| 111 | +public: | |
| 112 | + mainmenu(); | |
| 113 | + ~mainmenu(); | |
| 114 | + int Create(); | |
| 115 | + void Input(); | |
| 116 | + void Process(); | |
| 117 | + void Destroy(); | |
| 118 | +}; | |
| 119 | + | |
| 120 | +//! @brief ブリーフィング画面管理クラス | |
| 121 | +//! @details ブリーフィング画面を管理します。 | |
| 122 | +class briefing : public D2Dscene | |
| 123 | +{ | |
| 124 | + bool TwoTexture; //!< ブリーフィング画像を2枚使用 | |
| 125 | + int TextureA; //!< ブリーフィング画像A | |
| 126 | + int TextureB; //!< ブリーフィング画像B | |
| 127 | + void Render2D(); | |
| 128 | + | |
| 129 | +public: | |
| 130 | + briefing(); | |
| 131 | + ~briefing(); | |
| 132 | + int Create(); | |
| 133 | + void Destroy(); | |
| 134 | +}; | |
| 135 | + | |
| 136 | +//! @brief メインゲーム画面管理クラス | |
| 137 | +//! @details メインゲーム画面を管理します。 | |
| 138 | +class maingame : public D3Dscene | |
| 139 | +{ | |
| 140 | + //class EventControl Event[TOTAL_EVENTLINE]; //!< イベント制御クラス | |
| 141 | + float mouse_rx; //!< マウスによる水平軸角度 | |
| 142 | + float mouse_ry; //!< マウスによる垂直軸角度 | |
| 143 | + float view_rx; //!< マウス角度とカメラ角度の差(水平軸) | |
| 144 | + float view_ry; //!< マウス角度とカメラ角度の差(垂直軸) | |
| 145 | + bool ShowInfo_Debugmode; //!< 座標などを表示するデバックモード | |
| 146 | + bool Camera_Debugmode; //!< カメラデバックモード | |
| 147 | + bool Camera_F1mode; //!< カメラF1モード | |
| 148 | + int Camera_F2mode; //!< カメラF2モード | |
| 149 | + bool Camera_HOMEmode; //!< カメラHOMEモード | |
| 150 | + bool Cmd_F5; //!< 裏技F5モード | |
| 151 | + int start_framecnt; //!< メインゲーム開始時のカウント | |
| 152 | + int end_framecnt; //!< メインゲーム終了のカウント | |
| 153 | + int message_id; //!< 表示中のイベントメッセージ番号 | |
| 154 | + int message_cnt; //!< 表示中のイベントメッセージカウント | |
| 155 | + bool redflash_flag; //!< レッドフラッシュ描画フラグ | |
| 156 | + int time; //!< timer | |
| 157 | + int time_input; //!< 入力取得の処理時間 | |
| 158 | + int time_process_object; //!< 基本オブジェクトの処理時間 | |
| 159 | + int time_process_ai; //!< AIの処理時間 | |
| 160 | + int time_process_event; //!< イベントの処理時間 | |
| 161 | + int time_sound; //!< サウンドの処理時間 | |
| 162 | + int time_render; //!< 描画の処理時間 | |
| 163 | + GameInfo MainGameInfo; //!< リザルト用管理クラス | |
| 164 | + bool CheckInputControl(int CheckKey, int mode); | |
| 165 | + void Render3D(); | |
| 166 | + void Render2D(); | |
| 167 | + | |
| 168 | +public: | |
| 169 | + maingame(); | |
| 170 | + ~maingame(); | |
| 171 | + int Create(); | |
| 172 | + void Input(); | |
| 173 | + void Process(); | |
| 174 | + void Sound(); | |
| 175 | + void Destroy(); | |
| 176 | +}; | |
| 177 | + | |
| 178 | +//! @brief リザルト画面管理クラス | |
| 179 | +//! @details リザルト(結果表示)画面を管理します。 | |
| 180 | +class result : public D2Dscene | |
| 181 | +{ | |
| 182 | + void Render2D(); | |
| 183 | + | |
| 184 | +public: | |
| 185 | + result(); | |
| 186 | + ~result(); | |
| 187 | +}; | |
| 188 | + | |
| 189 | +void InitScreen(opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result); | |
| 190 | +void ProcessScreen(HWND hWnd, opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result, unsigned int framecnt); | |
| 191 | + | |
| 192 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,569 @@ | ||
| 1 | +//! @file soundmanager.cpp | |
| 2 | +//! @brief SoundManagerクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "soundmanager.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +SoundManager::SoundManager(SoundControl *in_SoundCtrl, ResourceManager *in_Resource, ParameterInfo *in_Param) | |
| 36 | +{ | |
| 37 | + SoundCtrl = in_SoundCtrl; | |
| 38 | + Resource = in_Resource; | |
| 39 | + Param = in_Param; | |
| 40 | + soundlistA = new soundlist[MAX_SOUNDMGR_LIST]; | |
| 41 | + soundlistB = new soundlist[MAX_SOUNDMGR_LIST]; | |
| 42 | + changeAB = false; | |
| 43 | + listAdatas = 0; | |
| 44 | + listBdatas = 0; | |
| 45 | +} | |
| 46 | + | |
| 47 | +//! ディストラクタ | |
| 48 | +SoundManager::~SoundManager() | |
| 49 | +{ | |
| 50 | + if( soundlistA != NULL ){ delete [] soundlistA; } | |
| 51 | + if( soundlistB != NULL ){ delete [] soundlistB; } | |
| 52 | +} | |
| 53 | + | |
| 54 | +//! 使用するクラスを設定 | |
| 55 | +//! @param in_SoundCtrl サウンドコントロールクラス | |
| 56 | +//! @param in_Resource リソース管理クラス | |
| 57 | +//! @param in_Param 設定値管理クラス | |
| 58 | +//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。 | |
| 59 | +void SoundManager::SetClass(SoundControl *in_SoundCtrl, ResourceManager *in_Resource, ParameterInfo *in_Param) | |
| 60 | +{ | |
| 61 | + SoundCtrl = in_SoundCtrl; | |
| 62 | + Resource = in_Resource; | |
| 63 | + Param = in_Param; | |
| 64 | +} | |
| 65 | + | |
| 66 | +//! 空間の音源を初期化 | |
| 67 | +void SoundManager::InitWorldSound() | |
| 68 | +{ | |
| 69 | + changeAB = false; | |
| 70 | + listAdatas = 0; | |
| 71 | + listBdatas = 0; | |
| 72 | +} | |
| 73 | + | |
| 74 | +//! 空間に発砲音を追加 | |
| 75 | +//! @param x 音源のX座標 | |
| 76 | +//! @param y 音源のY座標 | |
| 77 | +//! @param z 音源のZ座標 | |
| 78 | +//! @param id 武器の種類番号 | |
| 79 | +//! @param teamID チーム番号 | |
| 80 | +//! @param player プレイヤーによる発砲かどうか(trueでプレイヤー) | |
| 81 | +//! @return 成功:true 失敗:false | |
| 82 | +bool SoundManager::ShotWeapon(float x, float y, float z, int id, int teamID, bool player) | |
| 83 | +{ | |
| 84 | + soundlist *plist = NULL; | |
| 85 | + if( GetNewList(&plist) == false ){ return false; } | |
| 86 | + | |
| 87 | + if( player == true ){ | |
| 88 | + plist->paramid = SHOT_WEAPON_PLAYER; | |
| 89 | + } | |
| 90 | + else{ | |
| 91 | + plist->paramid = SHOT_WEAPON; | |
| 92 | + } | |
| 93 | + plist->dataid = id; | |
| 94 | + plist->x = x; | |
| 95 | + plist->y = y; | |
| 96 | + plist->z = z; | |
| 97 | + plist->teamid = teamID; | |
| 98 | + | |
| 99 | + return true; | |
| 100 | +} | |
| 101 | + | |
| 102 | +//! 空間にマップ着弾音を追加 | |
| 103 | +//! @param x 音源のX座標 | |
| 104 | +//! @param y 音源のY座標 | |
| 105 | +//! @param z 音源のZ座標 | |
| 106 | +//! @return 成功:true 失敗:false | |
| 107 | +bool SoundManager::HitMap(float x, float y, float z) | |
| 108 | +{ | |
| 109 | + soundlist *plist = NULL; | |
| 110 | + if( GetNewList(&plist) == false ){ return false; } | |
| 111 | + | |
| 112 | + plist->paramid = HIT_MAP; | |
| 113 | + plist->x = x; | |
| 114 | + plist->y = y; | |
| 115 | + plist->z = z; | |
| 116 | + | |
| 117 | + return true; | |
| 118 | +} | |
| 119 | + | |
| 120 | +//! 空間に被弾音を追加 | |
| 121 | +//! @param x 音源のX座標 | |
| 122 | +//! @param y 音源のY座標 | |
| 123 | +//! @param z 音源のZ座標 | |
| 124 | +//! @return 成功:true 失敗:false | |
| 125 | +bool SoundManager::HitHuman(float x, float y, float z) | |
| 126 | +{ | |
| 127 | + soundlist *plist = NULL; | |
| 128 | + if( GetNewList(&plist) == false ){ return false; } | |
| 129 | + | |
| 130 | + plist->paramid = HIT_HUMAN; | |
| 131 | + plist->x = x; | |
| 132 | + plist->y = y; | |
| 133 | + plist->z = z; | |
| 134 | + | |
| 135 | + return true; | |
| 136 | +} | |
| 137 | + | |
| 138 | +//! 空間に小物着弾音を追加 | |
| 139 | +//! @param x 音源のX座標 | |
| 140 | +//! @param y 音源のY座標 | |
| 141 | +//! @param z 音源のZ座標 | |
| 142 | +//! @param id 小物の種類番号 | |
| 143 | +//! @return 成功:true 失敗:false | |
| 144 | +bool SoundManager::HitSmallObject(float x, float y, float z, int id) | |
| 145 | +{ | |
| 146 | + soundlist *plist = NULL; | |
| 147 | + if( GetNewList(&plist) == false ){ return false; } | |
| 148 | + | |
| 149 | + plist->paramid = HIT_SMALLOBJECT; | |
| 150 | + plist->dataid = id; | |
| 151 | + plist->x = x; | |
| 152 | + plist->y = y; | |
| 153 | + plist->z = z; | |
| 154 | + | |
| 155 | + return true; | |
| 156 | +} | |
| 157 | + | |
| 158 | +//! 弾の通過・横切る音を追加 | |
| 159 | +//! @param x 音源のX座標 | |
| 160 | +//! @param y 音源のY座標 | |
| 161 | +//! @param z 音源のZ座標 | |
| 162 | +//! @param move_x 音源のX軸移動量 | |
| 163 | +//! @param move_y 音源のY軸移動量 | |
| 164 | +//! @param move_z 音源のZ軸移動量 | |
| 165 | +//! @return 成功:true 失敗:false | |
| 166 | +//! @attention move_x・move_y・move_zの移動量は、1フレーム分を指定してください。実際に座標が移動するわけではありません。 | |
| 167 | +bool SoundManager::PassingBullet(float x, float y, float z, float move_x, float move_y, float move_z) | |
| 168 | +{ | |
| 169 | + soundlist *plist = NULL; | |
| 170 | + if( GetNewList(&plist) == false ){ return false; } | |
| 171 | + | |
| 172 | + plist->paramid = BULLET; | |
| 173 | + plist->x = x; | |
| 174 | + plist->y = y; | |
| 175 | + plist->z = z; | |
| 176 | + plist->move_x = move_x; | |
| 177 | + plist->move_y = move_y; | |
| 178 | + plist->move_z = move_z; | |
| 179 | + | |
| 180 | + return true; | |
| 181 | +} | |
| 182 | + | |
| 183 | +//! 空間に手榴弾バウンド・跳ね返り音を追加 | |
| 184 | +//! @param x 音源のX座標 | |
| 185 | +//! @param y 音源のY座標 | |
| 186 | +//! @param z 音源のZ座標 | |
| 187 | +//! @return 成功:true 失敗:false | |
| 188 | +bool SoundManager::GrenadeBound(float x, float y, float z) | |
| 189 | +{ | |
| 190 | + soundlist *plist = NULL; | |
| 191 | + if( GetNewList(&plist) == false ){ return false; } | |
| 192 | + | |
| 193 | + plist->paramid = GRE_BOUND; | |
| 194 | + plist->x = x; | |
| 195 | + plist->y = y; | |
| 196 | + plist->z = z; | |
| 197 | + | |
| 198 | + return true; | |
| 199 | +} | |
| 200 | + | |
| 201 | +//! 空間に手榴弾爆発音を追加 | |
| 202 | +//! @param x 音源のX座標 | |
| 203 | +//! @param y 音源のY座標 | |
| 204 | +//! @param z 音源のZ座標 | |
| 205 | +//! @return 成功:true 失敗:false | |
| 206 | +bool SoundManager::GrenadeExplosion(float x, float y, float z) | |
| 207 | +{ | |
| 208 | + soundlist *plist = NULL; | |
| 209 | + if( GetNewList(&plist) == false ){ return false; } | |
| 210 | + | |
| 211 | + plist->paramid = GRE_EXPLOSION; | |
| 212 | + plist->x = x; | |
| 213 | + plist->y = y; | |
| 214 | + plist->z = z; | |
| 215 | + | |
| 216 | + return true; | |
| 217 | +} | |
| 218 | + | |
| 219 | +//! 空間に足音を追加 | |
| 220 | +//! @param x 音源のX座標 | |
| 221 | +//! @param y 音源のY座標 | |
| 222 | +//! @param z 音源のZ座標 | |
| 223 | +//! @param teamID チーム番号 | |
| 224 | +//! @return 成功:true 失敗:false | |
| 225 | +bool SoundManager::SetFootsteps(float x, float y, float z, int teamID) | |
| 226 | +{ | |
| 227 | + soundlist *plist = NULL; | |
| 228 | + if( GetNewList(&plist) == false ){ return false; } | |
| 229 | + | |
| 230 | + plist->paramid = FOOTSTEPS; | |
| 231 | + plist->x = x; | |
| 232 | + plist->y = y; | |
| 233 | + plist->z = z; | |
| 234 | + plist->teamid = teamID; | |
| 235 | + | |
| 236 | + return true; | |
| 237 | +} | |
| 238 | + | |
| 239 | +//! 空間に武器リロード音を追加 | |
| 240 | +//! @param x 音源のX座標 | |
| 241 | +//! @param y 音源のY座標 | |
| 242 | +//! @param z 音源のZ座標 | |
| 243 | +//! @param teamID チーム番号 | |
| 244 | +//! @return 成功:true 失敗:false | |
| 245 | +bool SoundManager::ReloadWeapon(float x, float y, float z, int teamID) | |
| 246 | +{ | |
| 247 | + soundlist *plist = NULL; | |
| 248 | + if( GetNewList(&plist) == false ){ return false; } | |
| 249 | + | |
| 250 | + plist->paramid = WEAPON_RELOAD; | |
| 251 | + plist->x = x; | |
| 252 | + plist->y = y; | |
| 253 | + plist->z = z; | |
| 254 | + plist->teamid = teamID; | |
| 255 | + | |
| 256 | + return true; | |
| 257 | +} | |
| 258 | + | |
| 259 | +//! 指定した位置の周辺にある音源を取得 | |
| 260 | +//! @param pos_x 音源のX座標 | |
| 261 | +//! @param pos_y 音源のY座標 | |
| 262 | +//! @param pos_z 音源のZ座標 | |
| 263 | +//! @param teamID チーム番号 | |
| 264 | +//! @param psoundlist サウンドリストを受け取るポインタ | |
| 265 | +//! @return 返す(サウンドリストの)音源の数 | |
| 266 | +int SoundManager::GetWorldSound(float pos_x, float pos_y, float pos_z, int teamID, soundlist *psoundlist) | |
| 267 | +{ | |
| 268 | + int lists; | |
| 269 | + soundlist *getlist = NULL; | |
| 270 | + int newlists = 0; | |
| 271 | + WeaponParameter WParam; | |
| 272 | + | |
| 273 | + //処理するリストを決定 | |
| 274 | + lists = GetTargetList(&getlist); | |
| 275 | + | |
| 276 | + for(int i=0; i<lists; i++){ | |
| 277 | + float x, y, z; | |
| 278 | + float maxdist = 20.0f; //判定距離の標準値 | |
| 279 | + | |
| 280 | + //音源の種類により判定距離を変える | |
| 281 | + if( (getlist[i].paramid == SHOT_WEAPON)||(getlist[i].paramid == SHOT_WEAPON_PLAYER) ){ | |
| 282 | + Param->GetWeapon(getlist[i].dataid, &WParam); | |
| 283 | + | |
| 284 | + if( getlist[i].teamid == teamID ){ maxdist = 20.0f; } | |
| 285 | + else if( WParam.silencer == true ){ maxdist = 25.0f; } | |
| 286 | + else{ maxdist = 120.0f; } | |
| 287 | + } | |
| 288 | + if( getlist[i].paramid == FOOTSTEPS ){ | |
| 289 | + if( getlist[i].teamid == teamID ){ continue; } | |
| 290 | + else{ maxdist = 35.0f; } | |
| 291 | + } | |
| 292 | + if( getlist[i].paramid == GRE_BOUND ){ | |
| 293 | + continue; | |
| 294 | + } | |
| 295 | + if( getlist[i].paramid == WEAPON_RELOAD ){ | |
| 296 | + continue; | |
| 297 | + } | |
| 298 | + | |
| 299 | + //銃弾ならば | |
| 300 | + if( getlist[i].paramid == BULLET ){ | |
| 301 | + float min_x, min_y, min_z; | |
| 302 | + | |
| 303 | + //銃弾が最も近づく座標を算出 | |
| 304 | + if( CheckApproach(&(getlist[i]), pos_x, pos_y, pos_z, &min_x, &min_y, &min_z) == false ){ continue; } | |
| 305 | + | |
| 306 | + //音源との距離が範囲内ならば〜 | |
| 307 | + x = min_x - pos_x; | |
| 308 | + y = min_y - pos_y; | |
| 309 | + z = min_z - pos_z; | |
| 310 | + if( x*x + y*y + z*z < maxdist*maxdist ){ | |
| 311 | + //出力先のリストに追加 | |
| 312 | + psoundlist[newlists].paramid = getlist[i].paramid; | |
| 313 | + psoundlist[newlists].dataid = getlist[i].dataid; | |
| 314 | + psoundlist[newlists].x = min_x; | |
| 315 | + psoundlist[newlists].y = min_y; | |
| 316 | + psoundlist[newlists].z = min_z; | |
| 317 | + newlists += 1; | |
| 318 | + } | |
| 319 | + } | |
| 320 | + else{ | |
| 321 | + //音源との距離が範囲内ならば〜 | |
| 322 | + x = getlist[i].x - pos_x; | |
| 323 | + y = getlist[i].y - pos_y; | |
| 324 | + z = getlist[i].z - pos_z; | |
| 325 | + if( x*x + y*y + z*z < maxdist*maxdist ){ | |
| 326 | + //出力先のリストに追加 | |
| 327 | + psoundlist[newlists].paramid = getlist[i].paramid; | |
| 328 | + psoundlist[newlists].dataid = getlist[i].dataid; | |
| 329 | + psoundlist[newlists].x = getlist[i].x; | |
| 330 | + psoundlist[newlists].y = getlist[i].y; | |
| 331 | + psoundlist[newlists].z = getlist[i].z; | |
| 332 | + newlists += 1; | |
| 333 | + } | |
| 334 | + } | |
| 335 | + } | |
| 336 | + | |
| 337 | + return newlists; | |
| 338 | +} | |
| 339 | + | |
| 340 | +//! 空間上のサウンドを再生 | |
| 341 | +//! @param camera_x カメラのX座標 | |
| 342 | +//! @param camera_y カメラのY座標 | |
| 343 | +//! @param camera_z カメラのZ座標 | |
| 344 | +//! @param camera_rx カメラのX軸角度 (予約) | |
| 345 | +//! @warning 毎フレーム呼び出してください。 | |
| 346 | +void SoundManager::PlayWorldSound(float camera_x, float camera_y, float camera_z, float camera_rx) | |
| 347 | +{ | |
| 348 | + int lists; | |
| 349 | + soundlist *getlist = NULL; | |
| 350 | + | |
| 351 | + //フラグを切り替える | |
| 352 | + if( changeAB == false ){ | |
| 353 | + listBdatas = 0; | |
| 354 | + changeAB = true; | |
| 355 | + } | |
| 356 | + else{ | |
| 357 | + listAdatas = 0; | |
| 358 | + changeAB = false; | |
| 359 | + } | |
| 360 | + | |
| 361 | + //カメラ座標を設定 | |
| 362 | + SoundCtrl->SetCamera(camera_x, camera_y, camera_z, camera_rx); | |
| 363 | + | |
| 364 | + //処理するリストを決定 | |
| 365 | + lists = GetTargetList(&getlist); | |
| 366 | + | |
| 367 | + for(int i=0; i<lists; i++){ | |
| 368 | + float x = getlist[i].x - camera_x; | |
| 369 | + float y = getlist[i].y - camera_y; | |
| 370 | + float z = getlist[i].z - camera_z; | |
| 371 | + | |
| 372 | + //範囲内の音源ならば再生を試みる | |
| 373 | + if( x*x + y*y + z*z < MAX_SOUNDDIST*MAX_SOUNDDIST ){ | |
| 374 | + PlaySound( &(getlist[i]), camera_x, camera_y, camera_z ); | |
| 375 | + } | |
| 376 | + } | |
| 377 | +} | |
| 378 | + | |
| 379 | +//! 新しいサウンドリスト(単一)を取得 | |
| 380 | +//! @param plist 新しいサウンドリスト(単一)の二重ポインタ | |
| 381 | +//! @return 成功:true 失敗:false | |
| 382 | +bool SoundManager::GetNewList(soundlist **plist) | |
| 383 | +{ | |
| 384 | + if( changeAB == false ){ | |
| 385 | + if( (listAdatas + 1) >= MAX_SOUNDMGR_LIST ){ | |
| 386 | + return false; | |
| 387 | + } | |
| 388 | + *plist = &(soundlistA[listAdatas]); | |
| 389 | + listAdatas += 1; | |
| 390 | + } | |
| 391 | + else{ | |
| 392 | + if( (listBdatas + 1) >= MAX_SOUNDMGR_LIST ){ | |
| 393 | + return false; | |
| 394 | + } | |
| 395 | + *plist = &(soundlistB[listBdatas]); | |
| 396 | + listBdatas += 1; | |
| 397 | + } | |
| 398 | + | |
| 399 | + return true; | |
| 400 | +} | |
| 401 | + | |
| 402 | +//! 処理対象のサウンドリストを取得 | |
| 403 | +//! @param plist 処理対象のサウンドリストの二重ポインタ | |
| 404 | +//! @return 取得したサウンドリストに含まれる音源の数 | |
| 405 | +int SoundManager::GetTargetList(soundlist **plist) | |
| 406 | +{ | |
| 407 | + if( changeAB == false ){ | |
| 408 | + *plist = soundlistB; | |
| 409 | + return listBdatas; | |
| 410 | + } | |
| 411 | + //else{ | |
| 412 | + *plist = soundlistA; | |
| 413 | + return listAdatas; | |
| 414 | + //} | |
| 415 | +} | |
| 416 | + | |
| 417 | +//! 音源がカメラ(視点)に最も近づくか確認 | |
| 418 | +//! @param plist 処理対象のサウンドリスト(単一)のポインタ | |
| 419 | +//! @param camera_x カメラのX座標 | |
| 420 | +//! @param camera_y カメラのY座標 | |
| 421 | +//! @param camera_z カメラのZ座標 | |
| 422 | +//! @param min_x 最短距離のX座標を受け取るポインタ | |
| 423 | +//! @param min_y 最短距離のY座標を受け取るポインタ | |
| 424 | +//! @param min_z 最短距離のZ座標を受け取るポインタ | |
| 425 | +//! @return 通り過ぎた:true 通り過ぎていない:false | |
| 426 | +//! @todo 動作未検証 | |
| 427 | +bool SoundManager::CheckApproach(soundlist *plist, float camera_x, float camera_y, float camera_z, float *min_x, float *min_y, float *min_z) | |
| 428 | +{ | |
| 429 | + float x, y, z; | |
| 430 | + float dist1, dist2, dist3; | |
| 431 | + | |
| 432 | + //現在位置の距離 | |
| 433 | + x = camera_x - plist->x; | |
| 434 | + y = camera_y - plist->y; | |
| 435 | + z = camera_z - plist->z; | |
| 436 | + dist1 = x*x + y*y + z*z; | |
| 437 | + | |
| 438 | + //1フレーム後の距離 | |
| 439 | + x = camera_x - (plist->x + plist->move_x); | |
| 440 | + y = camera_y - (plist->y + plist->move_y); | |
| 441 | + z = camera_z - (plist->z + plist->move_z); | |
| 442 | + dist2 = x*x + y*y + z*z; | |
| 443 | + | |
| 444 | + //2フレーム後の位置 | |
| 445 | + x = camera_x - (plist->x + plist->move_x*2); | |
| 446 | + y = camera_y - (plist->y + plist->move_y*2); | |
| 447 | + z = camera_z - (plist->z + plist->move_z*2); | |
| 448 | + dist3 = x*x + y*y + z*z; | |
| 449 | + | |
| 450 | + //1フレーム後の距離が最も近ければ〜 | |
| 451 | + if( (dist1 > dist2)&&(dist2 < dist3) ){ | |
| 452 | + float speed; | |
| 453 | + float min_dist, dist; | |
| 454 | + | |
| 455 | + //移動速度を求める | |
| 456 | + speed = (float)sqrt(plist->move_x*plist->move_x + plist->move_y*plist->move_y + plist->move_z*plist->move_z); | |
| 457 | + | |
| 458 | + //最短距離の座標を求める | |
| 459 | + min_dist = DistancePosRay(camera_x, camera_y, camera_z, plist->x, plist->y, plist->z, plist->move_x/speed, plist->move_y/speed, plist->move_z/speed, (float)speed*2); | |
| 460 | + | |
| 461 | + //最短距離時の座標を求める | |
| 462 | + dist = (float)sqrt(dist1 - min_dist*min_dist); | |
| 463 | + *min_x = plist->x + plist->move_x/speed * dist; | |
| 464 | + *min_y = plist->y + plist->move_y/speed * dist; | |
| 465 | + *min_z = plist->z + plist->move_z/speed * dist; | |
| 466 | + | |
| 467 | + return true; | |
| 468 | + } | |
| 469 | + | |
| 470 | + return false; | |
| 471 | +} | |
| 472 | + | |
| 473 | +//! 指定したサウンドリスト(1音源)を再生 | |
| 474 | +//! @param plist 再生するサウンドリスト(単一)のポインタ | |
| 475 | +//! @param camera_x カメラのX座標 | |
| 476 | +//! @param camera_y カメラのY座標 | |
| 477 | +//! @param camera_z カメラのZ座標 | |
| 478 | +void SoundManager::PlaySound(soundlist *plist, float camera_x, float camera_y, float camera_z) | |
| 479 | +{ | |
| 480 | + WeaponParameter WParam; | |
| 481 | + int hitsoundA, hitsoundB; | |
| 482 | + int hitsound; | |
| 483 | + int ccosound; | |
| 484 | + int bangsound; | |
| 485 | + | |
| 486 | + int id = -1; | |
| 487 | + int volume = 0; | |
| 488 | + | |
| 489 | + //再生条件を設定 | |
| 490 | + switch(plist->paramid){ | |
| 491 | + case SHOT_WEAPON: //発砲音 | |
| 492 | + Param->GetWeapon(plist->dataid, &WParam); | |
| 493 | + if( WParam.soundvolume == 0 ){ return; } | |
| 494 | + | |
| 495 | + id = Resource->GetWeaponSound(plist->dataid); | |
| 496 | + volume = WParam.soundvolume; | |
| 497 | + break; | |
| 498 | + | |
| 499 | + case SHOT_WEAPON_PLAYER: //プレイヤー自身の発砲音 | |
| 500 | + Param->GetWeapon(plist->dataid, &WParam); | |
| 501 | + if( WParam.soundvolume == 0 ){ return; } | |
| 502 | + | |
| 503 | + //3D音源とせずにそのまま再生して終了 | |
| 504 | + SoundCtrl->PlaySound(Resource->GetWeaponSound(plist->dataid), WParam.soundvolume, 0); | |
| 505 | + return; | |
| 506 | + | |
| 507 | + case HIT_MAP: //マップ着弾音 | |
| 508 | + Resource->GetBulletSound(&hitsoundA, &hitsoundB, NULL, NULL, NULL, NULL); | |
| 509 | + if( GetRand(2) ){ | |
| 510 | + id = hitsoundA; | |
| 511 | + } | |
| 512 | + else{ | |
| 513 | + id = hitsoundB; | |
| 514 | + } | |
| 515 | + volume = MAX_SOUNDHITMAP; | |
| 516 | + break; | |
| 517 | + | |
| 518 | + case HIT_HUMAN: //被弾音 | |
| 519 | + Resource->GetBulletSound(NULL, NULL, &hitsound, NULL, NULL, NULL); | |
| 520 | + id = hitsound; | |
| 521 | + volume = MAX_SOUNDHITHUMAN; | |
| 522 | + break; | |
| 523 | + | |
| 524 | + case HIT_SMALLOBJECT: //小物破壊音 | |
| 525 | + id = Resource->GetSmallObjectSound(plist->dataid); | |
| 526 | + volume = MAX_SOUNDHITSMALLOBJ; | |
| 527 | + break; | |
| 528 | + | |
| 529 | + case BULLET: //銃弾の音・横切る音 | |
| 530 | + float new_x, new_y, new_z; | |
| 531 | + int passingsound; | |
| 532 | + | |
| 533 | + if( CheckApproach(plist, camera_x, camera_y, camera_z, &new_x, &new_y, &new_z) == false ){ return; } | |
| 534 | + | |
| 535 | + //そのまま再生して終了 | |
| 536 | + Resource->GetBulletSound(NULL, NULL, NULL, &passingsound, NULL, NULL); | |
| 537 | + SoundCtrl->Play3DSound(passingsound, new_x, new_y, new_z, MAX_SOUNDPASSING); | |
| 538 | + return; | |
| 539 | + | |
| 540 | + case GRE_BOUND: //手榴弾 バウンド音 | |
| 541 | + Resource->GetBulletSound(NULL, NULL, NULL, NULL, NULL, &ccosound); | |
| 542 | + id = ccosound; | |
| 543 | + volume = MAX_SOUNDCCOGRENADE; | |
| 544 | + break; | |
| 545 | + | |
| 546 | + case GRE_EXPLOSION: //手榴弾 爆発音 | |
| 547 | + Resource->GetBulletSound(NULL, NULL, NULL, NULL, &bangsound, NULL); | |
| 548 | + id = bangsound; | |
| 549 | + volume = MAX_SOUNDHITGRENADE; | |
| 550 | + break; | |
| 551 | + | |
| 552 | + case FOOTSTEPS: //足音・走る音 | |
| 553 | + //足音を再生する処理を書く | |
| 554 | + //break; | |
| 555 | + | |
| 556 | + return; //何も再生せずに返す | |
| 557 | + | |
| 558 | + case WEAPON_RELOAD: //リロード音 | |
| 559 | + id = Resource->GetWeaponSound(-1); | |
| 560 | + volume = 100; | |
| 561 | + break; | |
| 562 | + | |
| 563 | + default: | |
| 564 | + return; | |
| 565 | + } | |
| 566 | + | |
| 567 | + //再生 | |
| 568 | + SoundCtrl->Play3DSound(id, plist->x, plist->y, plist->z, volume); | |
| 569 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,119 @@ | ||
| 1 | +//! @file main.cpp | |
| 2 | +//! @brief WinMain()関数の定義およびテストプログラム | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +//Doxygen設定ファイル | |
| 33 | +#include "doxygen.h" | |
| 34 | + | |
| 35 | +#include "main.h" | |
| 36 | + | |
| 37 | +#include <shlwapi.h> | |
| 38 | +#pragma comment(lib, "Shlwapi.lib") | |
| 39 | + | |
| 40 | +//! ステートマシン | |
| 41 | +StateMachine GameState; | |
| 42 | + | |
| 43 | +//! ゲーム設定データ | |
| 44 | +Config GameConfig; | |
| 45 | + | |
| 46 | +//! WinMain()関数 | |
| 47 | +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) | |
| 48 | +{ | |
| 49 | + //乱数初期化 | |
| 50 | + InitRand(); | |
| 51 | + | |
| 52 | +#ifdef _DEBUG | |
| 53 | + //メモリリークの検出 | |
| 54 | + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); | |
| 55 | + | |
| 56 | + //実行ファイルのある場所を、カレントディレクトリにする。 | |
| 57 | + char path[MAX_PATH]; | |
| 58 | + //GetModuleFileName(NULL, path, MAX_PATH); | |
| 59 | + strcpy(path, "K:\\ソフト\\XOPS\\xops096\\"); | |
| 60 | + PathRemoveFileSpec(path); | |
| 61 | + SetCurrentDirectory(path); | |
| 62 | +#endif | |
| 63 | + | |
| 64 | + //設定ファイル読み込み | |
| 65 | + if( GameConfig.LoadFile("config.dat") == 1 ){ | |
| 66 | + MessageBox(NULL, "config data open failed", "error", MB_OK); | |
| 67 | + return 1; | |
| 68 | + } | |
| 69 | + | |
| 70 | +#ifdef _DEBUG | |
| 71 | + char str[24]; | |
| 72 | + GameConfig.GetPlayerName(str); | |
| 73 | + MessageBox(NULL, str, "プレイヤー名", MB_OK); | |
| 74 | +#endif | |
| 75 | + | |
| 76 | + //ウィンドウ初期化 | |
| 77 | + HWND hWnd; | |
| 78 | + hWnd = InitWindow(hPrevInstance, GAMENAME, SCREEN_WIDTH, SCREEN_HEIGTH, nCmdShow, GameConfig.GetFullscreenFlag()); | |
| 79 | + | |
| 80 | + //基本的な初期化処理 | |
| 81 | + if( InitGame(hWnd) ){ | |
| 82 | + return 1; | |
| 83 | + } | |
| 84 | + | |
| 85 | + opening Opening; | |
| 86 | + mainmenu MainMenu; | |
| 87 | + briefing Briefing; | |
| 88 | + maingame MainGame; | |
| 89 | + result Result; | |
| 90 | + InitScreen(&Opening, &MainMenu, &Briefing, &MainGame, &Result); | |
| 91 | + | |
| 92 | + | |
| 93 | + unsigned int framecnt = 0; | |
| 94 | + | |
| 95 | + MSG msg = {0}; | |
| 96 | + | |
| 97 | + //[WM_QUIT]が来るまで回る | |
| 98 | + while( msg.message != WM_QUIT ){ | |
| 99 | + if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ){ //ウインドウメッセージが来ている | |
| 100 | + TranslateMessage( &msg ); | |
| 101 | + DispatchMessage( &msg ); | |
| 102 | + } | |
| 103 | + else if( GetActiveWindow() == hWnd ){ //ウインドウがアクティブならば | |
| 104 | + //メイン処理 | |
| 105 | + ProcessScreen(hWnd, &Opening, &MainMenu, &Briefing, &MainGame, &Result, framecnt); | |
| 106 | + | |
| 107 | + //FPS調整 | |
| 108 | + ControlFps(); | |
| 109 | + | |
| 110 | + framecnt++; | |
| 111 | + } | |
| 112 | + else{ //ウインドウが非アクティブで、ウインドウメッセージも来ない | |
| 113 | + //ウインドウメッセージが来るまで待つ | |
| 114 | + WaitMessage(); | |
| 115 | + } | |
| 116 | + } | |
| 117 | + | |
| 118 | + return 0; | |
| 119 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,63 @@ | ||
| 1 | +//! @file event.h | |
| 2 | +//! @brief EventControlクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef EVENT_H | |
| 33 | +#define EVENT_H | |
| 34 | + | |
| 35 | +#define TOTAL_EVENTFRAMESTEP 6 //!< 1フレーム中に1ラインあたり実行するステップ数 | |
| 36 | +#define DISTANCE_CHECKPOINT 25.0f //!< 「到着待ち」「ケース待ち」の判定距離 | |
| 37 | + | |
| 38 | +#ifndef H_LAYERLEVEL | |
| 39 | + #define H_LAYERLEVEL 3 //!< Select include file. | |
| 40 | +#endif | |
| 41 | +#include "main.h" | |
| 42 | + | |
| 43 | +//! @brief イベントを処理するクラス | |
| 44 | +//! @details ミッションのイベントポイントを処理します。 | |
| 45 | +//! @details このクラスは1つのイベント処理(流れ)に専念します。複数のイベントを並列に処理させる場合は、このクラスのオブジェクトを複数呼び出す必要があります。(例えば3つ同時に処理させる場合、このクラスのオブジェクトを3つ作成してください。) | |
| 46 | +class EventControl | |
| 47 | +{ | |
| 48 | + class PointDataInterface *Point; //!< PointDataInterfaceクラスのポインタ | |
| 49 | + class ObjectManager *ObjMgr; //!< ObjectManagerクラスのポインタ | |
| 50 | + signed char nextp4; //!< 次に処理するのP4:認識番号 | |
| 51 | + int waitcnt; //!< 時間待ち用カウント | |
| 52 | + | |
| 53 | + bool CheckHaveCase(human *in_human); | |
| 54 | + | |
| 55 | +public: | |
| 56 | + EventControl(PointDataInterface *in_Point = NULL, ObjectManager *in_ObjMgr = NULL); | |
| 57 | + ~EventControl(); | |
| 58 | + void SetClass(PointDataInterface *in_Point, ObjectManager *in_ObjMgr); | |
| 59 | + void Reset(signed char EntryP4); | |
| 60 | + int Execution(int *endcnt, bool *complete, int *MessageID, bool *SetMessageID); | |
| 61 | +}; | |
| 62 | + | |
| 63 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,607 @@ | ||
| 1 | +//! @file sound.cpp | |
| 2 | +//! @brief SoundControlクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "sound.h" | |
| 33 | + | |
| 34 | +#ifdef SOUND_DIRECTSOUND | |
| 35 | + | |
| 36 | +//! コンストラクタ | |
| 37 | +SoundControl::SoundControl() | |
| 38 | +{ | |
| 39 | + pDSound = NULL; | |
| 40 | +} | |
| 41 | + | |
| 42 | +//! ディストラクタ | |
| 43 | +SoundControl::~SoundControl() | |
| 44 | +{ | |
| 45 | + for(int i=0;i<MAX_LOADSOUND; i++){ | |
| 46 | + for(int j=0; j<MAX_SOUNDLISTS; j++){ | |
| 47 | + if( pDSBuffer[i][j] != NULL ){ pDSBuffer[i][j]->Release(); } | |
| 48 | + } | |
| 49 | + } | |
| 50 | + if( pDSound != NULL ){ pDSound->Release(); } | |
| 51 | +} | |
| 52 | + | |
| 53 | +//! 初期化 | |
| 54 | +//! @param hWnd ウィンドウハンドル | |
| 55 | +//! @return 成功:0 失敗:1 | |
| 56 | +int SoundControl::InitSound(HWND hWnd) | |
| 57 | +{ | |
| 58 | + //DirectSoundオブジェクトを生成 | |
| 59 | + if( FAILED( DirectSoundCreate8(NULL, &pDSound, NULL) ) ){ | |
| 60 | + return 1; | |
| 61 | + } | |
| 62 | + | |
| 63 | + //協調レベルの設定 | |
| 64 | + if( FAILED( pDSound->SetCooperativeLevel(hWnd, DSSCL_EXCLUSIVE) ) ){ | |
| 65 | + return 1; | |
| 66 | + } | |
| 67 | + | |
| 68 | + //プライマリ バッファを作成し、リスナーインターフェイスを取得する | |
| 69 | + LPDIRECTSOUNDBUFFER pPrimary; | |
| 70 | + DSBUFFERDESC dsbd; | |
| 71 | + ZeroMemory(&dsbd, sizeof(DSBUFFERDESC)); | |
| 72 | + dsbd.dwSize = sizeof(DSBUFFERDESC); | |
| 73 | + dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_PRIMARYBUFFER; | |
| 74 | + if( SUCCEEDED(pDSound->CreateSoundBuffer(&dsbd, &pPrimary, NULL)) ){ | |
| 75 | + pPrimary->QueryInterface(IID_IDirectSound3DListener8,(LPVOID *)&p3DListener); | |
| 76 | + pPrimary->Release(); | |
| 77 | + } | |
| 78 | + | |
| 79 | + //ドップラー効果を無効に | |
| 80 | + p3DListener->SetDopplerFactor(DS3D_MINDOPPLERFACTOR, DS3D_IMMEDIATE); | |
| 81 | + | |
| 82 | + //ロール・オフ(減衰度合い)設定 | |
| 83 | + p3DListener->SetRolloffFactor(0.05f, DS3D_IMMEDIATE); | |
| 84 | + | |
| 85 | + return 0; | |
| 86 | +} | |
| 87 | + | |
| 88 | +//! 再生音量を設定 | |
| 89 | +//! @param volume 再生音量 (0.0=無音 1.0=100%) | |
| 90 | +void SoundControl::SetVolume(float volume) | |
| 91 | +{ | |
| 92 | + // | |
| 93 | +} | |
| 94 | + | |
| 95 | +//! カメラの座標と角度を設定 | |
| 96 | +//! @param x カメラのX座標 | |
| 97 | +//! @param y カメラのY座標 | |
| 98 | +//! @param z カメラのZ座標 | |
| 99 | +//! @param rx カメラのX軸角度 (予約) | |
| 100 | +//! @warning 毎フレーム呼び出して、最新のカメラ座標を設定(適用)してください。 | |
| 101 | +void SoundControl::SetCamera(float x, float y, float z, float rx) | |
| 102 | +{ | |
| 103 | + p3DListener->SetPosition(x, y, z, DS3D_IMMEDIATE); | |
| 104 | + p3DListener->SetOrientation(cos(rx), 0.0f, sin(rx), 0.0f, 1.0f, 0.0f, DS3D_IMMEDIATE); | |
| 105 | +} | |
| 106 | + | |
| 107 | +//! サウンドを読み込む | |
| 108 | +//! @param filename ファイル名 | |
| 109 | +//! @return 成功:0以上の認識番号 失敗:-1 | |
| 110 | +int SoundControl::LoadSound(char* filename) | |
| 111 | +{ | |
| 112 | + if( pDSound == NULL ){ return -1; } | |
| 113 | + | |
| 114 | + //開いている番号を探す | |
| 115 | + int id=0; | |
| 116 | + for(id=0; id<MAX_LOADSOUND; id++){ | |
| 117 | + if( pDSBuffer[id][0] == NULL ){ break; } | |
| 118 | + } | |
| 119 | + if( id == MAX_LOADSOUND ){ return -1; } | |
| 120 | + | |
| 121 | + WAVEFORMATEX* pwfex; | |
| 122 | + int WavSize = 0; | |
| 123 | + int Wavoffset = 0; | |
| 124 | + | |
| 125 | + //Waveファイルの情報を取得 | |
| 126 | + if( CheckSoundFile(filename, &WavSize, &Wavoffset, &pwfex) == true ){ | |
| 127 | + return -1; | |
| 128 | + } | |
| 129 | + pwfex->cbSize = 0; | |
| 130 | + | |
| 131 | + // DirectSoundセカンダリーバッファー作成 | |
| 132 | + DSBUFFERDESC dsbd; | |
| 133 | + ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) ); | |
| 134 | + dsbd.dwSize = sizeof(DSBUFFERDESC); | |
| 135 | + dsbd.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME; | |
| 136 | + dsbd.dwBufferBytes = WavSize; | |
| 137 | + dsbd.guid3DAlgorithm = DS3DALG_NO_VIRTUALIZATION; | |
| 138 | + dsbd.lpwfxFormat = pwfex; | |
| 139 | + if( FAILED( pDSound->CreateSoundBuffer(&dsbd, &pDSBuffer[id][0], NULL) ) ){ | |
| 140 | + return -1; //セカンダリバッファー作成失敗 | |
| 141 | + } | |
| 142 | + | |
| 143 | + //ロックする | |
| 144 | + VOID* pBuffer = NULL; | |
| 145 | + DWORD dwBufferSize = 0; | |
| 146 | + if( FAILED(pDSBuffer[id][0]->Lock(0, WavSize, &pBuffer, &dwBufferSize, NULL, NULL, 0) ) ){ | |
| 147 | + return -1; //バッファのロック失敗 | |
| 148 | + } | |
| 149 | + | |
| 150 | + //一時領域を確保 | |
| 151 | + BYTE* pWavData; | |
| 152 | + int dwSize = dwBufferSize; | |
| 153 | + if( dwSize > WavSize ){ dwSize = WavSize; } | |
| 154 | + pWavData = new BYTE[dwSize]; | |
| 155 | + if( pWavData == NULL ){ | |
| 156 | + //WAVEファイルを読み込むメモリーが確保できない | |
| 157 | + return -1; | |
| 158 | + } | |
| 159 | + | |
| 160 | + //波形データを取り込む | |
| 161 | + FILE* fp; | |
| 162 | + fp = fopen(filename,"rb"); | |
| 163 | + fseek(fp, Wavoffset, SEEK_SET); | |
| 164 | + fread(pWavData, 1, dwSize, fp); | |
| 165 | + fclose(fp); | |
| 166 | + | |
| 167 | + //一時領域からセカンダリバッファーへコピー | |
| 168 | + for(int i=0; i<dwSize; i++){ | |
| 169 | + *((BYTE*)pBuffer+i) = *((BYTE*) pWavData+i); | |
| 170 | + } | |
| 171 | + | |
| 172 | + //ロック解除 | |
| 173 | + pDSBuffer[id][0]->Unlock(pBuffer, dwBufferSize, NULL, 0); | |
| 174 | + | |
| 175 | + //一時領域を解放 | |
| 176 | + delete pWavData; | |
| 177 | + | |
| 178 | + //セカンダリバッファーのコピーを作成 | |
| 179 | + for(int i=1; i<MAX_SOUNDLISTS; i++){ | |
| 180 | + if( pDSound->DuplicateSoundBuffer(pDSBuffer[id][0], &(pDSBuffer[id][i])) != DS_OK ){ | |
| 181 | + CleanupSound(id); | |
| 182 | + return -1; | |
| 183 | + } | |
| 184 | + } | |
| 185 | + | |
| 186 | + //音量最小で一度再生しておく | |
| 187 | + pDSBuffer[id][0]->SetVolume(DSBVOLUME_MIN); | |
| 188 | + pDSBuffer[id][0]->Play(NULL, 0, NULL); | |
| 189 | + | |
| 190 | + return id; | |
| 191 | +} | |
| 192 | + | |
| 193 | +//! サウンドを再生(非3D再生) | |
| 194 | +//! @param id 認識番号 | |
| 195 | +//! @param volume 再生ボリューム | |
| 196 | +//! @param pan <無効> | |
| 197 | +//! @return 成功:1 失敗:0 | |
| 198 | +//! @note 用途:プレイヤー自身が発生する音・ゲーム空間全体で均一に鳴らす音・BGM | |
| 199 | +int SoundControl::PlaySound(int id, int volume, int pan) | |
| 200 | +{ | |
| 201 | + if( pDSound == NULL ){ return 0; } | |
| 202 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return 0; } | |
| 203 | + if( pDSBuffer[id][0] == NULL ){ return 0; } | |
| 204 | + | |
| 205 | + DWORD status = 0; | |
| 206 | + | |
| 207 | + for(int i=0; i<MAX_SOUNDLISTS; i++){ | |
| 208 | + //再生状況を取得 | |
| 209 | + pDSBuffer[id][i]->GetStatus(&status); | |
| 210 | + | |
| 211 | + //サウンドが停止中ならば | |
| 212 | + if( (status & DSBSTATUS_PLAYING) == 0x00 ){ | |
| 213 | + LPDIRECTSOUND3DBUFFER pDS3DBuffer; | |
| 214 | + DWORD status = 0; | |
| 215 | + if( FAILED(pDSBuffer[id][i]->QueryInterface(IID_IDirectSound3DBuffer8,(VOID**)&pDS3DBuffer)) ){ | |
| 216 | + //IDirectSound3DBuffer8を取得できない | |
| 217 | + return 0; | |
| 218 | + } | |
| 219 | + | |
| 220 | + //3D再生を無効 | |
| 221 | + pDS3DBuffer->SetMode(DS3DMODE_DISABLE, DS3D_IMMEDIATE); | |
| 222 | + | |
| 223 | + //ボリュームを設定し再生 | |
| 224 | + pDSBuffer[id][i]->SetVolume( GetDSVolume(volume) ); | |
| 225 | + pDSBuffer[id][i]->Play(NULL, 0, NULL); | |
| 226 | + return 1; | |
| 227 | + } | |
| 228 | + } | |
| 229 | + | |
| 230 | + return 0; | |
| 231 | +} | |
| 232 | + | |
| 233 | +//! サウンドを再生(3D再生) | |
| 234 | +//! @param id 認識番号 | |
| 235 | +//! @param x 音源のX座標 | |
| 236 | +//! @param y 音源のY座標 | |
| 237 | +//! @param z 音源のZ座標 | |
| 238 | +//! @param volume 再生ボリューム | |
| 239 | +//! @return 成功:1 失敗:0 | |
| 240 | +//! @note 用途:絶対的な位置を持ち距離により減衰する、一般的な効果音。 | |
| 241 | +int SoundControl::Play3DSound(int id, float x, float y, float z, int volume) | |
| 242 | +{ | |
| 243 | + if( pDSound == NULL ){ return 0; } | |
| 244 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return 0; } | |
| 245 | + if( pDSBuffer[id][0] == NULL ){ return 0; } | |
| 246 | + | |
| 247 | + DWORD status = 0; | |
| 248 | + | |
| 249 | + for(int i=0; i<MAX_SOUNDLISTS; i++){ | |
| 250 | + //再生状況を取得 | |
| 251 | + pDSBuffer[id][i]->GetStatus(&status); | |
| 252 | + | |
| 253 | + //サウンドが停止中ならば | |
| 254 | + if( (status & DSBSTATUS_PLAYING) == 0x00 ){ | |
| 255 | + | |
| 256 | + LPDIRECTSOUND3DBUFFER pDS3DBuffer; | |
| 257 | + if( FAILED(pDSBuffer[id][i]->QueryInterface(IID_IDirectSound3DBuffer8,(VOID**)&pDS3DBuffer)) ){ | |
| 258 | + //IDirectSound3DBuffer8を取得できない | |
| 259 | + return 0; | |
| 260 | + } | |
| 261 | + | |
| 262 | + //最小距離と最大距離の設定 | |
| 263 | + pDS3DBuffer->SetMinDistance(1, DS3D_IMMEDIATE); | |
| 264 | + pDS3DBuffer->SetMaxDistance(MAX_SOUNDDIST, DS3D_IMMEDIATE); | |
| 265 | + | |
| 266 | + //音源の座標を設定 | |
| 267 | + pDS3DBuffer->SetPosition(x, y, z, DS3D_IMMEDIATE); | |
| 268 | + | |
| 269 | + //3D再生を有効 | |
| 270 | + pDS3DBuffer->SetMode(DS3DMODE_NORMAL, DS3D_IMMEDIATE); | |
| 271 | + | |
| 272 | + //ボリュームを設定し再生 | |
| 273 | + pDSBuffer[id][i]->SetVolume( GetDSVolume(volume) ); | |
| 274 | + pDSBuffer[id][i]->Play(NULL, 0, NULL); | |
| 275 | + return 1; | |
| 276 | + } | |
| 277 | + } | |
| 278 | + | |
| 279 | + return 0; | |
| 280 | +} | |
| 281 | + | |
| 282 | +//! サウンドを解放 | |
| 283 | +//! @param id 認識番号 | |
| 284 | +void SoundControl::CleanupSound(int id) | |
| 285 | +{ | |
| 286 | + if( pDSound == NULL ){ return; } | |
| 287 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return; } | |
| 288 | + if( pDSBuffer[id][0] == NULL ){ return; } | |
| 289 | + | |
| 290 | + //対象の全セカンダリバッファーを解放 | |
| 291 | + for(int i=0; i<MAX_SOUNDLISTS; i++){ | |
| 292 | + if( pDSBuffer[id][i] != NULL ){ pDSBuffer[id][i]->Release(); } | |
| 293 | + pDSBuffer[id][i] = NULL; | |
| 294 | + } | |
| 295 | +} | |
| 296 | + | |
| 297 | +//! Waveファイルの情報を調べる | |
| 298 | +//! @param filename ファイル名 | |
| 299 | +//! @param filesize ファイルサイズを受け取るポインタ | |
| 300 | +//! @param fileoffset データオフセットを受け取るポインタ | |
| 301 | +//! @param pwfex WAVEFORMATEX型を受け取る二重ポインタ | |
| 302 | +//! @return 成功:false 失敗:true | |
| 303 | +bool SoundControl::CheckSoundFile(char* filename, int *filesize, int *fileoffset, WAVEFORMATEX** pwfex) | |
| 304 | +{ | |
| 305 | + HMMIO hMmio = NULL; | |
| 306 | + MMCKINFO ckInfo; | |
| 307 | + MMCKINFO riffckInfo; | |
| 308 | + PCMWAVEFORMAT pcmWaveFormat; | |
| 309 | + bool errorflag; | |
| 310 | + | |
| 311 | + hMmio = mmioOpen(filename, NULL, MMIO_ALLOCBUF | MMIO_READ); | |
| 312 | + if( hMmio == NULL ){ | |
| 313 | + //ファイルがない | |
| 314 | + return true; | |
| 315 | + } | |
| 316 | + | |
| 317 | + //WAVEファイルか確認 | |
| 318 | + errorflag = true; | |
| 319 | + if( mmioDescend( hMmio, &riffckInfo, NULL, 0 ) == MMSYSERR_NOERROR ){ | |
| 320 | + if( (mmioFOURCC('R','I','F','F') == riffckInfo.ckid) && (mmioFOURCC('W','A','V','E') == riffckInfo.fccType) ){ | |
| 321 | + errorflag = false; | |
| 322 | + } | |
| 323 | + } | |
| 324 | + if( errorflag == true ){ | |
| 325 | + mmioClose(hMmio, MMIO_FHOPEN); | |
| 326 | + return true; //WAVEファイルでない | |
| 327 | + } | |
| 328 | + | |
| 329 | + //フォーマット情報取得 | |
| 330 | + ckInfo.ckid = mmioFOURCC('f','m','t',' '); | |
| 331 | + if( mmioDescend(hMmio, &ckInfo, &riffckInfo, MMIO_FINDCHUNK) == MMSYSERR_NOERROR ){ | |
| 332 | + if( mmioRead(hMmio, (HPSTR) &pcmWaveFormat, sizeof(pcmWaveFormat)) == sizeof(pcmWaveFormat) ){ | |
| 333 | + if( pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM ){ | |
| 334 | + if( pcmWaveFormat.wf.nChannels == 1 ){ //3D | |
| 335 | + *pwfex = (WAVEFORMATEX*)new CHAR[ sizeof(WAVEFORMATEX) ]; | |
| 336 | + if( *pwfex != NULL ){ | |
| 337 | + memcpy( *pwfex, &pcmWaveFormat, sizeof(pcmWaveFormat) ); | |
| 338 | + //pwfex->cbSize = 0; | |
| 339 | + } | |
| 340 | + } | |
| 341 | + } | |
| 342 | + } | |
| 343 | + } | |
| 344 | + if( pwfex == NULL ){ | |
| 345 | + mmioClose(hMmio, MMIO_FHOPEN); | |
| 346 | + return true; //ファイルフォーマットが対応してない | |
| 347 | + } | |
| 348 | + if( mmioAscend(hMmio, &ckInfo, 0) != MMSYSERR_NOERROR ){ | |
| 349 | + delete pwfex; | |
| 350 | + mmioClose(hMmio, MMIO_FHOPEN); | |
| 351 | + return true; //チャンク制御失敗 | |
| 352 | + } | |
| 353 | + | |
| 354 | + //データ領域を調べる | |
| 355 | + ckInfo.ckid = mmioFOURCC('d','a','t','a'); | |
| 356 | + if( mmioDescend(hMmio, &ckInfo, &riffckInfo, MMIO_FINDCHUNK) != MMSYSERR_NOERROR ){ | |
| 357 | + mmioClose(hMmio, MMIO_FHOPEN); | |
| 358 | + return true; //ファイルフォーマットが対応してない | |
| 359 | + } | |
| 360 | + | |
| 361 | + mmioClose(hMmio, MMIO_FHOPEN); | |
| 362 | + | |
| 363 | + *filesize = ckInfo.cksize; | |
| 364 | + *fileoffset = riffckInfo.dwDataOffset + sizeof(FOURCC); | |
| 365 | + return false; | |
| 366 | +} | |
| 367 | + | |
| 368 | +//! SetVolume()用 1/100 dB (デシベル) を計算 | |
| 369 | +//! @param volume 音量(0〜155) | |
| 370 | +//! @return 1/100 dB (デシベル) | |
| 371 | +int SoundControl::GetDSVolume(int volume) | |
| 372 | +{ | |
| 373 | + if( volume <= 0 ){ return DSBVOLUME_MIN; } | |
| 374 | + if( volume >= 155 ){ return DSBVOLUME_MAX; } | |
| 375 | + | |
| 376 | + float volume2 = 1.0f/155 * volume; | |
| 377 | + return (int)(10.0f * (log10f(volume2) / log10f(2))); | |
| 378 | +} | |
| 379 | + | |
| 380 | +#else | |
| 381 | + | |
| 382 | +//! コンストラクタ | |
| 383 | +SoundControl::SoundControl() | |
| 384 | +{ | |
| 385 | + lib = NULL; | |
| 386 | + | |
| 387 | + //使用済みフラグを初期化 | |
| 388 | + for(int i=0; i<MAX_LOADSOUND; i++){ | |
| 389 | + useflag[i] = false; | |
| 390 | + } | |
| 391 | +} | |
| 392 | + | |
| 393 | +//! ディストラクタ | |
| 394 | +SoundControl::~SoundControl() | |
| 395 | +{ | |
| 396 | + if( lib == NULL ){ return; } | |
| 397 | + | |
| 398 | + //使用中のサウンドデータ数を数える | |
| 399 | + int total = 0; | |
| 400 | + for(int i=0; i<MAX_LOADSOUND; i++){ | |
| 401 | + if( useflag[i] == true ){ total += 1; } | |
| 402 | + } | |
| 403 | + | |
| 404 | + //サウンドデータを開放し、DLLを終了 | |
| 405 | + DSrelease(total); | |
| 406 | + DSend(); | |
| 407 | + | |
| 408 | + //DLLを開放 | |
| 409 | + FreeLibrary(lib); | |
| 410 | +} | |
| 411 | + | |
| 412 | +//! 初期化@n | |
| 413 | +//! (DLLのロード、初期化関数の実行) | |
| 414 | +//! @param hWnd ウィンドウハンドル | |
| 415 | +//! @return 成功:0 失敗:1 | |
| 416 | +int SoundControl::InitSound(HWND hWnd) | |
| 417 | +{ | |
| 418 | + if( lib != NULL ){ | |
| 419 | + return 1; | |
| 420 | + } | |
| 421 | + | |
| 422 | + //DLLを読み込む | |
| 423 | + lib = LoadLibrary("ezds.dll"); | |
| 424 | + if (lib == NULL){ | |
| 425 | + return 1; | |
| 426 | + } | |
| 427 | + | |
| 428 | + //関数を割り当て | |
| 429 | + DSver = GetProcAddress(lib, "DSver"); | |
| 430 | + DSinit = (FARPROCH)GetProcAddress(lib, "DSinit"); | |
| 431 | + DSend = GetProcAddress(lib, "DSend"); | |
| 432 | + DSload = (FARPROCCI)GetProcAddress(lib, "DSload"); | |
| 433 | + DSplay = (FARPROCIII)GetProcAddress(lib, "DSplay"); | |
| 434 | + DSrelease = (FARPROCI)GetProcAddress(lib, "DSrelease"); | |
| 435 | + | |
| 436 | + //DLL初期化を実行 | |
| 437 | + if( DSinit(hWnd) == 0 ){ | |
| 438 | + //DLLを開放 | |
| 439 | + FreeLibrary(lib); | |
| 440 | + lib = NULL; | |
| 441 | + //return 1; | |
| 442 | + } | |
| 443 | + | |
| 444 | + return 0; | |
| 445 | +} | |
| 446 | + | |
| 447 | +//! 再生音量を設定 | |
| 448 | +//! @param volume 再生音量 (0.0=無音 1.0=100%) | |
| 449 | +void SoundControl::SetVolume(float volume) | |
| 450 | +{ | |
| 451 | + mastervolume = volume; | |
| 452 | +} | |
| 453 | + | |
| 454 | +//! カメラの座標と角度を設定 | |
| 455 | +//! @param x カメラのX座標 | |
| 456 | +//! @param y カメラのY座標 | |
| 457 | +//! @param z カメラのZ座標 | |
| 458 | +//! @param rx カメラのX軸角度 (予約) | |
| 459 | +//! @warning 毎フレーム呼び出して、最新のカメラ座標を設定(適用)してください。 | |
| 460 | +void SoundControl::SetCamera(float x, float y, float z, float rx) | |
| 461 | +{ | |
| 462 | + camera_x = x; | |
| 463 | + camera_y = y; | |
| 464 | + camera_z = z; | |
| 465 | + camera_rx = rx; | |
| 466 | +} | |
| 467 | + | |
| 468 | +//! サウンドを読み込む | |
| 469 | +//! @param filename ファイル名 | |
| 470 | +//! @return 成功:0以上の認識番号 失敗:-1 | |
| 471 | +int SoundControl::LoadSound(char* filename) | |
| 472 | +{ | |
| 473 | + if( lib == NULL ){ return -1; } | |
| 474 | + | |
| 475 | + //使用していないデータ番号を探す | |
| 476 | + for(int i=0; i<MAX_LOADSOUND; i++){ | |
| 477 | + if( useflag[i] == false ){ | |
| 478 | + | |
| 479 | + //読み込みを試みる | |
| 480 | + if( DSload(filename, i) == 0 ){ return -1; } | |
| 481 | + | |
| 482 | + //使用中を新たすフラグをセット | |
| 483 | + useflag[i] = true; | |
| 484 | + return i; | |
| 485 | + } | |
| 486 | + } | |
| 487 | + | |
| 488 | + return -1; | |
| 489 | +} | |
| 490 | + | |
| 491 | +//! サウンドを再生(非3D再生DLL呼び出し) | |
| 492 | +//! @param id 認識番号 | |
| 493 | +//! @param volume 再生ボリューム | |
| 494 | +//! @param pan パン(左右バランス) | |
| 495 | +//! @return 成功:1 失敗:0 | |
| 496 | +//! @note 用途:プレイヤー自身が発生する音・ゲーム空間全体で均一に鳴らす音・BGM | |
| 497 | +int SoundControl::PlaySound(int id, int volume, int pan) | |
| 498 | +{ | |
| 499 | + if( lib == NULL ){ return 0; } | |
| 500 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return 0; } | |
| 501 | + if( useflag[id] == false ){ return 0; } | |
| 502 | + | |
| 503 | + //サウンドを再生 | |
| 504 | + return DSplay(id, (int)(mastervolume * volume), pan); | |
| 505 | +} | |
| 506 | + | |
| 507 | +//! サウンドを再生(3D再生) | |
| 508 | +//! @param id 認識番号 | |
| 509 | +//! @param x 音源のX座標 | |
| 510 | +//! @param y 音源のY座標 | |
| 511 | +//! @param z 音源のZ座標 | |
| 512 | +//! @param volume 再生ボリューム | |
| 513 | +//! @return 成功:1 失敗:0 | |
| 514 | +//! @note 用途:絶対的な位置を持ち距離により減衰する、一般的な効果音。 | |
| 515 | +int SoundControl::Play3DSound(int id, float x, float y, float z, int volume) | |
| 516 | +{ | |
| 517 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return 0; } | |
| 518 | + if( useflag[id] == false ){ return 0; } | |
| 519 | + | |
| 520 | + float dist; | |
| 521 | + int playvolume; | |
| 522 | + int pan = 0; | |
| 523 | + | |
| 524 | + //距離による再生音量決定 | |
| 525 | + if( CheckSourceDist(x, y, z, false, &dist) == false ){ | |
| 526 | + return 0; | |
| 527 | + } | |
| 528 | + playvolume = CalculationVolume(volume, dist, false); | |
| 529 | + | |
| 530 | + /* | |
| 531 | + //左右のパン(再生バランス)の決定 | |
| 532 | + float vx = x - camera_x; | |
| 533 | + float vz = z - camera_z; | |
| 534 | + float rx = (atan2(vz, vx) - camera_rx) * -1; | |
| 535 | + for(; rx > (float)M_PI; rx -= (float)M_PI*2){} | |
| 536 | + for(; rx < (float)M_PI*-1; rx += (float)M_PI*2){} | |
| 537 | + pan = (int)((float)10 / M_PI * rx); | |
| 538 | + */ | |
| 539 | + | |
| 540 | + //DLL呼び出し | |
| 541 | + return PlaySound(id, playvolume, pan); | |
| 542 | +} | |
| 543 | + | |
| 544 | +//! サウンドを解放 | |
| 545 | +//! @param id 認識番号 | |
| 546 | +void SoundControl::CleanupSound(int id) | |
| 547 | +{ | |
| 548 | + if( lib == NULL ){ return; } | |
| 549 | + if( (id < 0)||(MAX_LOADSOUND -1 < id) ){ return; } | |
| 550 | + if( useflag[id] == false ){ return; } | |
| 551 | + | |
| 552 | + //読み込みを意図的に失敗させ、強制的に初期化 | |
| 553 | + DSload("", id); | |
| 554 | + | |
| 555 | + //使用中フラグを解除 | |
| 556 | + useflag[id] = false; | |
| 557 | +} | |
| 558 | + | |
| 559 | +//! 音源との距離を調べる | |
| 560 | +//! @param x 音源のX座標 | |
| 561 | +//! @param y 音源のY座標 | |
| 562 | +//! @param z 音源のZ座標 | |
| 563 | +//! @param snear 近距離音源 | |
| 564 | +//! @param out_dist 距離 | |
| 565 | +//! @return 有効(内):true 無効(外):false | |
| 566 | +bool SoundControl::CheckSourceDist(float x, float y, float z, bool snear, float *out_dist) | |
| 567 | +{ | |
| 568 | + float dx, dy ,dz, dist; | |
| 569 | + int max_dist; | |
| 570 | + | |
| 571 | + if( snear == false ){ | |
| 572 | + max_dist = MAX_SOUNDDIST; | |
| 573 | + } | |
| 574 | + else{ | |
| 575 | + max_dist = 30; | |
| 576 | + } | |
| 577 | + | |
| 578 | + dx = camera_x - x; | |
| 579 | + dy = camera_y - y; | |
| 580 | + dz = camera_z - z; | |
| 581 | + dist = dx*dx + dy*dy + dz*dz; | |
| 582 | + if( dist > max_dist * max_dist ){ | |
| 583 | + *out_dist = 0.0f; | |
| 584 | + return false; | |
| 585 | + } | |
| 586 | + | |
| 587 | + *out_dist = sqrt(dist); | |
| 588 | + return true; | |
| 589 | +} | |
| 590 | + | |
| 591 | +//! 音量を計算 | |
| 592 | +//! @param MaxVolume 音源の最大音量 | |
| 593 | +//! @param dist 音源との距離 | |
| 594 | +//! @param snear 近距離音源 | |
| 595 | +int SoundControl::CalculationVolume(int MaxVolume, float dist, bool snear) | |
| 596 | +{ | |
| 597 | + int max_dist; | |
| 598 | + if( snear == false ){ | |
| 599 | + max_dist = MAX_SOUNDDIST; | |
| 600 | + } | |
| 601 | + else{ | |
| 602 | + max_dist = 30; | |
| 603 | + } | |
| 604 | + return (int)( (float)MaxVolume/max_dist*dist*-1 + MaxVolume ); | |
| 605 | +} | |
| 606 | + | |
| 607 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,1832 @@ | ||
| 1 | +//! @file ai.cpp | |
| 2 | +//! @brief AIcontrolクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "ai.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +AIcontrol::AIcontrol(class ObjectManager *in_ObjMgr, class human *in_ctrlhuman, class BlockDataInterface *in_blocks, class PointDataInterface *in_Points, class ParameterInfo *in_Param, class Collision *in_CollD, class SoundManager *in_GameSound) | |
| 36 | +{ | |
| 37 | + ObjMgr = in_ObjMgr; | |
| 38 | + ctrlhuman = in_ctrlhuman; | |
| 39 | + blocks = in_blocks; | |
| 40 | + Points = in_Points; | |
| 41 | + Param = in_Param; | |
| 42 | + CollD = in_CollD; | |
| 43 | + GameSound = in_GameSound; | |
| 44 | + | |
| 45 | + battlemode = AI_NORMAL; | |
| 46 | + movemode = AI_WAIT; | |
| 47 | + target_pointid = -1; | |
| 48 | + target_posx = 0.0f; | |
| 49 | + target_posz = 0.0f; | |
| 50 | + target_rx = 0.0f; | |
| 51 | + total_move = 0.0f; | |
| 52 | + waitcnt = 0; | |
| 53 | + movejumpcnt = 1*((int)GAMEFPS); | |
| 54 | + gotocnt = 0; | |
| 55 | + moveturn_mode = 0; | |
| 56 | + longattack = false; | |
| 57 | +} | |
| 58 | + | |
| 59 | +//! ディストラクタ | |
| 60 | +AIcontrol::~AIcontrol() | |
| 61 | +{} | |
| 62 | + | |
| 63 | +//! 対象クラスを設定 | |
| 64 | +//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。 | |
| 65 | +void AIcontrol::SetClass(class ObjectManager *in_ObjMgr, class human *in_ctrlhuman, class BlockDataInterface *in_blocks, class PointDataInterface *in_Points, class ParameterInfo *in_Param, class Collision *in_CollD, class SoundManager *in_GameSound) | |
| 66 | +{ | |
| 67 | + ObjMgr = in_ObjMgr; | |
| 68 | + ctrlhuman = in_ctrlhuman; | |
| 69 | + blocks = in_blocks; | |
| 70 | + Points = in_Points; | |
| 71 | + Param = in_Param; | |
| 72 | + CollD = in_CollD; | |
| 73 | + GameSound = in_GameSound; | |
| 74 | +} | |
| 75 | + | |
| 76 | +//! ランダムな整数値を返す | |
| 77 | +//! @param num 範囲 | |
| 78 | +//! @return 0〜num-1 | |
| 79 | +int AIcontrol::random(int num) | |
| 80 | +{ | |
| 81 | + return GetRand(num); | |
| 82 | +} | |
| 83 | + | |
| 84 | +//! 人を検索 | |
| 85 | +//! @param in_p4 検索する人の第4パラメータ(認識番号) | |
| 86 | +//! @param out_x X座標を受け取るポインタ | |
| 87 | +//! @param out_z Z座標を受け取るポインタ | |
| 88 | +//! @return 成功:1 失敗:0 | |
| 89 | +int AIcontrol::SearchHumanPos(signed char in_p4, float *out_x, float *out_z) | |
| 90 | +{ | |
| 91 | + float x, z; | |
| 92 | + human* thuman; | |
| 93 | + | |
| 94 | + //人を検索してクラスを取得 | |
| 95 | + thuman = ObjMgr->SearchHuman(in_p4); | |
| 96 | + if( thuman == NULL ){ return 0; } | |
| 97 | + | |
| 98 | + //X・Z座標を取得 | |
| 99 | + thuman->GetPosData(&x, NULL, &z, NULL); | |
| 100 | + *out_x = x; | |
| 101 | + *out_z = z; | |
| 102 | + return 1; | |
| 103 | +} | |
| 104 | + | |
| 105 | +//! 目標地点に移動しているか確認 | |
| 106 | +//! @return 到達:true 非到達:false | |
| 107 | +bool AIcontrol::CheckTargetPos() | |
| 108 | +{ | |
| 109 | + //距離を算出 | |
| 110 | + float x = posx - target_posx; | |
| 111 | + float z = posz - target_posz; | |
| 112 | + float r = x * x + z * z; | |
| 113 | + | |
| 114 | + if( movemode == AI_TRACKING ){ //追尾中なら | |
| 115 | + if( r < AI_ARRIVALDIST_TRACKING * AI_ARRIVALDIST_TRACKING ){ | |
| 116 | + return true; | |
| 117 | + } | |
| 118 | + } | |
| 119 | + else{ //それ以外なら | |
| 120 | + if( r < (AI_ARRIVALDIST_PATH * AI_ARRIVALDIST_PATH) ){ | |
| 121 | + return true; | |
| 122 | + } | |
| 123 | + } | |
| 124 | + | |
| 125 | + return false; | |
| 126 | +} | |
| 127 | + | |
| 128 | +//! 目標地点を検索 | |
| 129 | +//! @param next 次を検索する | |
| 130 | +//! @return 完了:true 失敗:false | |
| 131 | +bool AIcontrol::SearchTarget(bool next) | |
| 132 | +{ | |
| 133 | + //ポイントの情報を取得 | |
| 134 | + pointdata pdata; | |
| 135 | + if( Points->Getdata(&pdata, target_pointid) != 0 ){ | |
| 136 | + movemode = AI_NULL; | |
| 137 | + return false; | |
| 138 | + } | |
| 139 | + | |
| 140 | + int nextpointp4; | |
| 141 | + | |
| 142 | + //次のポイントを検索するなら | |
| 143 | + if( next == true ){ | |
| 144 | + nextpointp4 = pdata.p3; | |
| 145 | + | |
| 146 | + //ランダムパス処理 | |
| 147 | + if( pdata.p1 == 8 ){ | |
| 148 | + if( random(2) == 0 ){ | |
| 149 | + nextpointp4 = pdata.p2; | |
| 150 | + } | |
| 151 | + else{ | |
| 152 | + nextpointp4 = pdata.p3; | |
| 153 | + } | |
| 154 | + movemode = AI_RANDOM; | |
| 155 | + } | |
| 156 | + | |
| 157 | + //ポイントを検索 | |
| 158 | + if( Points->SearchPointdata(&pdata, 0x08, 0, 0, 0, nextpointp4, 0) == 0 ){ | |
| 159 | + return false; | |
| 160 | + } | |
| 161 | + } | |
| 162 | + | |
| 163 | + //ランダムパスなら次へ | |
| 164 | + if( pdata.p1 == 8 ){ | |
| 165 | + target_pointid = pdata.id; | |
| 166 | + movemode = AI_RANDOM; | |
| 167 | + return false; | |
| 168 | + } | |
| 169 | + | |
| 170 | + //人なら座標を取得 | |
| 171 | + if( (pdata.p1 == 1)||(pdata.p1 == 6) ){ | |
| 172 | + SearchHumanPos(pdata.p4, &target_posx, &target_posz); | |
| 173 | + return true; | |
| 174 | + } | |
| 175 | + | |
| 176 | + //移動パスなら〜 | |
| 177 | + if( pdata.p1 == 3 ){ | |
| 178 | + //情報適用 | |
| 179 | + target_pointid = pdata.id; | |
| 180 | + target_posx = pdata.x; | |
| 181 | + target_posz = pdata.z; | |
| 182 | + target_rx = pdata.r; | |
| 183 | + | |
| 184 | + //移動ステート設定 | |
| 185 | + switch(pdata.p2){ | |
| 186 | + case 0: movemode = AI_WALK; break; | |
| 187 | + case 1: movemode = AI_RUN; break; | |
| 188 | + case 2: movemode = AI_WAIT; break; | |
| 189 | + case 3: | |
| 190 | + movemode = AI_TRACKING; | |
| 191 | + if( next == true ){ | |
| 192 | + nextpointp4 = pdata.p3; | |
| 193 | + | |
| 194 | + //ポイント(人)の情報を取得 | |
| 195 | + if( Points->SearchPointdata(&pdata, 0x08, 0, 0, 0, nextpointp4, 0) == 0 ){ | |
| 196 | + return false; | |
| 197 | + } | |
| 198 | + | |
| 199 | + //情報保存 | |
| 200 | + target_pointid = pdata.id; | |
| 201 | + target_posx = pdata.x; | |
| 202 | + target_posz = pdata.z; | |
| 203 | + } | |
| 204 | + break; | |
| 205 | + case 4: movemode = AI_WAIT; break; | |
| 206 | + case 5: movemode = AI_STOP; break; | |
| 207 | + case 6: movemode = AI_GRENADE; break; | |
| 208 | + case 7: movemode = AI_RUN2; break; | |
| 209 | + default: break; | |
| 210 | + } | |
| 211 | + return true; | |
| 212 | + } | |
| 213 | + | |
| 214 | + movemode = AI_NULL; | |
| 215 | + return false; | |
| 216 | +} | |
| 217 | + | |
| 218 | +//! 目標地点に移動 | |
| 219 | +void AIcontrol::MoveTarget() | |
| 220 | +{ | |
| 221 | + float x = posx - target_posx; | |
| 222 | + float z = posz - target_posz; | |
| 223 | + float r = x * x + z * z; | |
| 224 | + float atan; | |
| 225 | + int paramid; | |
| 226 | + HumanParameter Paraminfo; | |
| 227 | + bool zombie; | |
| 228 | + | |
| 229 | + //ゾンビかどうか判定 | |
| 230 | + ctrlhuman->GetParamData(¶mid, NULL, NULL, NULL); | |
| 231 | + Param->GetHuman(paramid, &Paraminfo); | |
| 232 | + if( Paraminfo.type == 2 ){ | |
| 233 | + zombie = true; | |
| 234 | + } | |
| 235 | + else{ | |
| 236 | + zombie = false; | |
| 237 | + } | |
| 238 | + | |
| 239 | + //目標地点への角度を求める | |
| 240 | + atan = atan2(x, z) - rx + (float)M_PI; | |
| 241 | + for(; atan > (float)M_PI; atan -= (float)M_PI*2){} | |
| 242 | + for(; atan < (float)M_PI*-1; atan += (float)M_PI*2){} | |
| 243 | + | |
| 244 | + //大きな差があれば少しづつ旋回するだけ | |
| 245 | + if( atan > AI_TURNRAD ){ | |
| 246 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 247 | + } | |
| 248 | + if( atan < AI_TURNRAD*-1 ){ | |
| 249 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 250 | + } | |
| 251 | + | |
| 252 | + //微々たる差なら一気に向く | |
| 253 | + if( (atan <= AI_TURNRAD) && (atan >= AI_TURNRAD*-1) ){ | |
| 254 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 255 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 256 | + rx += atan; | |
| 257 | + } | |
| 258 | + | |
| 259 | + //前進する | |
| 260 | + if( zombie == true ){ | |
| 261 | + if( abs(atan) < (float)M_PI/18*2 ){ | |
| 262 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 263 | + } | |
| 264 | + } | |
| 265 | + else if( battlemode == AI_CAUTION ){ | |
| 266 | + if( abs(atan) < (float)M_PI/18*5 ){ | |
| 267 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 268 | + } | |
| 269 | + } | |
| 270 | + else if( movemode == AI_WALK ){ | |
| 271 | + if( abs(atan) < (float)M_PI/180*6 ){ | |
| 272 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 273 | + } | |
| 274 | + } | |
| 275 | + else if( (movemode == AI_RUN)||(movemode == AI_RUN2) ){ | |
| 276 | + if( abs(atan) < (float)M_PI/18*5 ){ | |
| 277 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 278 | + } | |
| 279 | + } | |
| 280 | + else if( (movemode == AI_WAIT)||(movemode == AI_STOP) ){ | |
| 281 | + if( abs(atan) < (float)M_PI/180*6 ){ | |
| 282 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 283 | + } | |
| 284 | + } | |
| 285 | + else{ //movemode == AI_TRACKING | |
| 286 | + if( abs(atan) < (float)M_PI/18*2 ){ | |
| 287 | + if( r < (AI_ARRIVALDIST_WALKTRACKING * AI_ARRIVALDIST_WALKTRACKING) ){ | |
| 288 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 289 | + } | |
| 290 | + else{ | |
| 291 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 292 | + } | |
| 293 | + } | |
| 294 | + } | |
| 295 | + | |
| 296 | + //ジャンプ | |
| 297 | + if( random(128) == 0 ){ | |
| 298 | + MoveJump(); | |
| 299 | + } | |
| 300 | + | |
| 301 | + //引っ掛かっていたら、左右への回転をランダムに行う | |
| 302 | + if( random(28) == 0 ){ | |
| 303 | + if( ctrlhuman->GetMovemode(true) != 0 ){ | |
| 304 | + if( ctrlhuman->GetTotalMove() - total_move < 0.1f ){ | |
| 305 | + if( random(2) == 0 ){ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); } | |
| 306 | + else{ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); } | |
| 307 | + } | |
| 308 | + } | |
| 309 | + } | |
| 310 | + total_move = ctrlhuman->GetTotalMove(); | |
| 311 | +} | |
| 312 | + | |
| 313 | +//! 目標地点に移動(優先的な走り用) | |
| 314 | +void AIcontrol::MoveTarget2() | |
| 315 | +{ | |
| 316 | + float x = target_posx - posx; | |
| 317 | + float z = target_posz - posz; | |
| 318 | + float atan, rx2, trx; | |
| 319 | + | |
| 320 | + //人の向き・視点を求める (0.0〜2π) | |
| 321 | + rx2 = rx*-1 + (float)M_PI/2; | |
| 322 | + for(; rx2 > (float)M_PI*2; rx2 -= (float)M_PI*2){} | |
| 323 | + for(; rx2 < 0.0f; rx2 += (float)M_PI*2){} | |
| 324 | + | |
| 325 | + //ポイントまでの角度を求める (0.0〜2π) | |
| 326 | + trx = atan2(z, x); | |
| 327 | + if( trx < 0.0f ){ trx += (float)M_PI*2; } | |
| 328 | + | |
| 329 | + //視点を基準にポイントまでの角度を算出(-π〜π) | |
| 330 | + atan = trx - rx2; | |
| 331 | + for(; atan > (float)M_PI; atan -= (float)M_PI*2){} | |
| 332 | + for(; atan < (float)M_PI*-1; atan += (float)M_PI*2){} | |
| 333 | + | |
| 334 | + //前後移動の処理 | |
| 335 | + if( abs(atan) < (float)M_PI/180*56 ){ | |
| 336 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 337 | + } | |
| 338 | + if( abs(atan) > (float)M_PI/180*123.5f ){ | |
| 339 | + SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 340 | + } | |
| 341 | + | |
| 342 | + //左右移動の処理 | |
| 343 | + if( ((float)M_PI/180*-146 < atan)&&(atan < (float)M_PI/180*-33) ){ | |
| 344 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 345 | + } | |
| 346 | + if( ((float)M_PI/180*33 < atan)&&(atan < (float)M_PI/180*146) ){ | |
| 347 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 348 | + } | |
| 349 | + | |
| 350 | + //ジャンプ | |
| 351 | + if( random(128) == 0 ){ | |
| 352 | + MoveJump(); | |
| 353 | + } | |
| 354 | + | |
| 355 | + //引っ掛かっていたら、左右への回転をランダムに行う | |
| 356 | + if( random(28) == 0 ){ | |
| 357 | + if( ctrlhuman->GetMovemode(true) != 0 ){ | |
| 358 | + if( ctrlhuman->GetTotalMove() - total_move < 0.1f ){ | |
| 359 | + if( random(2) == 0 ){ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); } | |
| 360 | + else{ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); } | |
| 361 | + } | |
| 362 | + } | |
| 363 | + } | |
| 364 | + total_move = ctrlhuman->GetTotalMove(); | |
| 365 | +} | |
| 366 | + | |
| 367 | +//! 前後左右ランダムに移動(攻撃中用) | |
| 368 | +void AIcontrol::MoveRandom() | |
| 369 | +{ | |
| 370 | + int forwardstart, backstart, sidestart; | |
| 371 | + | |
| 372 | + if( longattack == false ){ | |
| 373 | + forwardstart = 80; | |
| 374 | + backstart = 90; | |
| 375 | + sidestart = 70; | |
| 376 | + } | |
| 377 | + else{ | |
| 378 | + forwardstart = 120; | |
| 379 | + backstart = 150; | |
| 380 | + sidestart = 130; | |
| 381 | + } | |
| 382 | + | |
| 383 | + //ランダムに移動を始める | |
| 384 | + if( random(forwardstart) == 0 ){ | |
| 385 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 386 | + } | |
| 387 | + if( random(backstart) == 0 ){ | |
| 388 | + SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 389 | + } | |
| 390 | + if( random(sidestart) == 0 ){ | |
| 391 | + SetFlag(moveturn_mode, AI_CTRL_MOVELEFT); | |
| 392 | + } | |
| 393 | + if( random(sidestart) == 0 ){ | |
| 394 | + SetFlag(moveturn_mode, AI_CTRL_MOVERIGHT); | |
| 395 | + } | |
| 396 | + | |
| 397 | + // 1/3の確率か、移動フラグが設定されていたら | |
| 398 | + if( (random(3) == 0)||(GetFlag(moveturn_mode, (AI_CTRL_MOVEFORWARD | AI_CTRL_MOVEBACKWARD | AI_CTRL_MOVELEFT | AI_CTRL_MOVERIGHT))) ){ | |
| 399 | + float vx, vz; | |
| 400 | + float Dist; | |
| 401 | + | |
| 402 | + if( random(2) == 0 ){ | |
| 403 | + //前方向のベクトルを計算 | |
| 404 | + vx = cos(rx*-1 + (float)M_PI/2); | |
| 405 | + vz = sin(rx*-1 + (float)M_PI/2); | |
| 406 | + if( | |
| 407 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる) | |
| 408 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる) | |
| 409 | + ){ | |
| 410 | + //前進フラグを削除し、後退フラグを設定 | |
| 411 | + DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 412 | + SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 413 | + } | |
| 414 | + | |
| 415 | + //後方向のベクトルを計算 | |
| 416 | + vx = cos(rx*-1 + (float)M_PI/2 + (float)M_PI); | |
| 417 | + vz = sin(rx*-1 + (float)M_PI/2 + (float)M_PI); | |
| 418 | + if( | |
| 419 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる) | |
| 420 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる) | |
| 421 | + ){ | |
| 422 | + //後退フラグを削除し、前進フラグを設定 | |
| 423 | + DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 424 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 425 | + } | |
| 426 | + } | |
| 427 | + else{ | |
| 428 | + // | |
| 429 | + vx = cos(rx*-1); | |
| 430 | + vz = sin(rx*-1); | |
| 431 | + if( | |
| 432 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる) | |
| 433 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる) | |
| 434 | + ){ | |
| 435 | + //右移動フラグを削除し、左移動フラグを設定 | |
| 436 | + DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT); | |
| 437 | + SetFlag(moveturn_mode, AI_CTRL_MOVELEFT); | |
| 438 | + } | |
| 439 | + | |
| 440 | + vx = cos(rx*-1 + (float)M_PI); | |
| 441 | + vz = sin(rx*-1 + (float)M_PI); | |
| 442 | + if( | |
| 443 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる) | |
| 444 | + (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる) | |
| 445 | + ){ | |
| 446 | + //左移動フラグを削除し、右移動フラグを設定 | |
| 447 | + DelFlag(moveturn_mode, AI_CTRL_MOVELEFT); | |
| 448 | + SetFlag(moveturn_mode, AI_CTRL_MOVERIGHT); | |
| 449 | + } | |
| 450 | + } | |
| 451 | + } | |
| 452 | + | |
| 453 | + //攻撃対象がいるなら | |
| 454 | + if( enemyhuman != NULL ){ | |
| 455 | + float tx, ty, tz; | |
| 456 | + | |
| 457 | + enemyhuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 458 | + | |
| 459 | + float x = posx - tx; | |
| 460 | + float y = posy - ty; | |
| 461 | + float z = posz - tz; | |
| 462 | + float r = x * x + y * y + z * z; | |
| 463 | + | |
| 464 | + //敵に近づきすぎたなら後退する | |
| 465 | + if( r < 20.0f * 20.0f ){ | |
| 466 | + DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 467 | + if( random(70) == 0 ){ | |
| 468 | + SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 469 | + } | |
| 470 | + } | |
| 471 | + } | |
| 472 | +} | |
| 473 | + | |
| 474 | +//! その場を見まわす | |
| 475 | +void AIcontrol::TurnSeen() | |
| 476 | +{ | |
| 477 | + int turnstart, turnstop; | |
| 478 | + | |
| 479 | + //回転の開始・終了確率を設定 | |
| 480 | + if( battlemode == AI_ACTION ){ | |
| 481 | + return; | |
| 482 | + } | |
| 483 | + else if( battlemode == AI_CAUTION ){ | |
| 484 | + turnstart = 20; | |
| 485 | + turnstop = 20; | |
| 486 | + } | |
| 487 | + else{ | |
| 488 | + if( movemode == AI_TRACKING ){ turnstart = 65; } | |
| 489 | + else{ turnstart = 85; } | |
| 490 | + turnstop = 18; | |
| 491 | + } | |
| 492 | + | |
| 493 | + //ランダムに回転を始める | |
| 494 | + if( random(turnstart) == 0 ){ | |
| 495 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 496 | + } | |
| 497 | + if( random(turnstart) == 0 ){ | |
| 498 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 499 | + } | |
| 500 | + | |
| 501 | + if( (battlemode == AI_NORMAL)&&(movemode == AI_WAIT) ){ | |
| 502 | + //ランダムにポイントの方を向こうとする | |
| 503 | + //「ポイントの方向を少し重視する」の再現 | |
| 504 | + if( random(80) == 0 ){ | |
| 505 | + float tr; | |
| 506 | + tr = target_rx - rx; | |
| 507 | + for(; tr > (float)M_PI; tr -= (float)M_PI*2){} | |
| 508 | + for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){} | |
| 509 | + | |
| 510 | + if( tr > 0.0f ){ | |
| 511 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 512 | + } | |
| 513 | + if( tr < 0.0f ){ | |
| 514 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 515 | + } | |
| 516 | + } | |
| 517 | + } | |
| 518 | + | |
| 519 | + //回転をランダムに止める | |
| 520 | + if( random(turnstop) == 0 ){ | |
| 521 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 522 | + } | |
| 523 | + if( random(turnstop) == 0 ){ | |
| 524 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 525 | + } | |
| 526 | +} | |
| 527 | + | |
| 528 | +//! 特定の方向を見続ける | |
| 529 | +bool AIcontrol::StopSeen() | |
| 530 | +{ | |
| 531 | + float tr; | |
| 532 | + bool returnflag; | |
| 533 | + | |
| 534 | + tr = target_rx - rx; | |
| 535 | + for(; tr > (float)M_PI; tr -= (float)M_PI*2){} | |
| 536 | + for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){} | |
| 537 | + | |
| 538 | + //大きな差があれば少しづつ旋回するだけ | |
| 539 | + if( tr > AI_TURNRAD ){ | |
| 540 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 541 | + returnflag = false; | |
| 542 | + } | |
| 543 | + if( tr < AI_TURNRAD*-1 ){ | |
| 544 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 545 | + returnflag = false; | |
| 546 | + } | |
| 547 | + | |
| 548 | + //微々たる差なら一気に向ける。 | |
| 549 | + if( (tr <= AI_TURNRAD) && (tr >= AI_TURNRAD*-1) ){ | |
| 550 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 551 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 552 | + rx += tr; | |
| 553 | + returnflag = true; | |
| 554 | + } | |
| 555 | + | |
| 556 | + return returnflag; | |
| 557 | +} | |
| 558 | + | |
| 559 | +//! 進行方向に障害物があればジャンプする | |
| 560 | +bool AIcontrol::MoveJump() | |
| 561 | +{ | |
| 562 | + //立ち止まっていれば処理しない | |
| 563 | + if( ctrlhuman->GetMovemode(true) == 0 ){ return false; } | |
| 564 | + | |
| 565 | + float dist_dummy; | |
| 566 | + | |
| 567 | + float new_posx, new_posy, new_posz; | |
| 568 | + | |
| 569 | + //腰付近のあたり判定 | |
| 570 | + new_posx = posx + cos(rx*-1 + (float)M_PI/2) * (AI_CHECKJUMP_DIST + HUMAN_MAPCOLLISION_R); | |
| 571 | + new_posy = posy + HUMAN_MAPCOLLISION_HEIGTH; | |
| 572 | + new_posz = posz + sin(rx*-1 + (float)M_PI/2) * (AI_CHECKJUMP_DIST + HUMAN_MAPCOLLISION_R); | |
| 573 | + if( CollD->CheckALLBlockInside(new_posx, new_posy, new_posz) == true ){ | |
| 574 | + ctrlhuman->Jump(); | |
| 575 | + return true; | |
| 576 | + } | |
| 577 | + | |
| 578 | + //体全体のあたり判定 | |
| 579 | + new_posx = posx + cos(rx*-1 + (float)M_PI/2) * AI_CHECKJUMP_DIST; | |
| 580 | + new_posy = posy + AI_CHECKJUMP_HEIGHT; | |
| 581 | + new_posz = posz + sin(rx*-1 + (float)M_PI/2) * AI_CHECKJUMP_DIST; | |
| 582 | + if( CollD->CheckALLBlockInside(new_posx, new_posy, new_posz) == true ){ | |
| 583 | + ctrlhuman->Jump(); | |
| 584 | + return true; | |
| 585 | + } | |
| 586 | + else if( CollD->CheckALLBlockIntersectRay(new_posx, new_posy, new_posz, 0.0f, 1.0f, 0.0f, NULL, NULL, &dist_dummy, HUMAN_HEIGTH - AI_CHECKJUMP_HEIGHT) == true ){ | |
| 587 | + ctrlhuman->Jump(); | |
| 588 | + return true; | |
| 589 | + } | |
| 590 | + | |
| 591 | + return false; | |
| 592 | +} | |
| 593 | + | |
| 594 | +//! 攻撃 | |
| 595 | +//! @todo ゾンビの相手を捕まえる処理 | |
| 596 | +void AIcontrol::Action() | |
| 597 | +{ | |
| 598 | + human* EnemyHuman = NULL; | |
| 599 | + int paramid; | |
| 600 | + HumanParameter Paraminfo; | |
| 601 | + bool zombie; | |
| 602 | + float posy2; | |
| 603 | + float tx, ty, tz; | |
| 604 | + | |
| 605 | + EnemyHuman = enemyhuman; | |
| 606 | + | |
| 607 | + //座標を取得 | |
| 608 | + EnemyHuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 609 | + posy2 = posy + VIEW_HEIGHT; | |
| 610 | + ty += VIEW_HEIGHT; | |
| 611 | + | |
| 612 | + //ゾンビかどうか判定 | |
| 613 | + ctrlhuman->GetParamData(¶mid, NULL, NULL, NULL); | |
| 614 | + Param->GetHuman(paramid, &Paraminfo); | |
| 615 | + if( Paraminfo.type == 2 ){ | |
| 616 | + zombie = true; | |
| 617 | + } | |
| 618 | + else{ | |
| 619 | + zombie = false; | |
| 620 | + } | |
| 621 | + | |
| 622 | + //所持している武器の種類を取得 | |
| 623 | + int weaponid = ctrlhuman->GetMainWeaponTypeNO(); | |
| 624 | + | |
| 625 | + float x = posx - tx; | |
| 626 | + float y = posy2 - ty; | |
| 627 | + float z = posz - tz; | |
| 628 | + float r = x * x + z * z; | |
| 629 | + float atan; | |
| 630 | + | |
| 631 | + //目標地点への角度を求める | |
| 632 | + atan = atan2(x, z) - rx + (float)M_PI; | |
| 633 | + for(; atan > (float)M_PI; atan -= (float)M_PI*2){} | |
| 634 | + for(; atan < (float)M_PI*-1; atan += (float)M_PI*2){} | |
| 635 | + | |
| 636 | + //大きな差があれば少しづつ旋回するだけ | |
| 637 | + if( atan > AI_TURNRAD ){ | |
| 638 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 639 | + } | |
| 640 | + if( atan < AI_TURNRAD*-1 ){ | |
| 641 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 642 | + } | |
| 643 | + | |
| 644 | + //微々たる差なら一気に向ける | |
| 645 | + if( (atan <= AI_TURNRAD) && (atan >= AI_TURNRAD*-1) ){ | |
| 646 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 647 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 648 | + rx += atan; | |
| 649 | + rx += (float)M_PI/180 * (random(5) - 2); | |
| 650 | + } | |
| 651 | + | |
| 652 | + //腕の角度 | |
| 653 | + if( zombie == true ){ | |
| 654 | + //ry = 0.0f; | |
| 655 | + | |
| 656 | + //大きな差があれば少しづつ旋回するだけ | |
| 657 | + if( ry < AI_TURNRAD*-1 ){ | |
| 658 | + SetFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 659 | + } | |
| 660 | + if( ry > AI_TURNRAD ){ | |
| 661 | + SetFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 662 | + } | |
| 663 | + | |
| 664 | + //微々たる差なら一気に向ける | |
| 665 | + if( (ry <= AI_TURNRAD) && (ry >= AI_TURNRAD*-1) ){ | |
| 666 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 667 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 668 | + ry = 0.0f; | |
| 669 | + } | |
| 670 | + } | |
| 671 | + else{ | |
| 672 | + float y2 = y; | |
| 673 | + float sqrtr = sqrt(r); | |
| 674 | + float addry; | |
| 675 | + | |
| 676 | + //自分が武器を持っていれば〜 | |
| 677 | + if( weaponid != ID_WEAPON_NONE ){ | |
| 678 | + //敵の移動を見超す | |
| 679 | + /* | |
| 680 | + if( weaponid == ID_WEAPON_GRENADE ){ //手榴弾なら垂直角度(高さ) | |
| 681 | + float scale; | |
| 682 | + if( sqrtr < 200.0f ){ scale = 0.12f; } | |
| 683 | + else{ scale = 0.4f; } | |
| 684 | + y2 += (sqrtr - 200.0f) * scale; | |
| 685 | + } | |
| 686 | + else{ //手榴弾以外なら水平角度 | |
| 687 | + float mx, mz; | |
| 688 | + EnemyHuman->GetMovePos(&mx, NULL, &mz); | |
| 689 | + if( sqrtr < 200.0f ){ rx += atan2(mz * 1.5f, mx * 1.5f); } | |
| 690 | + else{ rx += atan2(sqrtr * mz * 0.12f, sqrtr * mx * 0.12f); } | |
| 691 | + } | |
| 692 | + */ | |
| 693 | + } | |
| 694 | + | |
| 695 | + //自分が手ぶらならば〜 | |
| 696 | + if( weaponid == ID_WEAPON_NONE ){ | |
| 697 | + if( EnemyHuman->GetMainWeaponTypeNO() == ID_WEAPON_NONE ){ //敵も手ぶらならば〜 | |
| 698 | + addry = ARMRAD_NOWEAPON - ry; | |
| 699 | + } | |
| 700 | + else{ //敵が武器を持っていれば〜 | |
| 701 | + addry = (float)M_PI/18*8 - ry; | |
| 702 | + } | |
| 703 | + } | |
| 704 | + else{ | |
| 705 | + addry = atan2(y2, sqrt(r)) * -1 - ry; | |
| 706 | + } | |
| 707 | + | |
| 708 | + //大きな差があれば少しづつ旋回するだけ | |
| 709 | + if( addry > AI_TURNRAD ){ | |
| 710 | + SetFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 711 | + } | |
| 712 | + if( addry < AI_TURNRAD*-1 ){ | |
| 713 | + SetFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 714 | + } | |
| 715 | + | |
| 716 | + //微々たる差なら一気に向ける | |
| 717 | + if( (addry <= AI_TURNRAD) && (addry >= AI_TURNRAD*-1) ){ | |
| 718 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 719 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 720 | + ry += addry; | |
| 721 | + ry += (float)M_PI/180 * (random(5) - 2); | |
| 722 | + } | |
| 723 | + } | |
| 724 | + | |
| 725 | + //ゾンビ以外で手ぶらならば | |
| 726 | + if( zombie == false ){ | |
| 727 | + if( weaponid == ID_WEAPON_NONE ){ | |
| 728 | + //一定の確率で後退する | |
| 729 | + if( random(80) == 0 ){ | |
| 730 | + SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 731 | + } | |
| 732 | + } | |
| 733 | + } | |
| 734 | + | |
| 735 | + | |
| 736 | + if( zombie == true ){ //ゾンビの攻撃 | |
| 737 | + | |
| 738 | + //もし走っていれば、一度歩きに切り替える | |
| 739 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD) ){ | |
| 740 | + DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 741 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 742 | + } | |
| 743 | + | |
| 744 | + //敵に向かって前進する | |
| 745 | + if( (atan <= (float)M_PI/180*25) && (atan >= (float)M_PI/180*25*-1) ){ | |
| 746 | + if( (atan <= (float)M_PI/180*15) && (atan >= (float)M_PI/180*15*-1) && (r < 24.0f*24.0f) && (actioncnt%50 > 20) ){ | |
| 747 | + //歩きを取り消し、走る | |
| 748 | + SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 749 | + DelFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 750 | + } | |
| 751 | + else{ | |
| 752 | + SetFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 753 | + } | |
| 754 | + } | |
| 755 | + | |
| 756 | + /* | |
| 757 | + //ジャンプ | |
| 758 | + if( random(128) == 0 ){ | |
| 759 | + MoveJump(); | |
| 760 | + } | |
| 761 | + */ | |
| 762 | + | |
| 763 | + if( (r < 9.0f*9.0f)&&( abs(y) < 10.0f) ){ | |
| 764 | + //捕まえる (敵を引き付ける) | |
| 765 | + EnemyHuman->AddPosOrder(atan2(z, x), 1.2f); | |
| 766 | + | |
| 767 | + //敵の視点をランダムに動かす | |
| 768 | + float erx, ery; | |
| 769 | + EnemyHuman->GetRxRy(&erx, &ery); | |
| 770 | + switch(random(3)){ | |
| 771 | + case 0: erx -= (float)M_PI/180*2; break; | |
| 772 | + case 1: erx += (float)M_PI/180*2; break; | |
| 773 | + default: break; | |
| 774 | + } | |
| 775 | + switch(random(3)){ | |
| 776 | + case 0: ery -= (float)M_PI/180*2; break; | |
| 777 | + case 1: ery += (float)M_PI/180*2; break; | |
| 778 | + default: break; | |
| 779 | + } | |
| 780 | + EnemyHuman->SetRxRy(erx, ery); | |
| 781 | + } | |
| 782 | + | |
| 783 | + if( actioncnt%50 == 0){ | |
| 784 | + if( ObjMgr->CheckZombieAttack(ctrlhuman, EnemyHuman) == true ){ | |
| 785 | + ObjMgr->HitZombieAttack(EnemyHuman); | |
| 786 | + } | |
| 787 | + } | |
| 788 | + } | |
| 789 | + else{ //発砲する | |
| 790 | + float ShotAngle; | |
| 791 | + if( longattack == false ){ | |
| 792 | + //敵を捉えたと判定する、許容誤差を計算する | |
| 793 | + ShotAngle = (float)M_PI/180*8; | |
| 794 | + if( weaponid != ID_WEAPON_NONE ){ | |
| 795 | + WeaponParameter wparam; | |
| 796 | + Param->GetWeapon(weaponid, &wparam); | |
| 797 | + if( wparam.scopemode == 1 ){ | |
| 798 | + ShotAngle = (float)M_PI/180*6; | |
| 799 | + } | |
| 800 | + if( wparam.scopemode == 2 ){ | |
| 801 | + ShotAngle = (float)M_PI/180*4; | |
| 802 | + } | |
| 803 | + } | |
| 804 | + | |
| 805 | + //AIレベルごとに調整 | |
| 806 | + ShotAngle += (float)M_PI/180*0.5f * LevelParam->limitserror; | |
| 807 | + | |
| 808 | + if( movemode == AI_RUN2 ){ | |
| 809 | + ShotAngle *= 1.5f; | |
| 810 | + } | |
| 811 | + } | |
| 812 | + else{ | |
| 813 | + //敵を捉えたと判定する、許容誤差を計算する | |
| 814 | + ShotAngle = (float)M_PI/180*4; | |
| 815 | + if( weaponid != ID_WEAPON_NONE ){ | |
| 816 | + WeaponParameter wparam; | |
| 817 | + Param->GetWeapon(weaponid, &wparam); | |
| 818 | + if( wparam.scopemode == 1 ){ | |
| 819 | + ShotAngle = (float)M_PI/180*3; | |
| 820 | + } | |
| 821 | + if( wparam.scopemode == 2 ){ | |
| 822 | + ShotAngle = (float)M_PI/180*2; | |
| 823 | + } | |
| 824 | + } | |
| 825 | + | |
| 826 | + //AIレベルごとに調整 | |
| 827 | + ShotAngle += (float)M_PI/180*0.2f * LevelParam->limitserror; | |
| 828 | + } | |
| 829 | + | |
| 830 | + //敵を捉えていれば | |
| 831 | + float atanxy = atan + atan2(y, r); | |
| 832 | + if( atanxy < ShotAngle ){ | |
| 833 | + int rand = LevelParam->attack; | |
| 834 | + if( longattack == true ){ rand += 1; } | |
| 835 | + | |
| 836 | + //発砲 | |
| 837 | + if( random(rand) == 0 ){ | |
| 838 | + ObjMgr->ShotWeapon(ctrlhuman); | |
| 839 | + } | |
| 840 | + } | |
| 841 | + } | |
| 842 | + | |
| 843 | + //距離に応じて近距離・遠距離を切り替える | |
| 844 | + // 200.0fピッタリで設定値維持 | |
| 845 | + if( r < 200.0f * 200.0f ){ | |
| 846 | + longattack = false; | |
| 847 | + } | |
| 848 | + if( (r > 200.0f * 200.0f)&&(movemode != AI_RUN2) ){ | |
| 849 | + longattack = true; | |
| 850 | + } | |
| 851 | + | |
| 852 | + if( zombie == false ){ | |
| 853 | + //ランダムに移動 | |
| 854 | + MoveRandom(); | |
| 855 | + } | |
| 856 | + | |
| 857 | + actioncnt += 1; | |
| 858 | +} | |
| 859 | + | |
| 860 | +//! 攻撃をキャンセル | |
| 861 | +bool AIcontrol::ActionCancel() | |
| 862 | +{ | |
| 863 | + //敵が死亡したら終了 | |
| 864 | + if( enemyhuman->GetDeadFlag() == true ){ | |
| 865 | + return true; | |
| 866 | + } | |
| 867 | + | |
| 868 | + //距離を取得 | |
| 869 | + float tx, ty, tz; | |
| 870 | + enemyhuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 871 | + float x = posx - tx; | |
| 872 | + float y = posy - ty; | |
| 873 | + float z = posz - tz; | |
| 874 | + float r = sqrt(x*x + y*y + z*z); | |
| 875 | + | |
| 876 | + //距離が離れ過ぎていたら終了 | |
| 877 | + if( (x*x + y*y + z*z) > 620.0f*620.0f ){ | |
| 878 | + return true; | |
| 879 | + } | |
| 880 | + | |
| 881 | + if( longattack == false ){ | |
| 882 | + //適当なタイミングで敵が見えるか確認 | |
| 883 | + if( random(40) == 0 ){ | |
| 884 | + //ブロックが遮っていた(=見えない)ならば終了 | |
| 885 | + if( CheckLookEnemy(enemyhuman, AI_SEARCH_RX, AI_SEARCH_RY, 620.0f, NULL) == false ){ | |
| 886 | + return true; | |
| 887 | + } | |
| 888 | + } | |
| 889 | + | |
| 890 | + //強制的に終了 | |
| 891 | + if( random(550) == 0 ){ | |
| 892 | + return true; | |
| 893 | + } | |
| 894 | + } | |
| 895 | + else{ | |
| 896 | + //適当なタイミングで敵が見えるか確認 | |
| 897 | + if( random(30) == 0 ){ | |
| 898 | + //ブロックが遮っていた(=見えない)ならば終了 | |
| 899 | + if( CheckLookEnemy(enemyhuman, AI_SEARCH_RX, AI_SEARCH_RY, 620.0f, NULL) == false ){ | |
| 900 | + return true; | |
| 901 | + } | |
| 902 | + } | |
| 903 | + | |
| 904 | + //強制的に終了 | |
| 905 | + if( random(450) == 0 ){ | |
| 906 | + return true; | |
| 907 | + } | |
| 908 | + } | |
| 909 | + | |
| 910 | + return false; | |
| 911 | +} | |
| 912 | + | |
| 913 | +//! 武器を持つ | |
| 914 | +int AIcontrol::HaveWeapon() | |
| 915 | +{ | |
| 916 | + int selectweapon; | |
| 917 | + class weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 918 | + int weaponid; | |
| 919 | + | |
| 920 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 921 | + weapon[i] = NULL; | |
| 922 | + } | |
| 923 | + | |
| 924 | + //武器の情報を取得 | |
| 925 | + ctrlhuman->GetWeapon(&selectweapon, weapon); | |
| 926 | + | |
| 927 | + //武器を持っていれば、武器番号を取得 | |
| 928 | + if( weapon[selectweapon] != NULL ){ | |
| 929 | + weapon[selectweapon]->GetParamData(&weaponid, NULL, NULL); | |
| 930 | + } | |
| 931 | + | |
| 932 | + //武器を持っていないか、「ケース」ならば | |
| 933 | + if( (weapon[selectweapon] == NULL)||(weaponid == ID_WEAPON_CASE) ){ | |
| 934 | + //次の武器を指定 | |
| 935 | + int notselectweapon = selectweapon + 1; | |
| 936 | + if( notselectweapon == TOTAL_HAVEWEAPON ){ notselectweapon = 0; } | |
| 937 | + | |
| 938 | + //持ち替える | |
| 939 | + if( weapon[notselectweapon] != NULL ){ | |
| 940 | + ctrlhuman->ChangeWeapon(); | |
| 941 | + return 1; | |
| 942 | + } | |
| 943 | + } | |
| 944 | + | |
| 945 | + return 0; | |
| 946 | +} | |
| 947 | + | |
| 948 | +//! 移動や方向転換をランダムに終了 | |
| 949 | +void AIcontrol::CancelMoveTurn() | |
| 950 | +{ | |
| 951 | + int forward, back, side, updown, rightleft; | |
| 952 | + | |
| 953 | + if( battlemode == AI_ACTION ){ //攻撃中 | |
| 954 | + if( movemode == AI_RUN2 ){ //優先的な走り | |
| 955 | + DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 956 | + DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 957 | + DelFlag(moveturn_mode, AI_CTRL_MOVELEFT); | |
| 958 | + DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT); | |
| 959 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 960 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 961 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 962 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 963 | + if( random(3) == 0 ){ | |
| 964 | + DelFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 965 | + } | |
| 966 | + return; | |
| 967 | + } | |
| 968 | + else{ //優先的な走り 以外 | |
| 969 | + if( longattack == false ){ | |
| 970 | + forward = 6; | |
| 971 | + back = 6; | |
| 972 | + side = 7; | |
| 973 | + updown = 5; | |
| 974 | + rightleft = 6; | |
| 975 | + } | |
| 976 | + else{ | |
| 977 | + forward = 5; | |
| 978 | + back = 4; | |
| 979 | + side = 5; | |
| 980 | + updown = 3; | |
| 981 | + rightleft = 3; | |
| 982 | + } | |
| 983 | + } | |
| 984 | + } | |
| 985 | + else if( battlemode == AI_CAUTION ){ //警戒中 | |
| 986 | + forward = 10; | |
| 987 | + back = 10; | |
| 988 | + side = 10; | |
| 989 | + updown = 14; | |
| 990 | + rightleft = 20; | |
| 991 | + } | |
| 992 | + else{ | |
| 993 | + forward = 12; | |
| 994 | + back = 12; | |
| 995 | + side = 12; | |
| 996 | + updown = 15; | |
| 997 | + rightleft = 18; | |
| 998 | + } | |
| 999 | + | |
| 1000 | + //移動をランダムに止める | |
| 1001 | + if( random(forward) == 0 ){ | |
| 1002 | + DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD); | |
| 1003 | + } | |
| 1004 | + if( random(back) == 0 ){ | |
| 1005 | + DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD); | |
| 1006 | + } | |
| 1007 | + if( random(side) == 0 ){ | |
| 1008 | + DelFlag(moveturn_mode, AI_CTRL_MOVELEFT); | |
| 1009 | + } | |
| 1010 | + if( random(side) == 0 ){ | |
| 1011 | + DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT); | |
| 1012 | + } | |
| 1013 | + if( random(3) == 0 ){ | |
| 1014 | + DelFlag(moveturn_mode, AI_CTRL_MOVEWALK); | |
| 1015 | + } | |
| 1016 | + | |
| 1017 | + //回転をランダムに止める | |
| 1018 | + if( random(updown) == 0 ){ | |
| 1019 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 1020 | + } | |
| 1021 | + if( random(updown) == 0 ){ | |
| 1022 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 1023 | + } | |
| 1024 | + if( random(rightleft) == 0 ){ | |
| 1025 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 1026 | + } | |
| 1027 | + if( random(rightleft) == 0 ){ | |
| 1028 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 1029 | + } | |
| 1030 | +} | |
| 1031 | + | |
| 1032 | +//! 移動や方向転換を実行 | |
| 1033 | +void AIcontrol::ControlMoveTurn() | |
| 1034 | +{ | |
| 1035 | + //移動の実行 | |
| 1036 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD) ){ | |
| 1037 | + ctrlhuman->SetMoveForward(); | |
| 1038 | + } | |
| 1039 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD) ){ | |
| 1040 | + ctrlhuman->SetMoveBack(); | |
| 1041 | + } | |
| 1042 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVELEFT) ){ | |
| 1043 | + ctrlhuman->SetMoveLeft(); | |
| 1044 | + } | |
| 1045 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVERIGHT) ){ | |
| 1046 | + ctrlhuman->SetMoveRight(); | |
| 1047 | + } | |
| 1048 | + if( GetFlag(moveturn_mode, AI_CTRL_MOVEWALK) ){ | |
| 1049 | + ctrlhuman->SetMoveWalk(); | |
| 1050 | + } | |
| 1051 | + | |
| 1052 | + //方向転換の実行 | |
| 1053 | + if( GetFlag(moveturn_mode, AI_CTRL_TURNUP) ){ | |
| 1054 | + ry += AI_TURNRAD; | |
| 1055 | + } | |
| 1056 | + if( GetFlag(moveturn_mode, AI_CTRL_TURNDOWN) ){ | |
| 1057 | + ry -= AI_TURNRAD; | |
| 1058 | + } | |
| 1059 | + if( GetFlag(moveturn_mode, AI_CTRL_TURNLEFT) ){ | |
| 1060 | + rx -= AI_TURNRAD; | |
| 1061 | + } | |
| 1062 | + if( GetFlag(moveturn_mode, AI_CTRL_TURNRIGHT) ){ | |
| 1063 | + rx += AI_TURNRAD; | |
| 1064 | + } | |
| 1065 | +} | |
| 1066 | + | |
| 1067 | +//! 武器をリロード・捨てる | |
| 1068 | +//! @return 捨てる:1 リロード:2 持ち替える:3 何もしない:0 | |
| 1069 | +int AIcontrol::ControlWeapon() | |
| 1070 | +{ | |
| 1071 | + int selectweapon; | |
| 1072 | + class weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1073 | + int weaponid, lnbs, nbs; | |
| 1074 | + | |
| 1075 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1076 | + weapon[i] = NULL; | |
| 1077 | + } | |
| 1078 | + | |
| 1079 | + //武器の情報を取得 | |
| 1080 | + ctrlhuman->GetWeapon(&selectweapon, weapon); | |
| 1081 | + if( weapon[selectweapon] == NULL ){ return 0; } | |
| 1082 | + weapon[selectweapon]->GetParamData(&weaponid, &lnbs, &nbs); | |
| 1083 | + | |
| 1084 | + //スコープ解除 | |
| 1085 | + ctrlhuman->SetDisableScope(); | |
| 1086 | + | |
| 1087 | + //「ケース」なら何もしない | |
| 1088 | + if( weaponid == ID_WEAPON_CASE ){ return 0; } | |
| 1089 | + | |
| 1090 | + //戦闘中にグレネードを持っていれば | |
| 1091 | + if( battlemode == AI_ACTION ){ | |
| 1092 | + if( weaponid == ID_WEAPON_GRENADE ){ | |
| 1093 | + int nextselectweapon, nextnds; | |
| 1094 | + | |
| 1095 | + //次の武器の弾数を取得 | |
| 1096 | + nextselectweapon = selectweapon + 1; | |
| 1097 | + nextnds = 0; | |
| 1098 | + if( nextselectweapon == TOTAL_HAVEWEAPON ){ | |
| 1099 | + nextselectweapon = 0; | |
| 1100 | + } | |
| 1101 | + if( weapon[nextselectweapon] != NULL ){ | |
| 1102 | + weapon[nextselectweapon]->GetParamData(NULL, NULL, &nextnds); | |
| 1103 | + } | |
| 1104 | + | |
| 1105 | + if( longattack == false ){ | |
| 1106 | + // 1/100の確率で持ち替える | |
| 1107 | + if( (random(100) == 0)&&(nextnds > 0) ){ | |
| 1108 | + ctrlhuman->ChangeWeapon(); | |
| 1109 | + return 3; | |
| 1110 | + } | |
| 1111 | + } | |
| 1112 | + else{ | |
| 1113 | + // 1/66の確率で持ち替える | |
| 1114 | + if( (random(66) == 0)&&(nextnds > 0) ){ | |
| 1115 | + ctrlhuman->ChangeWeapon(); | |
| 1116 | + return 3; | |
| 1117 | + } | |
| 1118 | + } | |
| 1119 | + } | |
| 1120 | + } | |
| 1121 | + | |
| 1122 | + //残弾数が無ければ | |
| 1123 | + if( lnbs == 0 ){ | |
| 1124 | + int ways; | |
| 1125 | + | |
| 1126 | + //処理確率決定 | |
| 1127 | + if( battlemode == AI_NORMAL ){ ways = 1; } | |
| 1128 | + else if( battlemode == AI_CAUTION ){ ways = 10; } | |
| 1129 | + else{ ways = 8; } | |
| 1130 | + | |
| 1131 | + // 1/waysの確率で処理 | |
| 1132 | + if( random(ways) == 0 ){ | |
| 1133 | + int under; | |
| 1134 | + | |
| 1135 | + //リロード確率 | |
| 1136 | + if( battlemode == AI_NORMAL ){ | |
| 1137 | + ways = 1; | |
| 1138 | + under = 0; | |
| 1139 | + } | |
| 1140 | + else if( battlemode == AI_CAUTION ){ | |
| 1141 | + ways = 5; | |
| 1142 | + under = 3; | |
| 1143 | + } | |
| 1144 | + else{ | |
| 1145 | + if( longattack == false ){ | |
| 1146 | + // 確率は 3/4 | |
| 1147 | + ways = 4; | |
| 1148 | + under = 2; | |
| 1149 | + } | |
| 1150 | + else{ | |
| 1151 | + // 確率は 2/3 | |
| 1152 | + ways = 3; | |
| 1153 | + under = 1; | |
| 1154 | + } | |
| 1155 | + } | |
| 1156 | + | |
| 1157 | + //弾が無ければ捨てる | |
| 1158 | + if( nbs == 0 ){ | |
| 1159 | + ctrlhuman->DumpWeapon(); | |
| 1160 | + return 1; | |
| 1161 | + } | |
| 1162 | + | |
| 1163 | + //ランダムに リロード実行 or 武器を持ちかえ | |
| 1164 | + if( random(ways) <= under ){ | |
| 1165 | + ObjMgr->ReloadWeapon(ctrlhuman); | |
| 1166 | + return 2; | |
| 1167 | + } | |
| 1168 | + //else{ | |
| 1169 | + ctrlhuman->ChangeWeapon(); | |
| 1170 | + return 3; | |
| 1171 | + //} | |
| 1172 | + } | |
| 1173 | + } | |
| 1174 | + | |
| 1175 | + return 0; | |
| 1176 | +} | |
| 1177 | + | |
| 1178 | +//! 手榴弾を投げる | |
| 1179 | +//! @return 処理中:0 投げ終わった:1 手榴弾を持っていない:2 | |
| 1180 | +int AIcontrol::ThrowGrenade() | |
| 1181 | +{ | |
| 1182 | + int selectweapon; | |
| 1183 | + class weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1184 | + int weaponid, nbs, i; | |
| 1185 | + | |
| 1186 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1187 | + weapon[i] = NULL; | |
| 1188 | + } | |
| 1189 | + | |
| 1190 | + //手榴弾を持っているか確認 | |
| 1191 | + ctrlhuman->GetWeapon(&selectweapon, weapon); | |
| 1192 | + for(i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1193 | + if( weapon[i] != NULL ){ | |
| 1194 | + weapon[i]->GetParamData(&weaponid, NULL, &nbs); | |
| 1195 | + if( weaponid == ID_WEAPON_GRENADE ){ | |
| 1196 | + break; | |
| 1197 | + } | |
| 1198 | + } | |
| 1199 | + } | |
| 1200 | + if( i == TOTAL_HAVEWEAPON ){ | |
| 1201 | + return 2; | |
| 1202 | + } | |
| 1203 | + | |
| 1204 | + //手榴弾を持っていなければ、切り替える | |
| 1205 | + if( i != selectweapon ){ | |
| 1206 | + ctrlhuman->ChangeWeapon(i); | |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + pointdata pdata; | |
| 1210 | + float posy2; | |
| 1211 | + | |
| 1212 | + //パスと人の高さを取得 | |
| 1213 | + Points->Getdata(&pdata, target_pointid); | |
| 1214 | + posy2 = posy + VIEW_HEIGHT; | |
| 1215 | + | |
| 1216 | + float x = posx - target_posx; | |
| 1217 | + float y = pdata.y - posy2; | |
| 1218 | + float z = posz - target_posz; | |
| 1219 | + float r = x * x + z * z; | |
| 1220 | + float atan_rx, atan_ry; | |
| 1221 | + | |
| 1222 | + //目標地点への角度を求める | |
| 1223 | + atan_rx = atan2(x, z) - rx + (float)M_PI; | |
| 1224 | + for(; atan_rx > (float)M_PI; atan_rx -= (float)M_PI*2){} | |
| 1225 | + for(; atan_rx < (float)M_PI*-1; atan_rx += (float)M_PI*2){} | |
| 1226 | + atan_ry = atan2(y, sqrt(r)) - ry; | |
| 1227 | + | |
| 1228 | + //大きな差があれば少しづつ旋回するだけ | |
| 1229 | + if( atan_rx > AI_TURNRAD ){ | |
| 1230 | + SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 1231 | + } | |
| 1232 | + if( atan_rx < AI_TURNRAD*-1 ){ | |
| 1233 | + SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 1234 | + } | |
| 1235 | + if( atan_ry > AI_TURNRAD ){ | |
| 1236 | + SetFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 1237 | + } | |
| 1238 | + if( atan_ry < AI_TURNRAD*-1 ){ | |
| 1239 | + SetFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 1240 | + } | |
| 1241 | + | |
| 1242 | + //微々たる差なら一気に向ける | |
| 1243 | + if( (atan_rx <= AI_TURNRAD) && (atan_rx >= AI_TURNRAD*-1) ){ | |
| 1244 | + DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT); | |
| 1245 | + DelFlag(moveturn_mode, AI_CTRL_TURNLEFT); | |
| 1246 | + rx += atan_rx; | |
| 1247 | + } | |
| 1248 | + if( (atan_ry <= AI_TURNRAD) && (atan_ry >= AI_TURNRAD*-1) ){ | |
| 1249 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 1250 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 1251 | + ry += atan_ry; | |
| 1252 | + } | |
| 1253 | + | |
| 1254 | + //投げる | |
| 1255 | + if( (abs(atan_rx) < (float)M_PI/1800*15)&&(abs(atan_ry) < (float)M_PI/1800*15) ){ | |
| 1256 | + //角度を設定 | |
| 1257 | + ctrlhuman->SetRxRy(rx, ry); | |
| 1258 | + | |
| 1259 | + if( ObjMgr->ShotWeapon(ctrlhuman) != 0 ){ | |
| 1260 | + return 1; | |
| 1261 | + } | |
| 1262 | + } | |
| 1263 | + | |
| 1264 | + return 0; | |
| 1265 | +} | |
| 1266 | + | |
| 1267 | +//! 腕の角度を設定 | |
| 1268 | +void AIcontrol::ArmAngle() | |
| 1269 | +{ | |
| 1270 | + float addry; | |
| 1271 | + | |
| 1272 | + if( ctrlhuman->GetMainWeaponTypeNO() == ID_WEAPON_NONE ){ //手ぶら | |
| 1273 | + addry = ARMRAD_NOWEAPON - ry; | |
| 1274 | + } | |
| 1275 | + else if( (battlemode == AI_CAUTION)&&(cautioncnt > 0) ){ //警戒中 | |
| 1276 | + addry = 0.0f - ry; | |
| 1277 | + } | |
| 1278 | + else{ //平常時で武器所有中 | |
| 1279 | + addry = AI_WEAPON_ARMRAD - ry; | |
| 1280 | + } | |
| 1281 | + | |
| 1282 | + //大きな差があれば少しづつ旋回するだけ | |
| 1283 | + if( addry > AI_TURNRAD ){ | |
| 1284 | + SetFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 1285 | + } | |
| 1286 | + if( addry < AI_TURNRAD*-1 ){ | |
| 1287 | + SetFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 1288 | + } | |
| 1289 | + | |
| 1290 | + //微々たる差なら一気に向ける | |
| 1291 | + if( (addry <= AI_TURNRAD) && (addry >= AI_TURNRAD*-1) ){ | |
| 1292 | + DelFlag(moveturn_mode, AI_CTRL_TURNUP); | |
| 1293 | + DelFlag(moveturn_mode, AI_CTRL_TURNDOWN); | |
| 1294 | + ry += addry; | |
| 1295 | + } | |
| 1296 | +} | |
| 1297 | + | |
| 1298 | +//! 敵を探す | |
| 1299 | +int AIcontrol::SearchEnemy() | |
| 1300 | +{ | |
| 1301 | + if( battlemode == AI_ACTION ){ return 0; } | |
| 1302 | + | |
| 1303 | + int weaponid = ctrlhuman->GetMainWeaponTypeNO(); | |
| 1304 | + int weaponscope = 0; | |
| 1305 | + int searchloops; | |
| 1306 | + float maxDist; | |
| 1307 | + float A_rx, A_ry, B_rx, B_ry; | |
| 1308 | + | |
| 1309 | + //武器を持っていれば、スコープモードを取得 | |
| 1310 | + if( weaponid != ID_WEAPON_NONE ){ | |
| 1311 | + WeaponParameter Wparam; | |
| 1312 | + | |
| 1313 | + Param->GetWeapon(weaponid, &Wparam); | |
| 1314 | + weaponscope = Wparam.scopemode; | |
| 1315 | + } | |
| 1316 | + | |
| 1317 | + //敵の探索回数と探索範囲(距離と角度)を設定 | |
| 1318 | + if( battlemode == AI_NORMAL ){ | |
| 1319 | + searchloops = (LevelParam->search) * 4; | |
| 1320 | + | |
| 1321 | + if( weaponscope == 2 ){ maxDist = 50.0f; } | |
| 1322 | + if( weaponscope == 1 ){ maxDist = 25.0f; } | |
| 1323 | + else{ maxDist = 0.0f; } | |
| 1324 | + maxDist += 12.0f*((LevelParam->search)-2) + 350.0f; | |
| 1325 | + A_rx = (float)M_PI/180*60; | |
| 1326 | + A_ry = (float)M_PI/180*110; | |
| 1327 | + B_rx = (float)M_PI/180*40; | |
| 1328 | + B_ry = (float)M_PI/180*60; | |
| 1329 | + } | |
| 1330 | + else { //battlemode == AI_CAUTION | |
| 1331 | + searchloops = (LevelParam->search) * 5; | |
| 1332 | + | |
| 1333 | + if( weaponscope == 2 ){ maxDist = 80.0f; } | |
| 1334 | + if( weaponscope == 1 ){ maxDist = 40.0f; } | |
| 1335 | + else{ maxDist = 0.0f; } | |
| 1336 | + maxDist += 15.0f*((LevelParam->search)-2) + 420.0f; | |
| 1337 | + A_rx = (float)M_PI/180*80; | |
| 1338 | + A_ry = (float)M_PI/180*130; | |
| 1339 | + B_rx = (float)M_PI/180*50; | |
| 1340 | + B_ry = (float)M_PI/180*80; | |
| 1341 | + } | |
| 1342 | + | |
| 1343 | + //指定回数、敵を探索 | |
| 1344 | + for(int i=0; i<searchloops; i++){ | |
| 1345 | + int targetid = random(MAX_HUMAN); | |
| 1346 | + | |
| 1347 | + if( CheckLookEnemy(targetid, A_rx, A_ry, 200.0f, NULL) == true ){ | |
| 1348 | + longattack = false; | |
| 1349 | + return 1; | |
| 1350 | + } | |
| 1351 | + | |
| 1352 | + if( CheckLookEnemy(targetid, B_rx, B_ry, maxDist, NULL) == true ){ | |
| 1353 | + if( random(4) == 0 ){ | |
| 1354 | + if( movemode == AI_RUN2 ){ longattack = false; } | |
| 1355 | + else{ longattack = true; } | |
| 1356 | + return 2; | |
| 1357 | + } | |
| 1358 | + } | |
| 1359 | + } | |
| 1360 | + return 0; | |
| 1361 | +} | |
| 1362 | + | |
| 1363 | +//! 敵を探す(遠距離攻撃中に近距離を探す) | |
| 1364 | +int AIcontrol::SearchShortEnemy() | |
| 1365 | +{ | |
| 1366 | + float A_rx, A_ry; | |
| 1367 | + A_rx = (float)M_PI/180*100; | |
| 1368 | + A_ry = (float)M_PI/180*52; | |
| 1369 | + | |
| 1370 | + for(int i=0; i<3; i++){ | |
| 1371 | + int targetid = random(MAX_HUMAN); | |
| 1372 | + | |
| 1373 | + if( CheckLookEnemy(targetid, A_rx, A_ry, 200.0f, NULL) == true ){ | |
| 1374 | + longattack = false; | |
| 1375 | + return 1; | |
| 1376 | + } | |
| 1377 | + } | |
| 1378 | + return 0; | |
| 1379 | +} | |
| 1380 | + | |
| 1381 | +//! 敵が見えるか判定 | |
| 1382 | +bool AIcontrol::CheckLookEnemy(int id, float search_rx, float search_ry, float maxDist, float *out_minDist) | |
| 1383 | +{ | |
| 1384 | + if( ObjMgr == NULL ){ return false; } | |
| 1385 | + | |
| 1386 | + //人のオブジェクトを取得 | |
| 1387 | + class human* thuman; | |
| 1388 | + thuman = ObjMgr->GeHumanObject(id); | |
| 1389 | + if( thuman == NULL ){ return false; } | |
| 1390 | + | |
| 1391 | + //同名関数をオーバーロード | |
| 1392 | + return CheckLookEnemy(thuman, search_rx, search_ry, maxDist, out_minDist); | |
| 1393 | +} | |
| 1394 | + | |
| 1395 | +//! 敵が見えるか判定 | |
| 1396 | +bool AIcontrol::CheckLookEnemy(class human* thuman, float search_rx, float search_ry, float maxDist, float *out_minDist) | |
| 1397 | +{ | |
| 1398 | + //return false; | |
| 1399 | + | |
| 1400 | + //無効なデータなら終了 | |
| 1401 | + if( ctrlhuman == NULL ){ return false; } | |
| 1402 | + if( thuman == NULL ){ return false; } | |
| 1403 | + if( thuman->GetDrawFlag() == false ){ return false; } | |
| 1404 | + if( thuman->GetDeadFlag() == true ){ return false; } | |
| 1405 | + | |
| 1406 | + //自分と敵の座標を取得 | |
| 1407 | + int ctrlteam, targetteam; | |
| 1408 | + float tx, ty, tz; | |
| 1409 | + ctrlhuman->GetParamData(NULL, NULL, NULL, &ctrlteam); | |
| 1410 | + thuman->GetParamData(NULL, NULL, NULL, &targetteam); | |
| 1411 | + thuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 1412 | + | |
| 1413 | + //自分と敵が同一人物でなければ | |
| 1414 | + if( ctrlteam != targetteam ){ | |
| 1415 | + float Dist; | |
| 1416 | + float Dist_dummy; | |
| 1417 | + float x, y, z; | |
| 1418 | + | |
| 1419 | + //距離を取得 | |
| 1420 | + x = tx - posx; | |
| 1421 | + y = ty - posy; | |
| 1422 | + z = tz - posz; | |
| 1423 | + Dist = sqrt(x*x + y*y + z*z); | |
| 1424 | + | |
| 1425 | + //判定を行う距離より近ければ | |
| 1426 | + if( Dist < maxDist ){ | |
| 1427 | + float rx2, trx, mrx; | |
| 1428 | + | |
| 1429 | + //人の向き・視点を求める (0.0〜2π) | |
| 1430 | + rx2 = rx*-1 + (float)M_PI/2; | |
| 1431 | + for(; rx2 > (float)M_PI*2; rx2 -= (float)M_PI*2){} | |
| 1432 | + for(; rx2 < 0.0f; rx2 += (float)M_PI*2){} | |
| 1433 | + | |
| 1434 | + //ポイントまでの角度を求める (0.0〜2π) | |
| 1435 | + trx = atan2(z, x); | |
| 1436 | + if( trx < 0.0f ){ trx += (float)M_PI*2; } | |
| 1437 | + | |
| 1438 | + //視点を基準にポイントまでの角度を算出(-π〜π) | |
| 1439 | + mrx = trx - rx2; | |
| 1440 | + for(; mrx > (float)M_PI; mrx -= (float)M_PI*2){} | |
| 1441 | + for(; mrx < (float)M_PI*-1; mrx += (float)M_PI*2){} | |
| 1442 | + | |
| 1443 | + //角度上、視界に入っていれば | |
| 1444 | + if( (abs(mrx) < search_rx/2)&&(abs(atan2(y, sqrt(x*x + z*z))) < search_ry/2) ){ | |
| 1445 | + //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ) | |
| 1446 | + if( CollD->CheckALLBlockIntersectRay(posx, posy + VIEW_HEIGHT, posz, x/Dist, y/Dist, z/Dist, NULL, NULL, &Dist_dummy, Dist) == false ){ | |
| 1447 | + if( out_minDist != NULL ){ *out_minDist = Dist; } | |
| 1448 | + enemyhuman = thuman; | |
| 1449 | + return true; | |
| 1450 | + } | |
| 1451 | + } | |
| 1452 | + } | |
| 1453 | + } | |
| 1454 | + return false; | |
| 1455 | +} | |
| 1456 | + | |
| 1457 | +//! 死体があるか確認 | |
| 1458 | +bool AIcontrol::CheckCorpse(int id) | |
| 1459 | +{ | |
| 1460 | + //クラス設定がおかしければ処理しない | |
| 1461 | + if( ObjMgr == NULL ){ return false; } | |
| 1462 | + if( ctrlhuman == NULL ){ return false; } | |
| 1463 | + | |
| 1464 | + //ターゲットのクラスを取得 | |
| 1465 | + class human* thuman; | |
| 1466 | + thuman = ObjMgr->GeHumanObject(id); | |
| 1467 | + if( thuman == NULL ){ return false; } | |
| 1468 | + if( thuman->GetDrawFlag() == false ){ return false; } | |
| 1469 | + | |
| 1470 | + //死亡していれば | |
| 1471 | + if( thuman->GetDeadFlag() == true ){ | |
| 1472 | + | |
| 1473 | + //チーム番号を取得 | |
| 1474 | + int ctrlteam, targetteam; | |
| 1475 | + ctrlhuman->GetParamData(NULL, NULL, NULL, &ctrlteam); | |
| 1476 | + thuman->GetParamData(NULL, NULL, NULL, &targetteam); | |
| 1477 | + | |
| 1478 | + //味方ならば | |
| 1479 | + if( ctrlteam == targetteam ){ | |
| 1480 | + float tposx, tposy, tposz; | |
| 1481 | + float x, y, z, r; | |
| 1482 | + float atan; | |
| 1483 | + | |
| 1484 | + //座標から距離を取得 | |
| 1485 | + thuman->GetPosData(&tposx, &tposy, &tposz, NULL); | |
| 1486 | + x = posx - tposx; | |
| 1487 | + y = posy - tposy; | |
| 1488 | + z = posz - tposz; | |
| 1489 | + r = x*x + y*y + z*z; | |
| 1490 | + | |
| 1491 | + if( r < 22.0f * 22.0f ){ | |
| 1492 | + //死体への角度を求める | |
| 1493 | + atan = atan2(x, z) - rx + (float)M_PI; | |
| 1494 | + for(; atan > (float)M_PI; atan -= (float)M_PI*2){} | |
| 1495 | + for(; atan < (float)M_PI*-1; atan += (float)M_PI*2){} | |
| 1496 | + | |
| 1497 | + if( abs(atan) < (float)M_PI/18*4 ){ | |
| 1498 | + return true; | |
| 1499 | + } | |
| 1500 | + } | |
| 1501 | + } | |
| 1502 | + } | |
| 1503 | + return false; | |
| 1504 | +} | |
| 1505 | + | |
| 1506 | +//! パスによる移動 | |
| 1507 | +void AIcontrol::MovePath() | |
| 1508 | +{ | |
| 1509 | + if( movemode == AI_NULL ){ //異常なパス | |
| 1510 | + // | |
| 1511 | + } | |
| 1512 | + else if( movemode == AI_GRENADE ){ //手榴弾パス | |
| 1513 | + if( ThrowGrenade() != 0 ){ | |
| 1514 | + SearchTarget(true); | |
| 1515 | + } | |
| 1516 | + } | |
| 1517 | + else{ //その他パス | |
| 1518 | + if( CheckTargetPos() == false ){ | |
| 1519 | + MoveTarget(); | |
| 1520 | + } | |
| 1521 | + else if( (movemode == AI_WAIT)||(movemode == AI_TRACKING) ){ | |
| 1522 | + TurnSeen(); | |
| 1523 | + } | |
| 1524 | + else if( (movemode == AI_STOP)&&(waitcnt < ((int)GAMEFPS)*5) ){ | |
| 1525 | + if( StopSeen() == true ){ | |
| 1526 | + waitcnt += 1; | |
| 1527 | + } | |
| 1528 | + } | |
| 1529 | + else{ | |
| 1530 | + waitcnt = 0; | |
| 1531 | + SearchTarget(true); | |
| 1532 | + } | |
| 1533 | + } | |
| 1534 | +} | |
| 1535 | + | |
| 1536 | +//! 攻撃メイン処理 | |
| 1537 | +//! @return 不変:false 変更:true | |
| 1538 | +bool AIcontrol::ActionMain() | |
| 1539 | +{ | |
| 1540 | + int newbattlemode = AI_ACTION; | |
| 1541 | + | |
| 1542 | + //攻撃処理 | |
| 1543 | + Action(); | |
| 1544 | + | |
| 1545 | + if( movemode == AI_RUN2 ){ //優先的な走り | |
| 1546 | + //目標地点へ移動 | |
| 1547 | + if( CheckTargetPos() == true ){ | |
| 1548 | + newbattlemode = AI_NORMAL; | |
| 1549 | + SearchTarget(true); | |
| 1550 | + } | |
| 1551 | + else{ | |
| 1552 | + MoveTarget2(); | |
| 1553 | + } | |
| 1554 | + } | |
| 1555 | + else{ //優先的な走り 以外 | |
| 1556 | + //遠距離攻撃中なら、近くの敵を探す | |
| 1557 | + if( longattack == true ){ | |
| 1558 | + SearchShortEnemy(); | |
| 1559 | + } | |
| 1560 | + } | |
| 1561 | + | |
| 1562 | + //攻撃終了判定 | |
| 1563 | + if( ActionCancel() == true ){ | |
| 1564 | + enemyhuman = NULL; | |
| 1565 | + | |
| 1566 | + if( movemode == AI_RUN2 ){ | |
| 1567 | + newbattlemode = AI_NORMAL; | |
| 1568 | + } | |
| 1569 | + else{ | |
| 1570 | + newbattlemode = AI_CAUTION; | |
| 1571 | + cautioncnt = 160; | |
| 1572 | + } | |
| 1573 | + } | |
| 1574 | + | |
| 1575 | + //設定を判定 | |
| 1576 | + if( battlemode != newbattlemode ){ | |
| 1577 | + battlemode = newbattlemode; | |
| 1578 | + return true; | |
| 1579 | + } | |
| 1580 | + return false; | |
| 1581 | +} | |
| 1582 | + | |
| 1583 | +//! 警戒メイン処理 | |
| 1584 | +//! @return 不変:false 変更:true | |
| 1585 | +bool AIcontrol::CautionMain() | |
| 1586 | +{ | |
| 1587 | + int newbattlemode = AI_CAUTION; | |
| 1588 | + | |
| 1589 | + //座標とチーム番号を取得 | |
| 1590 | + int teamid; | |
| 1591 | + ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid); | |
| 1592 | + | |
| 1593 | + //被弾と音の状況を取得 | |
| 1594 | + bool HitFlag = ctrlhuman->CheckHit(); | |
| 1595 | + soundlist soundlist[MAX_SOUNDMGR_LIST]; | |
| 1596 | + int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist); | |
| 1597 | + | |
| 1598 | + //回転と腕の角度 | |
| 1599 | + TurnSeen(); | |
| 1600 | + ArmAngle(); | |
| 1601 | + | |
| 1602 | + //メイン処理 | |
| 1603 | + if( enemyhuman != NULL ){ //既に敵を見つけていれば | |
| 1604 | + newbattlemode = AI_ACTION; | |
| 1605 | + actioncnt = 0; | |
| 1606 | + } | |
| 1607 | + else if( SearchEnemy() != 0 ){ //敵が見つかれば | |
| 1608 | + newbattlemode = AI_ACTION; | |
| 1609 | + actioncnt = 0; | |
| 1610 | + } | |
| 1611 | + else if( (HitFlag == true)||(soundlists > 0) ){ //被弾したか音が聞こえた | |
| 1612 | + cautioncnt = 160; //警戒を再開 | |
| 1613 | + } | |
| 1614 | + else if( cautioncnt == 0 ){ //警戒を終了するなら | |
| 1615 | + if( CheckTargetPos() == false ){ //警戒開始地点より離れているか | |
| 1616 | + MoveTarget(); //警戒開始地点に近づく | |
| 1617 | + } | |
| 1618 | + else{ | |
| 1619 | + newbattlemode = AI_NORMAL; | |
| 1620 | + | |
| 1621 | + //警戒待ちパスなら次へ進める | |
| 1622 | + pointdata pdata; | |
| 1623 | + Points->Getdata(&pdata, target_pointid); | |
| 1624 | + if( (pdata.p1 == 3)&&(pdata.p2 == 4) ){ | |
| 1625 | + SearchTarget(true); | |
| 1626 | + } | |
| 1627 | + } | |
| 1628 | + } | |
| 1629 | + else if( cautioncnt < 100 ){ //100フレームを切ったら、ランダムに警戒終了(カウント:0に) | |
| 1630 | + if( random(50) == 0 ){ cautioncnt = 0; } | |
| 1631 | + } | |
| 1632 | + else{ cautioncnt -= 1; } | |
| 1633 | + | |
| 1634 | + //追尾中で対象から離れすぎたら、ランダムに警戒終了 | |
| 1635 | + if( (movemode == AI_TRACKING)&&(random(3) == 0) ){ | |
| 1636 | + pointdata pdata; | |
| 1637 | + float x, z; | |
| 1638 | + float tx, tz; | |
| 1639 | + Points->Getdata(&pdata, target_pointid); | |
| 1640 | + SearchHumanPos(pdata.p4, &tx, &tz); | |
| 1641 | + x = posx - tx; | |
| 1642 | + z = posz - tz; | |
| 1643 | + if( (x*x + z*z) > 25.0f*25.0f ){ | |
| 1644 | + cautioncnt = 0; | |
| 1645 | + } | |
| 1646 | + } | |
| 1647 | + | |
| 1648 | + //設定を判定 | |
| 1649 | + if( battlemode != newbattlemode ){ | |
| 1650 | + battlemode = newbattlemode; | |
| 1651 | + return true; | |
| 1652 | + } | |
| 1653 | + return false; | |
| 1654 | +} | |
| 1655 | + | |
| 1656 | +//! 通常メイン処理 | |
| 1657 | +//! @return 不変:false 変更:true | |
| 1658 | +bool AIcontrol::NormalMain() | |
| 1659 | +{ | |
| 1660 | + int newbattlemode = AI_NORMAL; | |
| 1661 | + | |
| 1662 | + if( hold == false ){ | |
| 1663 | + SearchTarget(false); | |
| 1664 | + } | |
| 1665 | + enemyhuman = NULL; | |
| 1666 | + | |
| 1667 | + //座標とチーム番号を取得 | |
| 1668 | + int teamid; | |
| 1669 | + ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid); | |
| 1670 | + | |
| 1671 | + //被弾と音の状況を取得 | |
| 1672 | + bool HitFlag = ctrlhuman->CheckHit(); | |
| 1673 | + soundlist soundlist[MAX_SOUNDMGR_LIST]; | |
| 1674 | + int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist); | |
| 1675 | + | |
| 1676 | + //ランダムパスなら処理実行 | |
| 1677 | + if( movemode == AI_RANDOM ){ | |
| 1678 | + SearchTarget(true); | |
| 1679 | + } | |
| 1680 | + | |
| 1681 | + //腕の角度を設定 | |
| 1682 | + if( movemode != AI_GRENADE ){ | |
| 1683 | + ArmAngle(); | |
| 1684 | + } | |
| 1685 | + | |
| 1686 | + if( movemode == AI_RUN2 ){ //優先的な走りの処理 | |
| 1687 | + //敵を見つけたら攻撃に入る | |
| 1688 | + if( SearchEnemy() != 0 ){ | |
| 1689 | + newbattlemode = AI_ACTION; | |
| 1690 | + } | |
| 1691 | + else{ | |
| 1692 | + MovePath(); //移動実行 | |
| 1693 | + } | |
| 1694 | + } | |
| 1695 | + else{ //優先的な走り以外の処理 | |
| 1696 | + //警戒判定に入る処理 | |
| 1697 | + if( | |
| 1698 | + (SearchEnemy() != 0)|| //敵を見つけた | |
| 1699 | + (HitFlag == true)||(soundlists > 0)|| //被弾したか音が聞こえた | |
| 1700 | + (CheckCorpse( random(MAX_HUMAN) ) == true) //死体を見つけた | |
| 1701 | + ){ | |
| 1702 | + newbattlemode = AI_CAUTION; | |
| 1703 | + cautioncnt = 160; | |
| 1704 | + target_posx = posx; | |
| 1705 | + target_posz = posz; | |
| 1706 | + } | |
| 1707 | + else{ | |
| 1708 | + MovePath(); //移動実行 | |
| 1709 | + } | |
| 1710 | + } | |
| 1711 | + | |
| 1712 | + //設定を判定 | |
| 1713 | + if( battlemode != newbattlemode ){ | |
| 1714 | + battlemode = newbattlemode; | |
| 1715 | + return true; | |
| 1716 | + } | |
| 1717 | + return false; | |
| 1718 | +} | |
| 1719 | + | |
| 1720 | +//! 初期化系関数 | |
| 1721 | +void AIcontrol::Init() | |
| 1722 | +{ | |
| 1723 | + //クラス設定がおかしければ処理しない | |
| 1724 | + if( ctrlhuman == NULL ){ return; } | |
| 1725 | + if( blocks == NULL ){ return; } | |
| 1726 | + if( Points == NULL ){ return; } | |
| 1727 | + if( CollD == NULL ){ return; } | |
| 1728 | + | |
| 1729 | + //使用されていない人なら処理しない | |
| 1730 | + if( ctrlhuman->GetDrawFlag() == false ){ return; } | |
| 1731 | + | |
| 1732 | + //ステートを初期化 | |
| 1733 | + hold = false; | |
| 1734 | + battlemode = AI_NORMAL; | |
| 1735 | + movemode = AI_NULL; | |
| 1736 | + enemyhuman = NULL; | |
| 1737 | + waitcnt = 0; | |
| 1738 | + gotocnt = 0; | |
| 1739 | + moveturn_mode = 0x00; | |
| 1740 | + cautioncnt = 0; | |
| 1741 | + actioncnt = 0; | |
| 1742 | + longattack = false; | |
| 1743 | + | |
| 1744 | + //AIレベルと設定値を取得 | |
| 1745 | + int paramid; | |
| 1746 | + HumanParameter paramdata; | |
| 1747 | + //target_pointid = in_target_pointid; | |
| 1748 | + ctrlhuman->GetParamData(¶mid, &target_pointid, NULL, NULL); | |
| 1749 | + Param->GetHuman(paramid, ¶mdata); | |
| 1750 | + AIlevel = paramdata.AIlevel; | |
| 1751 | + Param->GetAIlevel(AIlevel, &LevelParam); | |
| 1752 | + | |
| 1753 | + //次のポイントを検索 | |
| 1754 | + SearchTarget(true); | |
| 1755 | +} | |
| 1756 | + | |
| 1757 | +//! 指定した場所へ待機させる | |
| 1758 | +//! @param px X座標 | |
| 1759 | +//! @param pz Z座標 | |
| 1760 | +//! @param rx 重視する向き | |
| 1761 | +//! @attention 移動パスに関わらず、指定した座標への待機を強制します。Init()関数を再度実行するまで元に戻せません。 | |
| 1762 | +void AIcontrol::SetHoldWait(float px, float pz, float rx) | |
| 1763 | +{ | |
| 1764 | + movemode = AI_WAIT; | |
| 1765 | + hold = true; | |
| 1766 | + target_posx = px; | |
| 1767 | + target_posz = pz; | |
| 1768 | + target_rx = rx; | |
| 1769 | +} | |
| 1770 | + | |
| 1771 | +//! 指定した人を追尾させる | |
| 1772 | +//! @param id 人のデータ番号 | |
| 1773 | +//! @attention 移動パスに関わらず、指定した人への追尾を強制します。Init()関数を再度実行するまで元に戻せません。 | |
| 1774 | +void AIcontrol::SetHoldTracking(int id) | |
| 1775 | +{ | |
| 1776 | + movemode = AI_TRACKING; | |
| 1777 | + hold = false; | |
| 1778 | + target_pointid = id; | |
| 1779 | +} | |
| 1780 | + | |
| 1781 | +//! 処理系関数 | |
| 1782 | +void AIcontrol::Process() | |
| 1783 | +{ | |
| 1784 | + //クラス設定がおかしければ処理しない | |
| 1785 | + if( ctrlhuman == NULL ){ return; } | |
| 1786 | + if( blocks == NULL ){ return; } | |
| 1787 | + if( Points == NULL ){ return; } | |
| 1788 | + if( CollD == NULL ){ return; } | |
| 1789 | + | |
| 1790 | + //無効な人クラスなら処理しない | |
| 1791 | + if( ctrlhuman->GetDrawFlag() == false ){ return; } | |
| 1792 | + | |
| 1793 | + //死亡したら | |
| 1794 | + if( ctrlhuman->GetHP() <= 0 ){ | |
| 1795 | + battlemode = AI_DEAD; | |
| 1796 | + movemode = AI_DEAD; | |
| 1797 | + return; | |
| 1798 | + } | |
| 1799 | + | |
| 1800 | + //座標と角度を取得 | |
| 1801 | + ctrlhuman->GetPosData(&posx, &posy, &posz, NULL); | |
| 1802 | + ctrlhuman->GetRxRy(&rx, &ry); | |
| 1803 | + | |
| 1804 | + //ランダムに動作を止める | |
| 1805 | + CancelMoveTurn(); | |
| 1806 | + | |
| 1807 | + //攻撃中か警戒中ならば | |
| 1808 | + if( (battlemode == AI_ACTION)||(battlemode == AI_CAUTION) ){ | |
| 1809 | + //武器を持つ | |
| 1810 | + HaveWeapon(); | |
| 1811 | + } | |
| 1812 | + | |
| 1813 | + //主計算実行 | |
| 1814 | + if( battlemode == AI_ACTION ){ //攻撃中 | |
| 1815 | + ActionMain(); | |
| 1816 | + } | |
| 1817 | + else if( battlemode == AI_CAUTION ){ //警戒中 | |
| 1818 | + CautionMain(); | |
| 1819 | + } | |
| 1820 | + else{ //平常時 | |
| 1821 | + NormalMain(); | |
| 1822 | + } | |
| 1823 | + | |
| 1824 | + //移動・方向転換処理 | |
| 1825 | + ControlMoveTurn(); | |
| 1826 | + | |
| 1827 | + //武器を取り扱い | |
| 1828 | + ControlWeapon(); | |
| 1829 | + | |
| 1830 | + //角度を適用 | |
| 1831 | + ctrlhuman->SetRxRy(rx, ry); | |
| 1832 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,1398 @@ | ||
| 1 | +//! @file d3dgraphics.cpp | |
| 2 | +//! @brief D3DGraphicsクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "d3dgraphics.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +D3DGraphics::D3DGraphics() | |
| 36 | +{ | |
| 37 | + pD3D = NULL; | |
| 38 | + pd3dDevice = NULL; | |
| 39 | + aspect = 1.0f; | |
| 40 | + fullscreenflag = false; | |
| 41 | + for(int i=0; i<MAX_MODEL; i++){ | |
| 42 | + pmesh[i] = NULL; | |
| 43 | + } | |
| 44 | + for(int i=0; i<MAX_TEXTURE; i++){ | |
| 45 | + ptextures[i] = NULL; | |
| 46 | + } | |
| 47 | + | |
| 48 | + blockdata = NULL; | |
| 49 | + for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){ | |
| 50 | + mapTextureID[i] = -1; | |
| 51 | + } | |
| 52 | + | |
| 53 | + StartRenderFlag = false; | |
| 54 | + | |
| 55 | + //ptextsprite = NULL; | |
| 56 | + pxmsfont = NULL; | |
| 57 | + TextureFont = -1; | |
| 58 | + TextureFont_width = 0; | |
| 59 | + TextureFont_height = 0; | |
| 60 | +} | |
| 61 | + | |
| 62 | +//! ディストラクタ | |
| 63 | +D3DGraphics::~D3DGraphics() | |
| 64 | +{ | |
| 65 | + if( TextureFont != -1 ){ CleanupTexture(TextureFont); } | |
| 66 | + if( pxmsfont != NULL ){ pxmsfont->Release(); } | |
| 67 | + //if( ptextsprite != NULL ){ ptextsprite->Release(); } | |
| 68 | + | |
| 69 | + CleanupMapdata(); | |
| 70 | + | |
| 71 | + for(int i=0; i<MAX_MODEL; i++){ | |
| 72 | + CleanupModel(i); | |
| 73 | + } | |
| 74 | + for(int i=0; i<MAX_TEXTURE; i++){ | |
| 75 | + CleanupTexture(i); | |
| 76 | + } | |
| 77 | + | |
| 78 | + if( pd3dDevice != NULL ) pd3dDevice->Release(); | |
| 79 | + if( pD3D != NULL ) pD3D->Release(); | |
| 80 | +} | |
| 81 | + | |
| 82 | +//! 初期化@n | |
| 83 | +//! (DirectX 9) | |
| 84 | +//! @param hWnd ウィンドウハンドル | |
| 85 | +//! @param TextureFontFilename 使用するテクスチャフォントのファイル名 | |
| 86 | +//! @param fullscreen false:ウィンドウ表示 true:フルスクリーン用表示 | |
| 87 | +//! @return 成功:0 失敗:1 | |
| 88 | +int D3DGraphics::InitD3D(HWND hWnd, char *TextureFontFilename, bool fullscreen) | |
| 89 | +{ | |
| 90 | + D3DPRESENT_PARAMETERS d3dpp; | |
| 91 | + RECT rec; | |
| 92 | + | |
| 93 | + GetClientRect( hWnd, &rec); | |
| 94 | + | |
| 95 | + fullscreenflag = fullscreen; | |
| 96 | + | |
| 97 | + //D3D9の作成 | |
| 98 | + pD3D = Direct3DCreate9(D3D_SDK_VERSION); | |
| 99 | + if( pD3D == NULL ){ | |
| 100 | + return 1; | |
| 101 | + } | |
| 102 | + | |
| 103 | + //D3Dデバイスの作成 | |
| 104 | + ZeroMemory(&d3dpp, sizeof(d3dpp)); | |
| 105 | + if( fullscreenflag == false ){ | |
| 106 | + d3dpp.Windowed = TRUE; | |
| 107 | + d3dpp.BackBufferWidth = rec.right; | |
| 108 | + d3dpp.BackBufferHeight = rec.bottom; | |
| 109 | + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; | |
| 110 | + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; | |
| 111 | + d3dpp.EnableAutoDepthStencil = TRUE; | |
| 112 | + d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; | |
| 113 | + d3dpp.FullScreen_RefreshRateInHz = 0; | |
| 114 | + } | |
| 115 | + else{ | |
| 116 | + D3DDISPLAYMODE dispmode; | |
| 117 | + pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispmode); | |
| 118 | + | |
| 119 | + d3dpp.Windowed = FALSE; | |
| 120 | + d3dpp.BackBufferWidth = rec.right; | |
| 121 | + d3dpp.BackBufferHeight = rec.bottom; | |
| 122 | + d3dpp.BackBufferFormat = dispmode.Format; | |
| 123 | + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; | |
| 124 | + d3dpp.EnableAutoDepthStencil = TRUE; | |
| 125 | + d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; | |
| 126 | + d3dpp.FullScreen_RefreshRateInHz = dispmode.RefreshRate; | |
| 127 | + } | |
| 128 | + | |
| 129 | + if( FAILED( pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice) ) ){ | |
| 130 | + if( FAILED( pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice) ) ){ | |
| 131 | + return 1; | |
| 132 | + } | |
| 133 | + } | |
| 134 | + | |
| 135 | + //ライト | |
| 136 | + //pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0,255,255,255) ); | |
| 137 | + pd3dDevice->LightEnable(0, FALSE); | |
| 138 | + pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); | |
| 139 | + | |
| 140 | + //フォグ | |
| 141 | + float fog_st = 100; | |
| 142 | + float fog_end = 800; | |
| 143 | + pd3dDevice->SetRenderState(D3DRS_FOGENABLE, TRUE); | |
| 144 | + pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(0, 0, 0, 0)); | |
| 145 | + pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR); | |
| 146 | + pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE); | |
| 147 | + pd3dDevice->SetRenderState(D3DRS_FOGSTART,*(DWORD*)(&fog_st)); | |
| 148 | + pd3dDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&fog_end)); | |
| 149 | + | |
| 150 | + // テクスチャフィルタを使う | |
| 151 | + pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); | |
| 152 | + pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); | |
| 153 | + pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); | |
| 154 | + | |
| 155 | + //ミップマップの詳細レベル (LOD) バイアスを指定する。 | |
| 156 | + float LODBias = -0.2f; | |
| 157 | + pd3dDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, *((LPDWORD)(&LODBias)) ); | |
| 158 | + | |
| 159 | + //アルファ・ブレンディングを行う | |
| 160 | + pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | |
| 161 | + | |
| 162 | + //透過処理を行う | |
| 163 | + pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); | |
| 164 | + pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); | |
| 165 | + | |
| 166 | + //アルファテストに対応しているかチェック | |
| 167 | + D3DCAPS9 Caps; | |
| 168 | + pd3dDevice->GetDeviceCaps(&Caps); | |
| 169 | + if( Caps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL ){ | |
| 170 | + //アルファテスト設定 | |
| 171 | + // 完全に透明なピクセルは描画しない | |
| 172 | + pd3dDevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x00000001); | |
| 173 | + pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); | |
| 174 | + pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); | |
| 175 | + } | |
| 176 | + | |
| 177 | + //深度バッファ比較関数 | |
| 178 | + pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); | |
| 179 | + pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); | |
| 180 | + | |
| 181 | + //ポリゴンの裏・表 | |
| 182 | + pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); | |
| 183 | + | |
| 184 | + | |
| 185 | + //テキストスプライト初期化 | |
| 186 | + if( FAILED( D3DXCreateSprite( pd3dDevice, &ptextsprite ) ) ){ | |
| 187 | + return 1; | |
| 188 | + } | |
| 189 | + //フォント名:MS ゴシック サイズ:18 | |
| 190 | + HRESULT hr = D3DXCreateFont( pd3dDevice, -18, 0, FW_NORMAL, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, | |
| 191 | + DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "MS ゴシック", &pxmsfont); | |
| 192 | + if( FAILED(hr) ) return 1; | |
| 193 | + | |
| 194 | + //テクスチャフォント用画像を取得 | |
| 195 | + TextureFont = LoadTexture(TextureFontFilename, true, false); | |
| 196 | + GetTextureSize(TextureFont, &TextureFont_width, &TextureFont_height); | |
| 197 | + | |
| 198 | + //アスペクト比を設定 | |
| 199 | + aspect = (float)rec.right / (float)rec.bottom; | |
| 200 | + | |
| 201 | + //マウスカーソルを消す | |
| 202 | + //ShowCursor(FALSE); | |
| 203 | + | |
| 204 | + return 0; | |
| 205 | +} | |
| 206 | + | |
| 207 | +/* | |
| 208 | +//! リセット@n | |
| 209 | +//! (ウィンドウ最小化からの復帰 など) | |
| 210 | +//! @param hWnd ウィンドウハンドル | |
| 211 | +//! @return 成功:0 失敗:1 | |
| 212 | +int D3DGraphics::ResetD3D(HWND hWnd) | |
| 213 | +{ | |
| 214 | + D3DPRESENT_PARAMETERS d3dpp; | |
| 215 | + RECT rec; | |
| 216 | + | |
| 217 | + GetClientRect( hWnd, &rec); | |
| 218 | + | |
| 219 | + //D3Dデバイスの作成 | |
| 220 | + ZeroMemory(&d3dpp, sizeof(d3dpp)); | |
| 221 | + if( fullscreenflag == false ){ | |
| 222 | + d3dpp.Windowed = TRUE; | |
| 223 | + d3dpp.BackBufferWidth = rec.right; | |
| 224 | + d3dpp.BackBufferHeight = rec.bottom; | |
| 225 | + d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; | |
| 226 | + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; | |
| 227 | + d3dpp.EnableAutoDepthStencil = TRUE; | |
| 228 | + d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; | |
| 229 | + d3dpp.FullScreen_RefreshRateInHz = 0; | |
| 230 | + } | |
| 231 | + else{ | |
| 232 | + D3DDISPLAYMODE dispmode; | |
| 233 | + pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispmode); | |
| 234 | + | |
| 235 | + d3dpp.Windowed = FALSE; | |
| 236 | + d3dpp.BackBufferWidth = rec.right; | |
| 237 | + d3dpp.BackBufferHeight = rec.bottom; | |
| 238 | + d3dpp.BackBufferFormat = dispmode.Format; | |
| 239 | + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; | |
| 240 | + d3dpp.EnableAutoDepthStencil = TRUE; | |
| 241 | + d3dpp.AutoDepthStencilFormat = D3DFMT_D24X8; | |
| 242 | + d3dpp.FullScreen_RefreshRateInHz = dispmode.RefreshRate; | |
| 243 | + } | |
| 244 | + | |
| 245 | + if( FAILED( pd3dDevice->Reset(&d3dpp) ) ){ | |
| 246 | + return 1; | |
| 247 | + } | |
| 248 | + | |
| 249 | + //ここに必要な処理を書く | |
| 250 | + | |
| 251 | + return 0; | |
| 252 | +} | |
| 253 | +*/ | |
| 254 | + | |
| 255 | +//! モデルファイルを読み込む(.x) | |
| 256 | +//! @param filename ファイル名 | |
| 257 | +//! @return 成功:モデル認識番号(0以上) 失敗:-1 | |
| 258 | +int D3DGraphics::LoadModel(char* filename) | |
| 259 | +{ | |
| 260 | + int id = -1; | |
| 261 | + | |
| 262 | + //空いている要素を探す | |
| 263 | + for(int i=0; i<MAX_MODEL; i++){ | |
| 264 | + if( pmesh[i] == NULL ){ | |
| 265 | + id = i; | |
| 266 | + break; | |
| 267 | + } | |
| 268 | + } | |
| 269 | + if( id == -1 ){ return -1; } | |
| 270 | + | |
| 271 | + LPD3DXBUFFER pD3DXMtrlBuffer; | |
| 272 | + | |
| 273 | + //.xファイルをバッファーに読み込む | |
| 274 | + if( FAILED( D3DXLoadMeshFromX( filename, D3DXMESH_SYSTEMMEM, pd3dDevice, NULL, | |
| 275 | + &pD3DXMtrlBuffer, NULL, &nummaterials[id], &pmesh[id] ) ) ) { | |
| 276 | + return -1; | |
| 277 | + } | |
| 278 | + | |
| 279 | + //マテリアル情報を取得 | |
| 280 | + D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); | |
| 281 | + int num = nummaterials[id]; | |
| 282 | + pmaterials[id] = new D3DMATERIAL9[num]; | |
| 283 | + if( pmaterials[id] == NULL ) return -3; | |
| 284 | + | |
| 285 | + //構造体に代入 | |
| 286 | + for( int i=0; i<num; i=i+1 ){ | |
| 287 | + pmaterials[id][i] = d3dxMaterials[i].MatD3D; | |
| 288 | + pmaterials[id][i].Ambient = pmaterials[id][i].Diffuse; | |
| 289 | + } | |
| 290 | + | |
| 291 | + //バッファを開放 | |
| 292 | + pD3DXMtrlBuffer->Release(); | |
| 293 | + | |
| 294 | + return id; | |
| 295 | +} | |
| 296 | + | |
| 297 | +//! モデルファイルの中間データを作成(モーフィング) | |
| 298 | +//! @param idA モデルAの認識番号 | |
| 299 | +//! @param idB モデルBの認識番号 | |
| 300 | +//! @return 成功:新しいモデル認識番号(0以上) 失敗:-1 | |
| 301 | +//! @attention モデルAとモデルBは、頂点数・ポリゴン数・インデックスが同じである必要があります。 | |
| 302 | +//! @attention それぞれのモデルデータが正しくないか 頂点数が異なる場合、実行に失敗します。 | |
| 303 | +int D3DGraphics::MorphingModel(int idA, int idB) | |
| 304 | +{ | |
| 305 | + //データが正しいか調べる | |
| 306 | + if( (idA < 0)||((MAX_MODEL -1) < idA) ){ return -1; } | |
| 307 | + if( pmesh[idA] == NULL ){ return -1; } | |
| 308 | + if( (idB < 0)||((MAX_MODEL -1) < idB) ){ return -1; } | |
| 309 | + if( pmesh[idB] == NULL ){ return -1; } | |
| 310 | + | |
| 311 | + int idN = -1; | |
| 312 | + int numvA, numvB; | |
| 313 | + LPDIRECT3DVERTEXBUFFER9 pvbA, pvbB, pvbN; | |
| 314 | + D3DXVECTOR3 *pVerticesA, *pVerticesB, *pVerticesN; | |
| 315 | + int FVFsize; | |
| 316 | + | |
| 317 | + //空いている要素を探す | |
| 318 | + for(int i=0; i<MAX_MODEL; i++){ | |
| 319 | + if( pmesh[i] == NULL ){ | |
| 320 | + idN = i; | |
| 321 | + break; | |
| 322 | + } | |
| 323 | + } | |
| 324 | + if( idN == -1 ){ return -1; } | |
| 325 | + | |
| 326 | + //頂点数を取得 | |
| 327 | + numvA = pmesh[idA]->GetNumVertices(); | |
| 328 | + numvB = pmesh[idB]->GetNumVertices(); | |
| 329 | + | |
| 330 | + //頂点数が同じかどうか調べる | |
| 331 | + if( numvA != numvB ){ return -1; } | |
| 332 | + | |
| 333 | + //頂点データをコピー(実質的に領域確保用のダミー) | |
| 334 | + if( pmesh[idA]->CloneMeshFVF(pmesh[idA]->GetOptions(), pmesh[idA]->GetFVF(), pd3dDevice, &pmesh[idN]) != D3D_OK ){ | |
| 335 | + return -1; | |
| 336 | + } | |
| 337 | + | |
| 338 | + //マテリアル情報をコピー | |
| 339 | + int num = nummaterials[idA]; | |
| 340 | + nummaterials[idN] = nummaterials[idA]; | |
| 341 | + pmaterials[idN] = new D3DMATERIAL9[num]; | |
| 342 | + if( pmaterials[idN] == NULL ) return -1; | |
| 343 | + for( int i=0; i<num; i=i+1 ){ | |
| 344 | + pmaterials[idN][i] = pmaterials[idA][i]; | |
| 345 | + } | |
| 346 | + | |
| 347 | + //バッファーを取得 | |
| 348 | + pmesh[idA]->GetVertexBuffer(&pvbA); | |
| 349 | + pmesh[idB]->GetVertexBuffer(&pvbB); | |
| 350 | + pmesh[idN]->GetVertexBuffer(&pvbN); | |
| 351 | + | |
| 352 | + //1頂点当たりのバイト数取得 | |
| 353 | + FVFsize = D3DXGetFVFVertexSize(pmesh[idN]->GetFVF()); | |
| 354 | + | |
| 355 | + //各頂点を読み出し計算 | |
| 356 | + for(int i=0; i<numvA; i++){ | |
| 357 | + pvbA->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesA, D3DLOCK_READONLY); | |
| 358 | + pvbB->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesB, D3DLOCK_READONLY); | |
| 359 | + pvbN->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesN, 0); | |
| 360 | + | |
| 361 | + //平均化 | |
| 362 | + pVerticesN->x = (pVerticesA->x + pVerticesB->x)/2; | |
| 363 | + pVerticesN->y = (pVerticesA->y + pVerticesB->y)/2; | |
| 364 | + pVerticesN->z = (pVerticesA->z + pVerticesB->z)/2; | |
| 365 | + | |
| 366 | + pvbA->Unlock(); | |
| 367 | + pvbB->Unlock(); | |
| 368 | + pvbN->Unlock(); | |
| 369 | + } | |
| 370 | + | |
| 371 | + return idN; | |
| 372 | +} | |
| 373 | + | |
| 374 | +//! モデルファイルを解放 | |
| 375 | +//! @param id モデル認識番号 | |
| 376 | +void D3DGraphics::CleanupModel(int id) | |
| 377 | +{ | |
| 378 | + if( (id < 0)||((MAX_MODEL -1) < id) ){ return; } | |
| 379 | + if( pmesh[id] != NULL ){ | |
| 380 | + delete [] pmaterials[id]; | |
| 381 | + | |
| 382 | + pmesh[id]->Release(); | |
| 383 | + pmesh[id] = NULL; | |
| 384 | + } | |
| 385 | +} | |
| 386 | + | |
| 387 | +//! テクスチャを読み込む | |
| 388 | +//! @param filename ファイル名 | |
| 389 | +//! @param texturefont テクスチャフォントフラグ | |
| 390 | +//! @param BlackTransparent 黒を透過する | |
| 391 | +//! @return 成功:テクスチャ認識番号(0以上) 失敗:-1 | |
| 392 | +int D3DGraphics::LoadTexture(char* filename, bool texturefont, bool BlackTransparent) | |
| 393 | +{ | |
| 394 | + int id = -1; | |
| 395 | + int MipLevels; | |
| 396 | + | |
| 397 | + //空いている認識番号を探す | |
| 398 | + for(int i=0; i<MAX_TEXTURE; i++){ | |
| 399 | + if( ptextures[i] == NULL ){ | |
| 400 | + id = i; | |
| 401 | + break; | |
| 402 | + } | |
| 403 | + } | |
| 404 | + if( id == -1 ){ return -1; } | |
| 405 | + | |
| 406 | + //ミップマップレベルを設定 | |
| 407 | + if( texturefont == true ){ | |
| 408 | + MipLevels = 1; | |
| 409 | + } | |
| 410 | + else{ | |
| 411 | + MipLevels = 4;//D3DX_DEFAULT; | |
| 412 | + } | |
| 413 | + | |
| 414 | + //テクスチャを読み込む | |
| 415 | + if( BlackTransparent == false ){ | |
| 416 | + if( FAILED( D3DXCreateTextureFromFileEx(pd3dDevice, filename, D3DX_DEFAULT, D3DX_DEFAULT, MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0x00000000, NULL, NULL, &ptextures[id]) ) ) { | |
| 417 | + return -1; | |
| 418 | + } | |
| 419 | + } | |
| 420 | + else{ | |
| 421 | + if( FAILED( D3DXCreateTextureFromFileEx(pd3dDevice, filename, D3DX_DEFAULT, D3DX_DEFAULT, MipLevels, 0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, D3DCOLOR_ARGB(255, 0, 0, 0), NULL, NULL, &ptextures[id]) ) ) { | |
| 422 | + return -1; | |
| 423 | + } | |
| 424 | + } | |
| 425 | + return id; | |
| 426 | +} | |
| 427 | + | |
| 428 | +//! テクスチャのサイズを取得 | |
| 429 | +//! @param id テクスチャ認識番号 | |
| 430 | +//! @param width 幅を受け取るポインタ | |
| 431 | +//! @param height 高さを受け取るポインタ | |
| 432 | +//! @return 成功:0 失敗:1 | |
| 433 | +//! @attention サーフェイスのサイズを取得します。GPUにロードされたサイズであり、テクスチャ(現物)と異なる場合があります。 | |
| 434 | +int D3DGraphics::GetTextureSize(int id, int *width, int *height) | |
| 435 | +{ | |
| 436 | + //無効な認識番号が指定されていたら、処理せず返す。 | |
| 437 | + if( id == -1 ){ return 1; } | |
| 438 | + if( ptextures[id] == NULL ){ return 1; } | |
| 439 | + | |
| 440 | + IDirect3DSurface9 *surface; | |
| 441 | + D3DSURFACE_DESC desc; | |
| 442 | + | |
| 443 | + //サーフェイスを取得 | |
| 444 | + ptextures[id]->GetSurfaceLevel(0, &surface); | |
| 445 | + | |
| 446 | + //幅と高さを取得 | |
| 447 | + surface->GetDesc(&desc); | |
| 448 | + *width = desc.Width; | |
| 449 | + *height = desc.Height; | |
| 450 | + | |
| 451 | + //サーフェイスを開放 | |
| 452 | + surface->Release(); | |
| 453 | + | |
| 454 | + return 0; | |
| 455 | +} | |
| 456 | + | |
| 457 | +//! テクスチャがアルファ値を含んでいるかチェック | |
| 458 | +//! @param id テクスチャ認識番号 | |
| 459 | +//! @return アルファ値を含む:1 含まない・エラー:0 | |
| 460 | +int D3DGraphics::CheckAlphaTexture(int id) | |
| 461 | +{ | |
| 462 | + //無効な認識番号が指定されていたら、処理せず返す。 | |
| 463 | + if( id == -1 ){ return 0; } | |
| 464 | + if( ptextures[id] == NULL ){ return 0; } | |
| 465 | + | |
| 466 | + IDirect3DSurface9 *surface; | |
| 467 | + D3DSURFACE_DESC desc; | |
| 468 | + int Format; | |
| 469 | + | |
| 470 | + //サーフェイスを取得 | |
| 471 | + ptextures[id]->GetSurfaceLevel(0, &surface); | |
| 472 | + | |
| 473 | + //幅と高さを取得 | |
| 474 | + surface->GetDesc(&desc); | |
| 475 | + Format = desc.Format; | |
| 476 | + | |
| 477 | + //サーフェイスを開放 | |
| 478 | + surface->Release(); | |
| 479 | + | |
| 480 | + //http://msdn.microsoft.com/ja-jp/library/cc324320.aspx | |
| 481 | + if( Format == D3DFMT_A8R8G8B8 ){ return 1; } | |
| 482 | + if( Format == D3DFMT_A1R5G5B5 ){ return 1; } | |
| 483 | + if( Format == D3DFMT_A4R4G4B4 ){ return 1; } | |
| 484 | + if( Format == D3DFMT_A8 ){ return 1; } | |
| 485 | + if( Format == D3DFMT_A8R3G3B2 ){ return 1; } | |
| 486 | + if( Format == D3DFMT_A2B10G10R10 ){ return 1; } | |
| 487 | + if( Format == D3DFMT_A8B8G8R8 ){ return 1; } | |
| 488 | + if( Format == D3DFMT_A2R10G10B10 ){ return 1; } | |
| 489 | + if( Format == D3DFMT_A16B16G16R16 ){ return 1; } | |
| 490 | + if( Format == D3DFMT_A8P8 ){ return 1; } | |
| 491 | + if( Format == D3DFMT_A8L8 ){ return 1; } | |
| 492 | + if( Format == D3DFMT_A4L4 ){ return 1; } | |
| 493 | + | |
| 494 | + return 0; | |
| 495 | +} | |
| 496 | + | |
| 497 | +//! テクスチャを解放 | |
| 498 | +//! @param id テクスチャ認識番号 | |
| 499 | +void D3DGraphics::CleanupTexture(int id) | |
| 500 | +{ | |
| 501 | + if( (id < 0)||((MAX_TEXTURE -1) < id) ){ return; } | |
| 502 | + if( ptextures[id] != NULL ){ | |
| 503 | + ptextures[id]->Release(); | |
| 504 | + ptextures[id] = NULL; | |
| 505 | + } | |
| 506 | +} | |
| 507 | + | |
| 508 | +//! 全ての描画処理を開始 | |
| 509 | +//! @return 成功:0 失敗:1 | |
| 510 | +//! @attention 描画処理の最初に呼び出す必要があります。 | |
| 511 | +int D3DGraphics::StartRender() | |
| 512 | +{ | |
| 513 | + if( StartRenderFlag == true ){ return 1; } | |
| 514 | + | |
| 515 | + //領域を初期化 | |
| 516 | + pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); | |
| 517 | + | |
| 518 | + if( SUCCEEDED( pd3dDevice->BeginScene() ) ){ | |
| 519 | + //Zバッファ初期化 | |
| 520 | + pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | |
| 521 | + | |
| 522 | + //座標ゼロ地点にワールド変換行列 | |
| 523 | + ResetWorldTransform(); | |
| 524 | + | |
| 525 | + //描画中のフラグを立てる | |
| 526 | + StartRenderFlag = true; | |
| 527 | + return 0; | |
| 528 | + } | |
| 529 | + | |
| 530 | + return 1; | |
| 531 | +} | |
| 532 | + | |
| 533 | +//! 全ての描画処理を終了 | |
| 534 | +//! @attention 描画処理の最後に呼び出す必要があります。 | |
| 535 | +void D3DGraphics::EndRender() | |
| 536 | +{ | |
| 537 | + //描画中なら終了 | |
| 538 | + if( StartRenderFlag == true ){ | |
| 539 | + pd3dDevice->EndScene(); | |
| 540 | + } | |
| 541 | + | |
| 542 | + pd3dDevice->Present(NULL, NULL, NULL, NULL); | |
| 543 | + | |
| 544 | + //フラグを false に | |
| 545 | + StartRenderFlag = false; | |
| 546 | +} | |
| 547 | + | |
| 548 | +//! Zバッファをリセット | |
| 549 | +void D3DGraphics::ResetZbuffer() | |
| 550 | +{ | |
| 551 | + //Zバッファを一度無効にし、初期化後、再度有効に | |
| 552 | + pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); | |
| 553 | + pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0); | |
| 554 | + pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | |
| 555 | +} | |
| 556 | + | |
| 557 | +//! ワールド空間を原点(0,0,0)に戻す など | |
| 558 | +void D3DGraphics::ResetWorldTransform() | |
| 559 | +{ | |
| 560 | + D3DXMATRIX matWorld; | |
| 561 | + D3DXMatrixIdentity(&matWorld); | |
| 562 | + pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); | |
| 563 | +} | |
| 564 | + | |
| 565 | +//! ワールド空間の座標・角度・拡大率を設定 | |
| 566 | +//! @param x X座標 | |
| 567 | +//! @param y Y座標 | |
| 568 | +//! @param z Z座標 | |
| 569 | +//! @param rx 横軸角度 | |
| 570 | +//! @param ry 縦軸角度 | |
| 571 | +//! @param size 拡大率 | |
| 572 | +void D3DGraphics::SetWorldTransform(float x, float y, float z, float rx, float ry, float size) | |
| 573 | +{ | |
| 574 | + SetWorldTransform(x, y, z, rx, ry, 0.0f, size); | |
| 575 | +} | |
| 576 | + | |
| 577 | +//! ワールド空間の座標・角度・拡大率を設定 | |
| 578 | +//! @param x X座標 | |
| 579 | +//! @param y Y座標 | |
| 580 | +//! @param z Z座標 | |
| 581 | +//! @param rx 横軸角度 | |
| 582 | +//! @param ry1 縦軸角度 | |
| 583 | +//! @param ry2 縦軸角度 | |
| 584 | +//! @param size 拡大率 | |
| 585 | +void D3DGraphics::SetWorldTransform(float x, float y, float z, float rx, float ry1, float ry2, float size) | |
| 586 | +{ | |
| 587 | + D3DXMATRIX matWorld; | |
| 588 | + D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5; | |
| 589 | + | |
| 590 | + //行列を作成 | |
| 591 | + D3DXMatrixTranslation(&matWorld1, x, y, z); | |
| 592 | + D3DXMatrixRotationY(&matWorld2, rx); | |
| 593 | + D3DXMatrixRotationX(&matWorld3, ry1); | |
| 594 | + D3DXMatrixRotationZ(&matWorld4, ry2); | |
| 595 | + D3DXMatrixScaling(&matWorld5, size, size, size); | |
| 596 | + | |
| 597 | + //計算 | |
| 598 | + matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1; | |
| 599 | + | |
| 600 | + //適用 | |
| 601 | + pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); | |
| 602 | +} | |
| 603 | + | |
| 604 | +//! ワールド空間の座標・角度・拡大率を設定(エフェクト用) | |
| 605 | +//! @param x X座標 | |
| 606 | +//! @param y Y座標 | |
| 607 | +//! @param z Z座標 | |
| 608 | +//! @param rx 横軸角度 | |
| 609 | +//! @param ry 縦軸角度 | |
| 610 | +//! @param rt 回転角度 | |
| 611 | +//! @param size 拡大率 | |
| 612 | +void D3DGraphics::SetWorldTransformEffect(float x, float y, float z, float rx, float ry, float rt, float size) | |
| 613 | +{ | |
| 614 | + D3DXMATRIX matWorld; | |
| 615 | + D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5; | |
| 616 | + | |
| 617 | + //行列を作成 | |
| 618 | + D3DXMatrixTranslation(&matWorld1, x, y, z); | |
| 619 | + D3DXMatrixRotationY(&matWorld2, rx); | |
| 620 | + D3DXMatrixRotationZ(&matWorld3, ry); | |
| 621 | + D3DXMatrixRotationX(&matWorld4, rt); | |
| 622 | + D3DXMatrixScaling(&matWorld5, size, size, size); | |
| 623 | + | |
| 624 | + //計算 | |
| 625 | + matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1; | |
| 626 | + | |
| 627 | + //適用 | |
| 628 | + pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); | |
| 629 | +} | |
| 630 | + | |
| 631 | +//! ワールド空間を人が武器を持つ場所に設定 | |
| 632 | +//! @param x X座標 | |
| 633 | +//! @param y Y座標 | |
| 634 | +//! @param z Z座標 | |
| 635 | +//! @param mx 手元を原点にした モデルのX座標 | |
| 636 | +//! @param my 手元を原点にした モデルのY座標 | |
| 637 | +//! @param mz 手元を原点にした モデルのZ座標 | |
| 638 | +//! @param rx 横軸角度 | |
| 639 | +//! @param ry 縦軸角度 | |
| 640 | +//! @param size 拡大率 | |
| 641 | +void D3DGraphics::SetWorldTransformHumanWeapon(float x, float y, float z, float mx, float my, float mz, float rx, float ry, float size) | |
| 642 | +{ | |
| 643 | + D3DXMATRIX matWorld; | |
| 644 | + D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5; | |
| 645 | + | |
| 646 | + //行列を作成 | |
| 647 | + D3DXMatrixTranslation(&matWorld1, x, y, z); | |
| 648 | + D3DXMatrixRotationY(&matWorld2, rx); | |
| 649 | + D3DXMatrixRotationX(&matWorld3, ry); | |
| 650 | + D3DXMatrixTranslation(&matWorld4, mx, my, mz); | |
| 651 | + D3DXMatrixScaling(&matWorld5, size, size, size); | |
| 652 | + | |
| 653 | + //計算 | |
| 654 | + matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1; | |
| 655 | + | |
| 656 | + //適用 | |
| 657 | + pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); | |
| 658 | +} | |
| 659 | + | |
| 660 | +//! ワールド空間を所持している武器を表示する場所に設定 | |
| 661 | +//! @param rotation 武器を回転させる | |
| 662 | +//! @param camera_x カメラのX座標 | |
| 663 | +//! @param camera_y カメラのY座標 | |
| 664 | +//! @param camera_z カメラのZ座標 | |
| 665 | +//! @param camera_rx カメラの横軸角度 | |
| 666 | +//! @param camera_ry カメラの縦軸角度 | |
| 667 | +//! @param rx 武器のの縦軸角度 | |
| 668 | +//! @param size 表示サイズ | |
| 669 | +//! @note rotation・・ true:現在持っている武器です。 false:予備の武器です。(rx は無視されます) | |
| 670 | +//! @todo 位置やサイズの微調整 | |
| 671 | +void D3DGraphics::SetWorldTransformPlayerWeapon(bool rotation, float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float rx, float size) | |
| 672 | +{ | |
| 673 | + D3DXMATRIX matWorld; | |
| 674 | + D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5, matWorld6; | |
| 675 | + | |
| 676 | + size = size * 0.3f; | |
| 677 | + | |
| 678 | + //行列を作成 | |
| 679 | + D3DXMatrixTranslation(&matWorld1, camera_x, camera_y, camera_z); | |
| 680 | + D3DXMatrixRotationY(&matWorld2, camera_rx *-1); | |
| 681 | + D3DXMatrixRotationZ(&matWorld3, camera_ry); | |
| 682 | + // matWorld4 = [奥行き, 縦, 横] | |
| 683 | + if( rotation == true ){ | |
| 684 | + D3DXMatrixTranslation(&matWorld4, 6.0f, -3.2f, -2.8f); | |
| 685 | + D3DXMatrixRotationY(&matWorld5, rx); | |
| 686 | + } | |
| 687 | + else{ | |
| 688 | + D3DXMatrixTranslation(&matWorld4, 12.0f, -6.8f, -8.0f); | |
| 689 | + D3DXMatrixRotationY(&matWorld5, D3DX_PI); | |
| 690 | + } | |
| 691 | + D3DXMatrixScaling(&matWorld6, size, size, size); | |
| 692 | + | |
| 693 | + //計算 | |
| 694 | + matWorld = matWorld6 * matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1; | |
| 695 | + | |
| 696 | + //適用 | |
| 697 | + pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld ); | |
| 698 | +} | |
| 699 | + | |
| 700 | +//! ワールド空間の座標を取得 | |
| 701 | +//! @param *x x軸を受け取るポインタ | |
| 702 | +//! @param *y y軸を受け取るポインタ | |
| 703 | +//! @param *z z軸を受け取るポインタ | |
| 704 | +void D3DGraphics::GetWorldTransformPos(float *x, float *y, float *z) | |
| 705 | +{ | |
| 706 | + D3DXMATRIX matWorld; | |
| 707 | + pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld ); | |
| 708 | + *x = matWorld._41; | |
| 709 | + *y = matWorld._42; | |
| 710 | + *z = matWorld._43; | |
| 711 | +} | |
| 712 | + | |
| 713 | +//! フォグを設定 | |
| 714 | +//! @param skynumber 空の番号 | |
| 715 | +void D3DGraphics::SetFog(int skynumber) | |
| 716 | +{ | |
| 717 | + D3DCOLOR skycolor; | |
| 718 | + | |
| 719 | + //空の番号により色を決定 | |
| 720 | + switch(skynumber){ | |
| 721 | + case 1: skycolor = D3DCOLOR_RGBA(64, 64+16, 64, 0); break; | |
| 722 | + case 2: skycolor = D3DCOLOR_RGBA(16, 16, 16, 0); break; | |
| 723 | + case 3: skycolor = D3DCOLOR_RGBA(0, 16, 32, 0); break; | |
| 724 | + case 4: skycolor = D3DCOLOR_RGBA(32, 16, 16, 0); break; | |
| 725 | + case 5: skycolor = D3DCOLOR_RGBA(64, 32, 32, 0); break; | |
| 726 | + default: skycolor = D3DCOLOR_RGBA(0, 0, 0, 0); break; | |
| 727 | + } | |
| 728 | + | |
| 729 | + //フォグを設定 | |
| 730 | + pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, skycolor); | |
| 731 | +} | |
| 732 | + | |
| 733 | +//! カメラ(視点)を設定 | |
| 734 | +//! @param camera_x カメラのX座標 | |
| 735 | +//! @param camera_y カメラのY座標 | |
| 736 | +//! @param camera_z カメラのZ座標 | |
| 737 | +//! @param camera_rx カメラの横軸角度 | |
| 738 | +//! @param camera_ry カメラの縦軸角度 | |
| 739 | +//! @param viewangle 視野角 | |
| 740 | +void D3DGraphics::SetCamera(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float viewangle) | |
| 741 | +{ | |
| 742 | + float vUpVecF; | |
| 743 | + D3DXMATRIX matWorld; | |
| 744 | + D3DXMATRIXA16 matView; | |
| 745 | + | |
| 746 | + //camera_ryを -PI〜PI の間に正規化 | |
| 747 | + for(; camera_ry>D3DX_PI; camera_ry -= D3DX_PI*2){} | |
| 748 | + for(; camera_ry<D3DX_PI*-1; camera_ry += D3DX_PI*2){} | |
| 749 | + | |
| 750 | + //カメラの向きを決定 | |
| 751 | + if( abs(camera_ry) < D3DX_PI/2 ){ | |
| 752 | + vUpVecF = 1.0f; | |
| 753 | + } | |
| 754 | + else{ | |
| 755 | + vUpVecF = -1.0f; | |
| 756 | + } | |
| 757 | + | |
| 758 | + D3DXMatrixIdentity(&matWorld); | |
| 759 | + pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld); | |
| 760 | + | |
| 761 | + //カメラ座標 | |
| 762 | + D3DXVECTOR3 vEyePt( camera_x, camera_y, camera_z ); | |
| 763 | + D3DXVECTOR3 vLookatPt( cos(camera_rx)*cos(camera_ry) + camera_x, sin(camera_ry) + camera_y, sin(camera_rx)*cos(camera_ry) + camera_z ); | |
| 764 | + D3DXVECTOR3 vUpVec( 0.0f, vUpVecF, 0.0f ); | |
| 765 | + D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); | |
| 766 | + pd3dDevice->SetTransform( D3DTS_VIEW, &matView ); | |
| 767 | + | |
| 768 | + //カメラ設定(射影変換行列)viewangle | |
| 769 | + D3DXMATRIXA16 matProj; | |
| 770 | + D3DXMatrixPerspectiveFovLH( &matProj, viewangle, aspect, CLIPPINGPLANE_NEAR, CLIPPINGPLANE_FAR); | |
| 771 | + pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj); | |
| 772 | +} | |
| 773 | + | |
| 774 | +//! マップデータを取り込む | |
| 775 | +//! @param in_blockdata ブロックデータ | |
| 776 | +//! @param directory ブロックデータが存在するディレクトリ | |
| 777 | +void D3DGraphics::LoadMapdata(BlockDataInterface* in_blockdata, char *directory) | |
| 778 | +{ | |
| 779 | + //ブロックデータが指定されていなければ、処理しない。 | |
| 780 | + if( in_blockdata == NULL ){ return; } | |
| 781 | + | |
| 782 | + char fname[MAX_PATH]; | |
| 783 | + char fnamefull[MAX_PATH]; | |
| 784 | + //int bs; | |
| 785 | + struct blockdata data; | |
| 786 | + int vID[4]; | |
| 787 | + int uvID[4]; | |
| 788 | + | |
| 789 | + //クラスを設定 | |
| 790 | + blockdata = in_blockdata; | |
| 791 | + | |
| 792 | + //テクスチャ読み込み | |
| 793 | + for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){ | |
| 794 | + //テクスチャ名を取得 | |
| 795 | + blockdata->GetTexture(fname, i); | |
| 796 | + | |
| 797 | + if( strcmp(fname, "") == 0 ){ //指定されていなければ、処理しない | |
| 798 | + mapTextureID[i] = -1; | |
| 799 | + } | |
| 800 | + else{ | |
| 801 | + //「ディレクトリ+ファイル名」を生成し、読み込む | |
| 802 | + strcpy(fnamefull, directory); | |
| 803 | + strcat(fnamefull, fname); | |
| 804 | + mapTextureID[i] = LoadTexture(fnamefull, false, false); | |
| 805 | + } | |
| 806 | + } | |
| 807 | + | |
| 808 | +#ifdef BLOCKDATA_GPUMEMORY | |
| 809 | + VERTEXTXTA* pVertices; | |
| 810 | + | |
| 811 | + //ブロック数を取得 | |
| 812 | + bs = blockdata->GetTotaldatas(); | |
| 813 | + | |
| 814 | + //ブロック数分のバッファーを作成 | |
| 815 | + pd3dDevice->CreateVertexBuffer(bs*6*4*sizeof(VERTEXTXTA),0,D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1,D3DPOOL_DEFAULT,&g_pVB,NULL); | |
| 816 | + | |
| 817 | + for(int i=0; i<bs; i++){ | |
| 818 | + //データを取得 | |
| 819 | + blockdata->Getdata(&data, i); | |
| 820 | + | |
| 821 | + for(int j=0; j<6; j++){ | |
| 822 | + //面の頂点データの関連付けを取得 | |
| 823 | + blockdataface(j, &vID[0], &uvID[0]); | |
| 824 | + | |
| 825 | + //GPUをロック(1面分) | |
| 826 | + g_pVB->Lock((i*6+j)*4*sizeof(VERTEXTXTA), 4*sizeof(VERTEXTXTA), (void**)&pVertices, 0); | |
| 827 | + | |
| 828 | + //頂点座標・UV座標・色を設定 | |
| 829 | + pVertices[0].position = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] ); | |
| 830 | + pVertices[0].tu = data.material[j].u[ uvID[1] ]; | |
| 831 | + pVertices[0].tv = data.material[j].v[ uvID[1] ]; | |
| 832 | + pVertices[1].position = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] ); | |
| 833 | + pVertices[1].tu = data.material[j].u[ uvID[2] ]; | |
| 834 | + pVertices[1].tv = data.material[j].v[ uvID[2] ]; | |
| 835 | + pVertices[2].position = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] ); | |
| 836 | + pVertices[2].tu = data.material[j].u[ uvID[0] ]; | |
| 837 | + pVertices[2].tv = data.material[j].v[ uvID[0] ]; | |
| 838 | + pVertices[3].position = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] ); | |
| 839 | + pVertices[3].tu = data.material[j].u[ uvID[3] ]; | |
| 840 | + pVertices[3].tv = data.material[j].v[ uvID[3] ]; | |
| 841 | + for(int k=0; k<4; k++){ | |
| 842 | + pVertices[k].color = D3DCOLOR_COLORVALUE(data.material[j].shadow, data.material[j].shadow, data.material[j].shadow, 1.0f); | |
| 843 | + } | |
| 844 | + | |
| 845 | + //GPUのロックを解除 | |
| 846 | + g_pVB->Unlock(); | |
| 847 | + } | |
| 848 | + } | |
| 849 | +#else | |
| 850 | + //ブロック数を取得 | |
| 851 | + bs = blockdata->GetTotaldatas(); | |
| 852 | + | |
| 853 | + for(int i=0; i<bs; i++){ | |
| 854 | + //データを取得 | |
| 855 | + blockdata->Getdata(&data, i); | |
| 856 | + | |
| 857 | + for(int j=0; j<6; j++){ | |
| 858 | + //面の頂点データの関連付けを取得 | |
| 859 | + blockdataface(j, vID, uvID); | |
| 860 | + | |
| 861 | + //頂点座標・UV座標・色を設定 | |
| 862 | + g_pVertices[i][j][0].position = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] ); | |
| 863 | + g_pVertices[i][j][0].tu = data.material[j].u[ uvID[1] ]; | |
| 864 | + g_pVertices[i][j][0].tv = data.material[j].v[ uvID[1] ]; | |
| 865 | + g_pVertices[i][j][1].position = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] ); | |
| 866 | + g_pVertices[i][j][1].tu = data.material[j].u[ uvID[2] ]; | |
| 867 | + g_pVertices[i][j][1].tv = data.material[j].v[ uvID[2] ]; | |
| 868 | + g_pVertices[i][j][2].position = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] ); | |
| 869 | + g_pVertices[i][j][2].tu = data.material[j].u[ uvID[0] ]; | |
| 870 | + g_pVertices[i][j][2].tv = data.material[j].v[ uvID[0] ]; | |
| 871 | + g_pVertices[i][j][3].position = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] ); | |
| 872 | + g_pVertices[i][j][3].tu = data.material[j].u[ uvID[3] ]; | |
| 873 | + g_pVertices[i][j][3].tv = data.material[j].v[ uvID[3] ]; | |
| 874 | + for(int k=0; k<4; k++){ | |
| 875 | + g_pVertices[i][j][k].color = D3DCOLOR_COLORVALUE(data.material[j].shadow, data.material[j].shadow, data.material[j].shadow, 1.0f); | |
| 876 | + } | |
| 877 | + } | |
| 878 | + } | |
| 879 | +#endif | |
| 880 | +} | |
| 881 | + | |
| 882 | +//! マップデータを描画 | |
| 883 | +void D3DGraphics::DrawMapdata() | |
| 884 | +{ | |
| 885 | + //ブロックデータが読み込まれていなければ、処理しない。 | |
| 886 | + if( blockdata == NULL ){ return; } | |
| 887 | + | |
| 888 | + struct blockdata data; | |
| 889 | + D3DMATERIAL9 mtrl = {0}; | |
| 890 | + int textureID; | |
| 891 | + | |
| 892 | + //深度バッファ比較関数を設定 | |
| 893 | + //pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); | |
| 894 | + | |
| 895 | + | |
| 896 | +#ifdef BLOCKDATA_GPUMEMORY | |
| 897 | + //データ設定 | |
| 898 | + pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(VERTEXTXTA)); | |
| 899 | + | |
| 900 | + for(textureID=0; textureID<TOTAL_BLOCKTEXTURE; textureID++){ | |
| 901 | + //テクスチャが正常に読み込めていなければ設定 | |
| 902 | + if( mapTextureID[textureID] == -1 ){ | |
| 903 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); | |
| 904 | + pd3dDevice->SetTexture(0, NULL); | |
| 905 | + } | |
| 906 | + else{ | |
| 907 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); | |
| 908 | + pd3dDevice->SetTexture(0, ptextures[mapTextureID[textureID]] ); | |
| 909 | + } | |
| 910 | + | |
| 911 | + for(int i=0; i<bs; i++){ | |
| 912 | + //データ取得 | |
| 913 | + blockdata->Getdata(&data, i); | |
| 914 | + | |
| 915 | + for(int j=0; j<6; j++){ | |
| 916 | + //テクスチャ認識番号を取得 | |
| 917 | + int ID = data.material[j].textureID; | |
| 918 | + | |
| 919 | + if( textureID == ID ){ | |
| 920 | + //面を描画 | |
| 921 | + pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i*6+j)*4, 2); | |
| 922 | + } | |
| 923 | + } | |
| 924 | + } | |
| 925 | + } | |
| 926 | +#else | |
| 927 | + //データを設定 | |
| 928 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); | |
| 929 | + | |
| 930 | + for(textureID=0; textureID<TOTAL_BLOCKTEXTURE; textureID++){ | |
| 931 | + //テクスチャが正常に読み込めていなければ設定 | |
| 932 | + if( mapTextureID[textureID] == -1 ){ | |
| 933 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE); | |
| 934 | + pd3dDevice->SetTexture(0, NULL); | |
| 935 | + } | |
| 936 | + else{ | |
| 937 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); | |
| 938 | + pd3dDevice->SetTexture(0, ptextures[mapTextureID[textureID]] ); | |
| 939 | + } | |
| 940 | + | |
| 941 | + for(int i=0; i<bs; i++){ | |
| 942 | + //データ取得 | |
| 943 | + blockdata->Getdata(&data, i); | |
| 944 | + | |
| 945 | + for(int j=0; j<6; j++){ | |
| 946 | + //テクスチャ認識番号を取得 | |
| 947 | + int ID = data.material[j].textureID; | |
| 948 | + | |
| 949 | + if( textureID == ID ){ | |
| 950 | + //面を描画 | |
| 951 | + pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_pVertices[i][j], sizeof(VERTEXTXTA)); | |
| 952 | + } | |
| 953 | + } | |
| 954 | + } | |
| 955 | + } | |
| 956 | +#endif | |
| 957 | + | |
| 958 | + //深度バッファ比較関数を元に戻す | |
| 959 | + //pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); | |
| 960 | +} | |
| 961 | + | |
| 962 | +//! マップテクスチャを取得 | |
| 963 | +//! @param id テクスチャ番号 | |
| 964 | +//! @return テクスチャ認識番号(失敗:-1) | |
| 965 | +int D3DGraphics::GetMapTextureID(int id) | |
| 966 | +{ | |
| 967 | + if( (id < 0)||((TOTAL_BLOCKTEXTURE -1) < id ) ){ return -1; } | |
| 968 | + return mapTextureID[id]; | |
| 969 | +} | |
| 970 | + | |
| 971 | +//! マップデータを解放 | |
| 972 | +void D3DGraphics::CleanupMapdata() | |
| 973 | +{ | |
| 974 | + //テクスチャを開放 | |
| 975 | + for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){ | |
| 976 | + CleanupTexture(mapTextureID[i]); | |
| 977 | + } | |
| 978 | + | |
| 979 | +#ifdef BLOCKDATA_GPUMEMORY | |
| 980 | + //頂点データ解放 | |
| 981 | + if( g_pVB != NULL ){ | |
| 982 | + g_pVB->Release(); | |
| 983 | + g_pVB = NULL; | |
| 984 | + } | |
| 985 | +#endif | |
| 986 | + bs = 0; | |
| 987 | + | |
| 988 | + blockdata = NULL; | |
| 989 | +} | |
| 990 | + | |
| 991 | +//! モデルファイルを描画 | |
| 992 | +//! @param id_model モデル認識番号 | |
| 993 | +//! @param id_texture テクスチャ認識番号 | |
| 994 | +void D3DGraphics::RenderModel(int id_model, int id_texture) | |
| 995 | +{ | |
| 996 | + //無効な引数が設定されていれば失敗 | |
| 997 | + if( id_model == -1 ){ return; } | |
| 998 | + if( id_texture == -1 ){ return; } | |
| 999 | + | |
| 1000 | + //指定したモデルが初期化されていなければ失敗 | |
| 1001 | + if( pmesh[id_model] == NULL) return; | |
| 1002 | + | |
| 1003 | + //描画 | |
| 1004 | + for(int i=0; i<(signed)nummaterials[id_model]; i=i+1){ | |
| 1005 | + pd3dDevice->SetMaterial( &pmaterials[id_model][i] ); | |
| 1006 | + if( ptextures[id_texture] == NULL ){ | |
| 1007 | + pd3dDevice->SetTexture(0, NULL); | |
| 1008 | + } | |
| 1009 | + else{ | |
| 1010 | + pd3dDevice->SetTexture( 0, ptextures[id_texture] ); | |
| 1011 | + } | |
| 1012 | + pmesh[id_model]->DrawSubset(i); | |
| 1013 | + } | |
| 1014 | +} | |
| 1015 | + | |
| 1016 | +//! 板を描画 | |
| 1017 | +//! @param id_texture テクスチャ認識番号 | |
| 1018 | +//! @param alpha 透明度 (0.0〜1.0 0.0:完全透明) | |
| 1019 | +void D3DGraphics::RenderBoard(int id_texture, float alpha) | |
| 1020 | +{ | |
| 1021 | + //テクスチャが設定されていなければ、処理しない。 | |
| 1022 | + if( id_texture == -1 ){ return; } | |
| 1023 | + | |
| 1024 | + VERTEXTXTA BoardVertices[4]; | |
| 1025 | + | |
| 1026 | + //頂点座標・UV座標・色/透明度を設定 | |
| 1027 | + BoardVertices[0].position = D3DXVECTOR3(0.0f, 0.5f, -0.5f); | |
| 1028 | + BoardVertices[0].tu = 1.0f; | |
| 1029 | + BoardVertices[0].tv = 0.0f; | |
| 1030 | + BoardVertices[1].position = D3DXVECTOR3(0.0f, -0.5f, -0.5f); | |
| 1031 | + BoardVertices[1].tu = 1.0f; | |
| 1032 | + BoardVertices[1].tv = 1.0f; | |
| 1033 | + BoardVertices[2].position = D3DXVECTOR3(0.0f, 0.5f, 0.5f); | |
| 1034 | + BoardVertices[2].tu = 0.0f; | |
| 1035 | + BoardVertices[2].tv = 0.0f; | |
| 1036 | + BoardVertices[3].position = D3DXVECTOR3(0.0f, -0.5f, 0.5f); | |
| 1037 | + BoardVertices[3].tu = 0.0f; | |
| 1038 | + BoardVertices[3].tv = 1.0f; | |
| 1039 | + for(int i=0; i<4; i++){ | |
| 1040 | + BoardVertices[i].color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, alpha); | |
| 1041 | + } | |
| 1042 | + | |
| 1043 | + //アルファブレンドを設定 | |
| 1044 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
| 1045 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
| 1046 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
| 1047 | + | |
| 1048 | + //テクスチャとデータ形式を設定し描画 | |
| 1049 | + pd3dDevice->SetTexture(0, ptextures[id_texture]); | |
| 1050 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); | |
| 1051 | + pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, BoardVertices, sizeof(VERTEXTXTA)); | |
| 1052 | + | |
| 1053 | + //アルファブレンドを元に戻す | |
| 1054 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | |
| 1055 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
| 1056 | +} | |
| 1057 | + | |
| 1058 | +//! 画面の明るさを設定 | |
| 1059 | +//! @param Width 幅 | |
| 1060 | +//! @param Height 高さ | |
| 1061 | +//! @param Brightness 画面の明るさ (0 で不変、1 以上で明るさの度合い) | |
| 1062 | +void D3DGraphics::ScreenBrightness(int Width, int Height, int Brightness) | |
| 1063 | +{ | |
| 1064 | + //明るさ不変なら処理しない(軽量化) | |
| 1065 | + if( Brightness == 0 ){ return; } | |
| 1066 | + | |
| 1067 | + //透明度を設定し、描画 | |
| 1068 | + float alpha = 0.02f * Brightness; | |
| 1069 | + Draw2DBox(0, 0, Width, Height, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,alpha)); | |
| 1070 | +} | |
| 1071 | + | |
| 1072 | +//! 【デバック用】中心線描画 | |
| 1073 | +void D3DGraphics::Centerline() | |
| 1074 | +{ | |
| 1075 | + ResetWorldTransform(); | |
| 1076 | + Drawline(100.0f, 0.0f, 0.0f, -100.0f, 0.0f, 0.0f); | |
| 1077 | + Drawline(0.0f, 100.0f, 0.0f, 0.0f, -100.0f, 0.0f); | |
| 1078 | + Drawline(0.0f, 0.0f, 100.0f, 0.0f, 0.0f, -100.0f); | |
| 1079 | +} | |
| 1080 | + | |
| 1081 | +//! 【デバック用】緑線描画 | |
| 1082 | +void D3DGraphics::Drawline(float x1, float y1, float z1, float x2, float y2, float z2) | |
| 1083 | +{ | |
| 1084 | + VERTEXTXTA mv[2]; | |
| 1085 | + | |
| 1086 | + mv[0].position = D3DXVECTOR3(x1, y1, z1); | |
| 1087 | + mv[1].position = D3DXVECTOR3(x2, y2, z2); | |
| 1088 | + for(int i=0; i<2; i++){ | |
| 1089 | + mv[i].color = 0xFF00FF00; | |
| 1090 | + mv[i].tu = 0.0f; | |
| 1091 | + mv[i].tv = 0.0f; | |
| 1092 | + } | |
| 1093 | + | |
| 1094 | + pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1); | |
| 1095 | + pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, mv, sizeof(VERTEXTXTA)); | |
| 1096 | +} | |
| 1097 | + | |
| 1098 | +//! 2D システムフォントによるテキスト描画を開始 | |
| 1099 | +//! @attention DirectXの ID3DXSprite を初期化しています。 | |
| 1100 | +void D3DGraphics::Start2DMSFontTextRender() | |
| 1101 | +{ | |
| 1102 | + ptextsprite->Begin(D3DXSPRITE_ALPHABLEND); | |
| 1103 | +} | |
| 1104 | + | |
| 1105 | +//! 文字を描画(システムフォント使用) | |
| 1106 | +//! @param x x座標 | |
| 1107 | +//! @param y y座標 | |
| 1108 | +//! @param str 文字列 (改行コード:可) | |
| 1109 | +//! @param color 色 | |
| 1110 | +//! @warning <b>描画は非常に低速です。</b>画面内で何度も呼び出すとパフォーマンスに影響します。 | |
| 1111 | +//! @warning「改行コードを活用し一度に描画する」「日本語が必要ない文字はテクスチャフォントを活用する」などの対応を講じてください。 | |
| 1112 | +//! @attention DirectXの ID3DXSprite を使用し、システムフォントで描画ています。 | |
| 1113 | +//! @attention フォントの種類やサイズは固定です。 文字を二重に重ねて立体感を出さないと見にくくなります。 | |
| 1114 | +void D3DGraphics::Draw2DMSFontText(int x, int y, char *str, int color) | |
| 1115 | +{ | |
| 1116 | + //if( ptextsprite == NULL ){ return; } | |
| 1117 | + | |
| 1118 | + //テキストスプライト初期化 | |
| 1119 | + Start2DMSFontTextRender(); | |
| 1120 | + | |
| 1121 | + //基準座標を設定 | |
| 1122 | + D3DXMATRIX matWorld; | |
| 1123 | + D3DXMatrixIdentity(&matWorld); | |
| 1124 | + ptextsprite->SetTransform(&matWorld); | |
| 1125 | + | |
| 1126 | + //文字をを描画 | |
| 1127 | + RECT rc = {x, y, 0, 0}; | |
| 1128 | + pxmsfont->DrawText(ptextsprite, str, -1, &rc, DT_NOCLIP, color); | |
| 1129 | + | |
| 1130 | + //テキストスプライト解放 | |
| 1131 | + End2DMSFontTextRender(); | |
| 1132 | +} | |
| 1133 | + | |
| 1134 | +//! 文字を中央揃えで描画(システムフォント使用) | |
| 1135 | +//! @param x x座標 | |
| 1136 | +//! @param y y座標 | |
| 1137 | +//! @param w 横の大きさ | |
| 1138 | +//! @param h 縦の大きさ | |
| 1139 | +//! @param str 文字列 (改行コード:可) | |
| 1140 | +//! @param color 色 | |
| 1141 | +//! @warning <b>描画は非常に低速です。</b>画面内で何度も呼び出すとパフォーマンスに影響します。 | |
| 1142 | +//! @warning「改行コードを活用し一度に描画する」「日本語が必要ない文字はテクスチャフォントを活用する」などの対応を講じてください。 | |
| 1143 | +//! @attention DirectXの ID3DXSprite を使用し、システムフォントで描画ています。 | |
| 1144 | +//! @attention フォントの種類やサイズは固定です。 文字を二重に重ねて立体感を出さないと見にくくなります。 | |
| 1145 | +void D3DGraphics::Draw2DMSFontTextCenter(int x, int y, int w, int h, char *str, int color) | |
| 1146 | +{ | |
| 1147 | + //if( ptextsprite == NULL ){ return; } | |
| 1148 | + | |
| 1149 | + //テキストスプライト初期化 | |
| 1150 | + Start2DMSFontTextRender(); | |
| 1151 | + | |
| 1152 | + //基準座標を設定 | |
| 1153 | + D3DXMATRIX matWorld; | |
| 1154 | + D3DXMatrixIdentity(&matWorld); | |
| 1155 | + ptextsprite->SetTransform(&matWorld); | |
| 1156 | + | |
| 1157 | + //文字をを描画 | |
| 1158 | + RECT rc = {x, y, x+w, y+h}; | |
| 1159 | + pxmsfont->DrawText(ptextsprite, str, -1, &rc, DT_CENTER, color); | |
| 1160 | + | |
| 1161 | + //テキストスプライト解放 | |
| 1162 | + End2DMSFontTextRender(); | |
| 1163 | +} | |
| 1164 | + | |
| 1165 | +//! 2D システムフォントによるテキスト描画を終了 | |
| 1166 | +//! @attention DirectXの ID3DXSprite を解放しています。 | |
| 1167 | +void D3DGraphics::End2DMSFontTextRender() | |
| 1168 | +{ | |
| 1169 | + ptextsprite->End(); | |
| 1170 | +} | |
| 1171 | + | |
| 1172 | +//! 2D描画用設定 | |
| 1173 | +void D3DGraphics::Start2DRender() | |
| 1174 | +{ | |
| 1175 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | |
| 1176 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
| 1177 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | |
| 1178 | + | |
| 1179 | + //深度バッファ比較関数を設定 | |
| 1180 | + pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); | |
| 1181 | +} | |
| 1182 | + | |
| 1183 | +//! 文字を描画(テクスチャフォント使用) | |
| 1184 | +//! @param x x座標 | |
| 1185 | +//! @param y y座標 | |
| 1186 | +//! @param str 文字列 (改行コード:<b>不可</b>) | |
| 1187 | +//! @param color 色 | |
| 1188 | +//! @param fontwidth 一文字の幅 | |
| 1189 | +//! @param fontheight 一文字の高さ | |
| 1190 | +//! @attention 文字を二重に重ねて立体感を出さないと見にくくなります。 | |
| 1191 | +void D3DGraphics::Draw2DTextureFontText(int x, int y, char *str, int color, int fontwidth, int fontheight) | |
| 1192 | +{ | |
| 1193 | + //テクスチャフォントの取得に失敗していれば、処理しない | |
| 1194 | + if( TextureFont == -1 ){ return; } | |
| 1195 | + | |
| 1196 | + //2D描画用設定を適用 | |
| 1197 | + Start2DRender(); | |
| 1198 | + | |
| 1199 | + int w; | |
| 1200 | + float font_u, font_v; | |
| 1201 | + float t_u, t_v; | |
| 1202 | + TLVERTX pBoxVertices[4]; | |
| 1203 | + | |
| 1204 | + //1文字のUV座標を計算 | |
| 1205 | + font_u = 1.0f / 16; | |
| 1206 | + font_v = 1.0f / 16; | |
| 1207 | + | |
| 1208 | + //ワールド座標を原点に戻す | |
| 1209 | + ResetWorldTransform(); | |
| 1210 | + | |
| 1211 | + //テクスチャをフォントテクスチャに設定 | |
| 1212 | + pd3dDevice->SetTexture( 0, ptextures[TextureFont] ); | |
| 1213 | + | |
| 1214 | + //データ形式を設定 | |
| 1215 | + pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); | |
| 1216 | + | |
| 1217 | + // 与えられた文字数分ループ | |
| 1218 | + for(int i=0; i<(int)strlen(str); i++){ | |
| 1219 | + //UV座標を計算 | |
| 1220 | + w = str[i]; | |
| 1221 | + if( w < 0 ){ w += 256; } | |
| 1222 | + t_u = (w % 16) * font_u; | |
| 1223 | + t_v = (w / 16) * font_v; | |
| 1224 | + | |
| 1225 | + //頂点座標・UV座標・色を設定 | |
| 1226 | + pBoxVertices[0].x = (float)x + i*fontwidth; | |
| 1227 | + pBoxVertices[0].y = (float)y; | |
| 1228 | + pBoxVertices[0].tu = t_u; | |
| 1229 | + pBoxVertices[0].tv = t_v; | |
| 1230 | + pBoxVertices[1].x = (float)x + fontwidth + i*fontwidth; | |
| 1231 | + pBoxVertices[1].y = (float)y; | |
| 1232 | + pBoxVertices[1].tu = t_u + font_u; | |
| 1233 | + pBoxVertices[1].tv = t_v; | |
| 1234 | + pBoxVertices[2].x = (float)x + i*fontwidth; | |
| 1235 | + pBoxVertices[2].y = (float)y + fontheight; | |
| 1236 | + pBoxVertices[2].tu = t_u; | |
| 1237 | + pBoxVertices[2].tv = t_v + font_v; | |
| 1238 | + pBoxVertices[3].x = (float)x + fontwidth + i*fontwidth; | |
| 1239 | + pBoxVertices[3].y = (float)y + fontheight; | |
| 1240 | + pBoxVertices[3].tu = t_u + font_u; | |
| 1241 | + pBoxVertices[3].tv = t_v + font_v; | |
| 1242 | + for(int j=0; j<4; j++){ | |
| 1243 | + pBoxVertices[j].z = 0.0f; | |
| 1244 | + pBoxVertices[j].rhw = 1.0f; | |
| 1245 | + pBoxVertices[j].color = color; | |
| 1246 | + } | |
| 1247 | + | |
| 1248 | + //描画 | |
| 1249 | + pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX)); | |
| 1250 | + } | |
| 1251 | + | |
| 1252 | + //2D描画用設定を解除 | |
| 1253 | + End2DRender(); | |
| 1254 | +} | |
| 1255 | + | |
| 1256 | +//! 線を描画 | |
| 1257 | +//! @param x1 始点の x座標 | |
| 1258 | +//! @param y1 始点の y座標 | |
| 1259 | +//! @param x2 終点の x座標 | |
| 1260 | +//! @param y2 終点の y座標 | |
| 1261 | +//! @param color 色 | |
| 1262 | +void D3DGraphics::Draw2DLine(int x1, int y1, int x2, int y2, int color) | |
| 1263 | +{ | |
| 1264 | + TLVERTX pLineVertices[2]; | |
| 1265 | + | |
| 1266 | + //2D描画用設定を適用 | |
| 1267 | + Start2DRender(); | |
| 1268 | + | |
| 1269 | + //ワールド座標を原点に戻す | |
| 1270 | + ResetWorldTransform(); | |
| 1271 | + | |
| 1272 | + //頂点座標と色などを設定 | |
| 1273 | + pLineVertices[0].x = (float)x1; | |
| 1274 | + pLineVertices[0].y = (float)y1; | |
| 1275 | + pLineVertices[1].x = (float)x2; | |
| 1276 | + pLineVertices[1].y = (float)y2; | |
| 1277 | + for(int i=0; i<2; i++){ | |
| 1278 | + pLineVertices[i].z = 0.0f; | |
| 1279 | + pLineVertices[i].rhw = 1.0f; | |
| 1280 | + pLineVertices[i].color = color; | |
| 1281 | + pLineVertices[i].tu = 0.0f; | |
| 1282 | + pLineVertices[i].tv = 0.0f; | |
| 1283 | + } | |
| 1284 | + | |
| 1285 | + pd3dDevice->SetTexture(0, NULL); | |
| 1286 | + | |
| 1287 | + //データ形式を設定し、描画。 | |
| 1288 | + pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); | |
| 1289 | + pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 2, pLineVertices, sizeof(TLVERTX)); | |
| 1290 | + | |
| 1291 | + //2D描画用設定を解除 | |
| 1292 | + End2DRender(); | |
| 1293 | +} | |
| 1294 | + | |
| 1295 | +//! 四角形を描画 | |
| 1296 | +//! @param x1 左上の x座標 | |
| 1297 | +//! @param y1 左上の y座標 | |
| 1298 | +//! @param x2 右下の x座標 | |
| 1299 | +//! @param y2 右下の y座標 | |
| 1300 | +//! @param color 色 | |
| 1301 | +void D3DGraphics::Draw2DBox(int x1, int y1, int x2, int y2, int color) | |
| 1302 | +{ | |
| 1303 | + TLVERTX pBoxVertices[4]; | |
| 1304 | + | |
| 1305 | + //2D描画用設定を適用 | |
| 1306 | + Start2DRender(); | |
| 1307 | + | |
| 1308 | + //ワールド座標を原点に戻す | |
| 1309 | + ResetWorldTransform(); | |
| 1310 | + | |
| 1311 | + //頂点座標と色などを設定 | |
| 1312 | + pBoxVertices[0].x = (float)x1; | |
| 1313 | + pBoxVertices[0].y = (float)y1; | |
| 1314 | + pBoxVertices[1].x = (float)x2; | |
| 1315 | + pBoxVertices[1].y = (float)y1; | |
| 1316 | + pBoxVertices[2].x = (float)x1; | |
| 1317 | + pBoxVertices[2].y = (float)y2; | |
| 1318 | + pBoxVertices[3].x = (float)x2; | |
| 1319 | + pBoxVertices[3].y = (float)y2; | |
| 1320 | + for(int i=0; i<4; i++){ | |
| 1321 | + pBoxVertices[i].z = 0.0f; | |
| 1322 | + pBoxVertices[i].rhw = 1.0f; | |
| 1323 | + pBoxVertices[i].color = color; | |
| 1324 | + pBoxVertices[i].tu = 0.0f; | |
| 1325 | + pBoxVertices[i].tv = 0.0f; | |
| 1326 | + } | |
| 1327 | + | |
| 1328 | + pd3dDevice->SetTexture(0, NULL); | |
| 1329 | + | |
| 1330 | + //データ形式を設定し、描画。 | |
| 1331 | + pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); | |
| 1332 | + pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX)); | |
| 1333 | + | |
| 1334 | + //2D描画用設定を解除 | |
| 1335 | + End2DRender(); | |
| 1336 | +} | |
| 1337 | + | |
| 1338 | +//! 画像を描画 | |
| 1339 | +//! @param x x座標 | |
| 1340 | +//! @param y y座標 | |
| 1341 | +//! @param id テクスチャ認識番号 | |
| 1342 | +//! @param width 幅 | |
| 1343 | +//! @param height 高さ | |
| 1344 | +//! @param alpha 透明度(0.0〜1.0) | |
| 1345 | +void D3DGraphics::Draw2DTexture(int x, int y, int id, int width, int height, float alpha) | |
| 1346 | +{ | |
| 1347 | + //無効なテクスチャ番号を指定されていれば処理しない | |
| 1348 | + if( id == -1 ){ return; } | |
| 1349 | + | |
| 1350 | + TLVERTX pBoxVertices[4]; | |
| 1351 | + | |
| 1352 | + //2D描画用設定を適用 | |
| 1353 | + Start2DRender(); | |
| 1354 | + | |
| 1355 | + //ワールド座標を原点に戻す | |
| 1356 | + ResetWorldTransform(); | |
| 1357 | + | |
| 1358 | + //頂点座標・UV座標・色を設定 | |
| 1359 | + pBoxVertices[0].x = (float)x; | |
| 1360 | + pBoxVertices[0].y = (float)y; | |
| 1361 | + pBoxVertices[0].tu = 0.0f; | |
| 1362 | + pBoxVertices[0].tv = 0.0f; | |
| 1363 | + pBoxVertices[1].x = (float)x + width; | |
| 1364 | + pBoxVertices[1].y = (float)y; | |
| 1365 | + pBoxVertices[1].tu = 1.0f; | |
| 1366 | + pBoxVertices[1].tv = 0.0f; | |
| 1367 | + pBoxVertices[2].x = (float)x; | |
| 1368 | + pBoxVertices[2].y = (float)y + height; | |
| 1369 | + pBoxVertices[2].tu = 0.0f; | |
| 1370 | + pBoxVertices[2].tv = 1.0f; | |
| 1371 | + pBoxVertices[3].x = (float)x + width; | |
| 1372 | + pBoxVertices[3].y = (float)y + height; | |
| 1373 | + pBoxVertices[3].tu = 1.0f; | |
| 1374 | + pBoxVertices[3].tv = 1.0f; | |
| 1375 | + for(int i=0; i<4; i++){ | |
| 1376 | + pBoxVertices[i].z = 0.0f; | |
| 1377 | + pBoxVertices[i].rhw = 1.0f; | |
| 1378 | + pBoxVertices[i].color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,alpha); | |
| 1379 | + } | |
| 1380 | + | |
| 1381 | + //テクスチャとデータ形式を設定し、描画 | |
| 1382 | + pd3dDevice->SetTexture( 0, ptextures[id] ); | |
| 1383 | + pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); | |
| 1384 | + pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX)); | |
| 1385 | + | |
| 1386 | + //2D描画用設定を解除 | |
| 1387 | + End2DRender(); | |
| 1388 | +} | |
| 1389 | + | |
| 1390 | +//! 2D描画用設定を解除 | |
| 1391 | +void D3DGraphics::End2DRender() | |
| 1392 | +{ | |
| 1393 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | |
| 1394 | + pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | |
| 1395 | + | |
| 1396 | + //深度バッファ比較関数を元に戻す | |
| 1397 | + pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); | |
| 1398 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,130 @@ | ||
| 1 | +//! @file resource.h | |
| 2 | +//! @brief ResourceManagerクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef RESOURCE_H | |
| 33 | +#define RESOURCE_H | |
| 34 | + | |
| 35 | +#define TOTAL_UPMODE 6 //!< 上半身の合計モデル | |
| 36 | +#define TOTAL_ARMMODE 3 //!< 腕の合計モデル | |
| 37 | +#define TOTAL_WALKMODE 8 //!< 足(歩き)の合計モデル | |
| 38 | +#define TOTAL_RUNMODE 12 //!< 足(走り)の合計モデル | |
| 39 | + | |
| 40 | +#define MAX_LOADHUMANTEXTURE 10 //!< 人のテクスチャを読み込む最大枚数 | |
| 41 | + | |
| 42 | +#ifndef H_LAYERLEVEL | |
| 43 | + #define H_LAYERLEVEL 2 //!< Select include file. | |
| 44 | +#endif | |
| 45 | +#include "main.h" | |
| 46 | + | |
| 47 | +//! @brief リソース管理クラス | |
| 48 | +//! @details 主に使用されるモデルやテクスチャおよびサウンドを管理します。 (一部を除く) | |
| 49 | +class ResourceManager | |
| 50 | +{ | |
| 51 | + class ParameterInfo *ParamInfo; //!< 管理する設定値情報クラス | |
| 52 | + class D3DGraphics *d3dg; //!< 管理する描画クラス | |
| 53 | + class SoundControl *SoundCtrl; //!< 管理するサウンドクラス | |
| 54 | + | |
| 55 | + int human_upmodel[TOTAL_UPMODE]; //!< 上半身のモデル | |
| 56 | + int human_armmodel[TOTAL_ARMMODE]; //!< 腕のモデル | |
| 57 | + int human_legmodel; //!< 足(静止状態)のモデル | |
| 58 | + int human_walkmodel[TOTAL_WALKMODE]; //!< 足(歩き)のモデル | |
| 59 | + int human_runmodel[TOTAL_RUNMODE]; //!< 足(走り)のモデル | |
| 60 | + int human_texture_Param[MAX_LOADHUMANTEXTURE]; //!< 人のテクスチャの対応番号 | |
| 61 | + int human_texture_d3dg[MAX_LOADHUMANTEXTURE]; //!< 人のテクスチャの認識番号 | |
| 62 | + int weapon_model[TOTAL_PARAMETERINFO_WEAPON]; //!< 武器のモデル認識番号 | |
| 63 | + int weapon_texture[TOTAL_PARAMETERINFO_WEAPON]; //!< 武器のテクスチャ認識番号 | |
| 64 | + int weapon_sound[TOTAL_PARAMETERINFO_WEAPON]; //!< 武器のサウンド認識番号 | |
| 65 | + int weapon_reloadsound; //!< 武器のリロードサウンド認識番号 | |
| 66 | + int smallobject_model[TOTAL_PARAMETERINFO_SMALLOBJECT+1]; //!< 小物のモデル認識番号 | |
| 67 | + int smallobject_texture[TOTAL_PARAMETERINFO_SMALLOBJECT+1]; //!< 小物のテクスチャ認識番号 | |
| 68 | + int smallobject_sound[TOTAL_PARAMETERINFO_SMALLOBJECT+1]; //!< 小物のサウンド認識番号 | |
| 69 | + | |
| 70 | + int scopetexture; //!< スコープのテクスチャ | |
| 71 | + int skymodel; //!< 空背景のモデル | |
| 72 | + int skytexture; //!< 空背景のテクスチャ | |
| 73 | + int bulletmodel; //!< 弾のモデル | |
| 74 | + int bullettexture; //!< 弾のテクスチャ | |
| 75 | + int bullet_hitsoundA; //!< 弾のヒットサウンド(A) | |
| 76 | + int bullet_hitsoundB; //!< 弾のヒットサウンド(B) | |
| 77 | + int bullet_humanhitsound; //!< 弾のヒットサウンド(人) | |
| 78 | + int bullet_passingsound; //!< 弾の通過サウンド | |
| 79 | + int grenade_bang; //!< 手榴弾の爆発音 | |
| 80 | + int grenade_cco; //!< 手榴弾のバウンド音 | |
| 81 | + int effecttexture_blood; //!< エフェクト用・血テクスチャ | |
| 82 | + int effecttexture_mflash; //!< エフェクト用・フラッシュテクスチャ | |
| 83 | + int effecttexture_smoke; //!< エフェクト用・煙テクスチャ | |
| 84 | + int effecttexture_yakkyou; //!< エフェクト用・薬莢テクスチャ | |
| 85 | + | |
| 86 | +public: | |
| 87 | + ResourceManager(); | |
| 88 | + ~ResourceManager(); | |
| 89 | + void SetParameterInfo(ParameterInfo *_ParamInfo); | |
| 90 | + void SetD3DGraphics(D3DGraphics *_d3dg); | |
| 91 | + void SetSoundControl(SoundControl *_SoundCtrl); | |
| 92 | + | |
| 93 | + int LoadHumanModel(); | |
| 94 | + void GetHumanModel(int out_upmodel[], int out_armmodel[], int *legmodel, int out_walkmodel[], int out_runmodel[]); | |
| 95 | + void CleanupHumanModel(); | |
| 96 | + int AddHumanTexture(int id); | |
| 97 | + int GetHumanTexture(int id); | |
| 98 | + void CleanupHumanTexture(); | |
| 99 | + int LoadWeaponModelTexture(); | |
| 100 | + int GetWeaponModelTexture(int id, int *model, int *texture); | |
| 101 | + void CleanupWeaponModelTexture(); | |
| 102 | + int LoadWeaponSound(); | |
| 103 | + int GetWeaponSound(int id); | |
| 104 | + int LoadSmallObjectModelTexture(); | |
| 105 | + int GetSmallObjectModelTexture(int id, int *model, int *texture); | |
| 106 | + void CleanupSmallObjectModelTexture(); | |
| 107 | + int LoadSmallObjectSound(); | |
| 108 | + int GetSmallObjectSound(int id); | |
| 109 | + int LoadAddSmallObject(char *modelpath, char *texturepath, char *soundpath); | |
| 110 | + | |
| 111 | + int LoadScopeTexture(); | |
| 112 | + int GetScopeTexture(); | |
| 113 | + void CleanupScopeTexture(); | |
| 114 | + int LoadSkyModelTexture(int id); | |
| 115 | + void GetSkyModelTexture(int *model, int *texture); | |
| 116 | + void CleanupSkyModelTexture(); | |
| 117 | + int LoadBulletModelTexture(); | |
| 118 | + void GetBulletModelTexture(int *model, int *texture); | |
| 119 | + void CleanupBulletModelTexture(); | |
| 120 | + int LoadBulletSound(); | |
| 121 | + void GetBulletSound(int *hitsoundA, int *hitsoundB, int *humanhitsound, int *passingsound, int *grenadebang, int *grenadecco); | |
| 122 | + int LoadEffectTexture(); | |
| 123 | + int GetEffectBloodTexture(); | |
| 124 | + int GetEffectMflashTexture(); | |
| 125 | + int GetEffectSmokeTexture(); | |
| 126 | + int GetEffectYakkyouTexture(); | |
| 127 | + void CleanupEffectTexture(); | |
| 128 | +}; | |
| 129 | + | |
| 130 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,584 @@ | ||
| 1 | +//! @file input.cpp | |
| 2 | +//! @brief InputControlクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +//#define INPUT_DIRECTINPUT //!< @brief 入力を取得するインターフェースの選択 @details 定数宣言有効:DirectInput 定数宣言無効(コメント化):WinAPI | |
| 33 | + | |
| 34 | +#include "input.h" | |
| 35 | + | |
| 36 | +//! コンストラクタ | |
| 37 | +InputControl::InputControl() | |
| 38 | +{ | |
| 39 | +#ifdef INPUT_DIRECTINPUT | |
| 40 | + pDI = NULL; | |
| 41 | + pDIDevice = NULL; | |
| 42 | + pMouse = NULL; | |
| 43 | +#endif | |
| 44 | + | |
| 45 | + //キーボード設定値初期化 | |
| 46 | + for(int i=0; i<256; i++){ | |
| 47 | + keys[i] = 0; | |
| 48 | + } | |
| 49 | + memcpy(keys_lt, keys, sizeof(char)*256); | |
| 50 | + | |
| 51 | + //マウスの設定値初期化 | |
| 52 | + mx = 0; | |
| 53 | + my = 0; | |
| 54 | + mbl = false; | |
| 55 | + mbr = false; | |
| 56 | + mbl_lt = mbl; | |
| 57 | + mbr_lt = mbr; | |
| 58 | +} | |
| 59 | + | |
| 60 | +//! ディストラクタ | |
| 61 | +InputControl::~InputControl() | |
| 62 | +{ | |
| 63 | +#ifdef INPUT_DIRECTINPUT | |
| 64 | + //キーボードデバイスを開放 | |
| 65 | + if( pDIDevice != NULL ){ | |
| 66 | + pDIDevice->Unacquire(); | |
| 67 | + pDIDevice->Release(); | |
| 68 | + } | |
| 69 | + | |
| 70 | + //マウスデバイスを開放 | |
| 71 | + if( pMouse != NULL ){ | |
| 72 | + pMouse->Unacquire(); | |
| 73 | + pMouse->Release(); | |
| 74 | + } | |
| 75 | + | |
| 76 | + //DirectInputを開放 | |
| 77 | + if( pDI != NULL) pDI->Release(); | |
| 78 | +#endif | |
| 79 | +} | |
| 80 | + | |
| 81 | +//! 初期化@n | |
| 82 | +//! (DirectInput) | |
| 83 | +//! @param in_hWnd ウィンドウハンドル | |
| 84 | +//! @return 成功:0 失敗:1 | |
| 85 | +int InputControl::InitD3Dinput(HWND in_hWnd) | |
| 86 | +{ | |
| 87 | +#ifdef INPUT_DIRECTINPUT | |
| 88 | + //DirectInput初期化 | |
| 89 | + if( FAILED( DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pDI, NULL) ) ){ | |
| 90 | + return 1; | |
| 91 | + } | |
| 92 | + | |
| 93 | + //キーボード初期化 | |
| 94 | + if( FAILED( pDI->CreateDevice(GUID_SysKeyboard, &pDIDevice, NULL) ) ){ | |
| 95 | + return 1; | |
| 96 | + } | |
| 97 | + pDIDevice->SetDataFormat(&c_dfDIKeyboard); | |
| 98 | + pDIDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY); | |
| 99 | + | |
| 100 | + //マウス初期化 | |
| 101 | + if( FAILED( pDI->CreateDevice(GUID_SysMouse, &pMouse, NULL) ) ){ | |
| 102 | + return 1; | |
| 103 | + } | |
| 104 | + pMouse->SetDataFormat(&c_dfDIMouse2); | |
| 105 | + pMouse->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); | |
| 106 | + pMouse->Acquire(); | |
| 107 | +#endif | |
| 108 | + | |
| 109 | + //カーソルを非表示 | |
| 110 | + ShowCursor(false); | |
| 111 | + | |
| 112 | + //ウインドウハンドルを設定 | |
| 113 | + hWnd = in_hWnd; | |
| 114 | + | |
| 115 | + return 0; | |
| 116 | +} | |
| 117 | + | |
| 118 | +//! 入力デバイスの状態を更新 | |
| 119 | +//! @param mousemode マウスの座標取得 絶対値(座標):false 相対値(移動量):true | |
| 120 | +void InputControl::GetInputState(bool mousemode) | |
| 121 | +{ | |
| 122 | +#ifdef INPUT_DIRECTINPUT | |
| 123 | + //キーボードデバイスが正しく使用できれば | |
| 124 | + if( pDIDevice != NULL ){ | |
| 125 | + HRESULT hr = pDIDevice->Acquire(); | |
| 126 | + if( (hr==DI_OK) || (hr==S_FALSE) ){ | |
| 127 | + //取得直前のキー情報を、前フレーム情報として記録 | |
| 128 | + memcpy(keys_lt, keys, sizeof(char)*256); | |
| 129 | + | |
| 130 | + //現在のキーボード入力を取得 | |
| 131 | + pDIDevice->GetDeviceState(sizeof(keys), &keys); | |
| 132 | + } | |
| 133 | + } | |
| 134 | +#else | |
| 135 | + //取得直前のキー情報を、前フレーム情報として記録 | |
| 136 | + memcpy(keys_lt, keys, sizeof(char)*256); | |
| 137 | + | |
| 138 | + //現在のキーボード入力を取得 | |
| 139 | + GetKeyboardState((PBYTE)&keys); | |
| 140 | +#endif | |
| 141 | + | |
| 142 | + POINT point; | |
| 143 | + | |
| 144 | + //位置をスクリーン座標で取得(WinAPI) | |
| 145 | + GetCursorPos(&point); | |
| 146 | + ScreenToClient(hWnd, &point); | |
| 147 | + | |
| 148 | +#ifdef INPUT_DIRECTINPUT | |
| 149 | + //マウスデバイスが正しく初期化されていれば | |
| 150 | + if( pMouse != NULL ){ | |
| 151 | + //マウス情報を取得(DirectInput) | |
| 152 | + DIMOUSESTATE2 dIMouseState={0}; | |
| 153 | + if( FAILED(pMouse->GetDeviceState( sizeof(DIMOUSESTATE2), &dIMouseState ) ) ){ | |
| 154 | + pMouse->Acquire(); | |
| 155 | + } | |
| 156 | + | |
| 157 | + //マウス座標を出力 | |
| 158 | + if( mousemode == false ){ | |
| 159 | + mx = point.x; | |
| 160 | + my = point.y; | |
| 161 | + } | |
| 162 | + else{ | |
| 163 | + mx = dIMouseState.lX; | |
| 164 | + my = dIMouseState.lY; | |
| 165 | + } | |
| 166 | + | |
| 167 | + //取得直前のボタン情報を、前フレーム情報として記録 | |
| 168 | + mbl_lt = mbl; | |
| 169 | + mbr_lt = mbr; | |
| 170 | + | |
| 171 | + //マウスのボタンを取得 | |
| 172 | + if( dIMouseState.rgbButtons[0]&0x80 ){ mbl = true; } | |
| 173 | + else{ mbl = false; } | |
| 174 | + if( dIMouseState.rgbButtons[1]&0x80 ){ mbr = true; } | |
| 175 | + else{ mbr = false; } | |
| 176 | + } | |
| 177 | +#else | |
| 178 | + //マウス座標を出力 | |
| 179 | + if( mousemode == false ){ | |
| 180 | + mx = point.x; | |
| 181 | + my = point.y; | |
| 182 | + } | |
| 183 | + else{ | |
| 184 | + mx = point.x - point_lt.x; | |
| 185 | + my = point.y - point_lt.y; | |
| 186 | + } | |
| 187 | + | |
| 188 | + //マウス座標を前フレーム情報として記録 | |
| 189 | + point_lt = point; | |
| 190 | + | |
| 191 | + | |
| 192 | + //取得直前のボタン情報を、前フレーム情報として記録 | |
| 193 | + mbl_lt = mbl; | |
| 194 | + mbr_lt = mbr; | |
| 195 | + | |
| 196 | + //マウスのボタンを取得 | |
| 197 | + if( GetKeyState(VK_LBUTTON) < 0 ){ mbl = true; } | |
| 198 | + else{ mbl = false; } | |
| 199 | + if( GetKeyState(VK_RBUTTON) < 0 ){ mbr = true; } | |
| 200 | + else{ mbr = false; } | |
| 201 | +#endif | |
| 202 | +} | |
| 203 | + | |
| 204 | +//! マウスを中心に移動 | |
| 205 | +void InputControl::MoveMouseCenter() | |
| 206 | +{ | |
| 207 | + POINT point; | |
| 208 | + | |
| 209 | + //ウインドウ座標の中央を求める | |
| 210 | + point.x = SCREEN_WIDTH/2; | |
| 211 | + point.y = SCREEN_HEIGTH/2; | |
| 212 | + | |
| 213 | + //前回の座標を書き換え | |
| 214 | + point_lt = point; | |
| 215 | + | |
| 216 | + //スクリーン座標に変換し、座標変更 | |
| 217 | + ClientToScreen(hWnd, &point); | |
| 218 | + SetCursorPos(point.x, point.y); | |
| 219 | +} | |
| 220 | + | |
| 221 | +//! キーボードの入力をチェック(リアルタイム) | |
| 222 | +//! @return 押されてない:false 押されている:true | |
| 223 | +bool InputControl::CheckKeyNow(int id) | |
| 224 | +{ | |
| 225 | + //現在押されていれば | |
| 226 | + if( keys[id]&0x80 ){ return true; } | |
| 227 | + return false; | |
| 228 | +} | |
| 229 | + | |
| 230 | +//! キーボードの入力をチェック(押された瞬間) | |
| 231 | +//! @return 押された瞬間でない:false 押された瞬間である:true | |
| 232 | +bool InputControl::CheckKeyDown(int id) | |
| 233 | +{ | |
| 234 | + //前回は押されておらず、現在押されていれば | |
| 235 | + if( ((keys_lt[id]&0x80) == 0)&&(keys[id]&0x80) ){ return true; } | |
| 236 | + return false; | |
| 237 | +} | |
| 238 | + | |
| 239 | +//! キーボードの入力をチェック(離された瞬間) | |
| 240 | +//! @return 離された瞬間でない:false 離された瞬間である:true | |
| 241 | +bool InputControl::CheckKeyUp(int id) | |
| 242 | +{ | |
| 243 | + //前回を押されており、現在押されていなければ | |
| 244 | + if( (keys_lt[id]&0x80)&&((keys[id]&0x80) == 0) ){ return true; } | |
| 245 | + return false; | |
| 246 | +} | |
| 247 | + | |
| 248 | +//! マウスの入力をチェック | |
| 249 | +//! @param x x軸を受け取る整数値型ポインタ | |
| 250 | +//! @param y y軸を受け取る整数値型ポインタ | |
| 251 | +//! @attention 値は直前に実行した GetInputState() への引数に影響される。 | |
| 252 | +void InputControl::GetMouseMovement(int *x, int *y) | |
| 253 | +{ | |
| 254 | + //マウス座標を代入 | |
| 255 | + *x = mx; | |
| 256 | + *y = my; | |
| 257 | +} | |
| 258 | + | |
| 259 | +//! マウス・左ボタンの入力をチェック(リアルタイム) | |
| 260 | +//! @return 押されてない:false 押されている:true | |
| 261 | +bool InputControl::CheckMouseButtonNowL() | |
| 262 | +{ | |
| 263 | + //現在の情報を返す | |
| 264 | + return mbl; | |
| 265 | +} | |
| 266 | + | |
| 267 | +//! マウス・左ボタンの入力をチェック(押された瞬間) | |
| 268 | +//! @return 押された瞬間でない:false 押された瞬間である:true | |
| 269 | +bool InputControl::CheckMouseButtonDownL() | |
| 270 | +{ | |
| 271 | + //前回は押されておらず、現在押されていれば | |
| 272 | + if( (mbl_lt == false)&&(mbl == true) ){ return true; } | |
| 273 | + return false; | |
| 274 | +} | |
| 275 | + | |
| 276 | +//! マウス・左ボタンの入力をチェック(離された瞬間) | |
| 277 | +//! @return 離された瞬間でない:false 離された瞬間である:true | |
| 278 | +bool InputControl::CheckMouseButtonUpL() | |
| 279 | +{ | |
| 280 | + //前回を押されており、現在押されていなければ | |
| 281 | + if( (mbl_lt == true)&&(mbl == false) ){ return true; } | |
| 282 | + return false; | |
| 283 | +} | |
| 284 | + | |
| 285 | +//! マウス・右ボタンの入力をチェック(リアルタイム) | |
| 286 | +//! @return 押されてない:false 押されている:true | |
| 287 | +bool InputControl::CheckMouseButtonNowR() | |
| 288 | +{ | |
| 289 | + //現在の情報を返す | |
| 290 | + return mbr; | |
| 291 | +} | |
| 292 | + | |
| 293 | +//! マウス・右ボタンの入力をチェック(押された瞬間) | |
| 294 | +//! @return 押された瞬間でない:false 押された瞬間である:true | |
| 295 | +bool InputControl::CheckMouseButtonDownR() | |
| 296 | +{ | |
| 297 | + //前回は押されておらず、現在押されていれば | |
| 298 | + if( (mbr_lt == false)&&(mbr == true) ){ return true; } | |
| 299 | + return false; | |
| 300 | +} | |
| 301 | + | |
| 302 | +//! マウス・右ボタンの入力をチェック(離された瞬間) | |
| 303 | +//! @return 離された瞬間でない:false 離された瞬間である:true | |
| 304 | +bool InputControl::CheckMouseButtonUpR() | |
| 305 | +{ | |
| 306 | + //前回を押されており、現在押されていなければ | |
| 307 | + if( (mbr_lt == true)&&(mbr == false) ){ return true; } | |
| 308 | + return false; | |
| 309 | +} | |
| 310 | + | |
| 311 | +//! オリジナルキーコードをDirectInputキーコードへ変換 | |
| 312 | +//! @param code オリジナルキーコード | |
| 313 | +//! @return 1以上:DirectInputキーコード -1以下:特殊 0:失敗 | |
| 314 | +//! @attention 以下、特殊な戻り値の場合―<br>-1:MOUSE L -2:MOUSE R -3:DIK_LSHIFT / DIK_RSHIFT -4:DIK_LCONTROL / DIK_RCONTROL | |
| 315 | +int OriginalkeycodeToDinputdef(int code) | |
| 316 | +{ | |
| 317 | + int out = 0; | |
| 318 | + | |
| 319 | +#ifdef INPUT_DIRECTINPUT | |
| 320 | + switch(code){ | |
| 321 | + case 0x00: out = DIK_UP; break; | |
| 322 | + case 0x01: out = DIK_DOWN; break; | |
| 323 | + case 0x02: out = DIK_LEFT; break; | |
| 324 | + case 0x03: out = DIK_RIGHT; break; | |
| 325 | + case 0x04: out = DIK_NUMPAD0; break; | |
| 326 | + case 0x05: out = DIK_NUMPAD1; break; | |
| 327 | + case 0x06: out = DIK_NUMPAD2; break; | |
| 328 | + case 0x07: out = DIK_NUMPAD3; break; | |
| 329 | + case 0x08: out = DIK_NUMPAD4; break; | |
| 330 | + case 0x09: out = DIK_NUMPAD5; break; | |
| 331 | + case 0x0A: out = DIK_NUMPAD6; break; | |
| 332 | + case 0x0B: out = DIK_NUMPAD7; break; | |
| 333 | + case 0x0C: out = DIK_NUMPAD8; break; | |
| 334 | + case 0x0D: out = DIK_NUMPAD9; break; | |
| 335 | + case 0x0E: out = DIK_BACK; break; | |
| 336 | + case 0x0F: out = DIK_RETURN; break; | |
| 337 | + | |
| 338 | + case 0x10: out = DIK_TAB; break; | |
| 339 | + case 0x11: out = DIK_SPACE; break; | |
| 340 | + case 0x12: out = -1; break; //MOUSE L | |
| 341 | + case 0x13: out = -2; break; //MOUSE R | |
| 342 | + case 0x14: out = -3; break; //DIK_LSHIFT / DIK_RSHIFT | |
| 343 | + case 0x15: out = -4; break; //DIK_LCONTROL / DIK_RCONTROL | |
| 344 | + case 0x16: out = DIK_0; break; | |
| 345 | + case 0x17: out = DIK_1; break; | |
| 346 | + case 0x18: out = DIK_2; break; | |
| 347 | + case 0x19: out = DIK_3; break; | |
| 348 | + case 0x1A: out = DIK_4; break; | |
| 349 | + case 0x1B: out = DIK_5; break; | |
| 350 | + case 0x1C: out = DIK_6; break; | |
| 351 | + case 0x1D: out = DIK_7; break; | |
| 352 | + case 0x1E: out = DIK_8; break; | |
| 353 | + case 0x1F: out = DIK_9; break; | |
| 354 | + | |
| 355 | + case 0x20: out = DIK_A; break; | |
| 356 | + case 0x21: out = DIK_B; break; | |
| 357 | + case 0x22: out = DIK_C; break; | |
| 358 | + case 0x23: out = DIK_D; break; | |
| 359 | + case 0x24: out = DIK_E; break; | |
| 360 | + case 0x25: out = DIK_F; break; | |
| 361 | + case 0x26: out = DIK_G; break; | |
| 362 | + case 0x27: out = DIK_H; break; | |
| 363 | + case 0x28: out = DIK_I; break; | |
| 364 | + case 0x29: out = DIK_J; break; | |
| 365 | + case 0x2A: out = DIK_K; break; | |
| 366 | + case 0x2B: out = DIK_L; break; | |
| 367 | + case 0x2C: out = DIK_M; break; | |
| 368 | + case 0x2D: out = DIK_N; break; | |
| 369 | + case 0x2E: out = DIK_O; break; | |
| 370 | + case 0x2F: out = DIK_P; break; | |
| 371 | + | |
| 372 | + case 0x30: out = DIK_Q; break; | |
| 373 | + case 0x31: out = DIK_R; break; | |
| 374 | + case 0x32: out = DIK_S; break; | |
| 375 | + case 0x33: out = DIK_T; break; | |
| 376 | + case 0x34: out = DIK_U; break; | |
| 377 | + case 0x35: out = DIK_V; break; | |
| 378 | + case 0x36: out = DIK_W; break; | |
| 379 | + case 0x37: out = DIK_X; break; | |
| 380 | + case 0x38: out = DIK_Y; break; | |
| 381 | + case 0x39: out = DIK_Z; break; | |
| 382 | + case 0x3A: out = DIK_SLASH; break; | |
| 383 | + case 0x3B: out = DIK_COLON; break; | |
| 384 | + case 0x3C: out = DIK_SEMICOLON; break; | |
| 385 | + case 0x3D: out = DIK_MINUS; break; | |
| 386 | + case 0x3E: out = DIK_AT; break; | |
| 387 | + case 0x3F: out = DIK_LBRACKET; break; | |
| 388 | + | |
| 389 | + case 0x40: out = DIK_RBRACKET; break; | |
| 390 | + case 0x41: out = DIK_BACKSLASH; break; | |
| 391 | + case 0x42: out = DIK_YEN; break; | |
| 392 | + case 0x43: out = DIK_COMMA; break; | |
| 393 | + case 0x44: out = DIK_PERIOD; break; | |
| 394 | + case 0x45: out = DIK_EQUALS; break; | |
| 395 | + case 0x46: out = DIK_NUMPADSTAR; break; | |
| 396 | + case 0x47: out = DIK_NUMPADSLASH; break; | |
| 397 | + case 0x48: out = DIK_NUMPADPLUS; break; | |
| 398 | + case 0x49: out = DIK_NUMPADMINUS; break; | |
| 399 | + case 0x4A: out = DIK_NUMPADPERIOD; break; | |
| 400 | + | |
| 401 | + default : out = 0; | |
| 402 | + } | |
| 403 | +#else | |
| 404 | + switch(code){ | |
| 405 | + case 0x00: out = VK_UP; break; | |
| 406 | + case 0x01: out = VK_DOWN; break; | |
| 407 | + case 0x02: out = VK_LEFT; break; | |
| 408 | + case 0x03: out = VK_RIGHT; break; | |
| 409 | + case 0x04: out = VK_NUMPAD0; break; | |
| 410 | + case 0x05: out = VK_NUMPAD1; break; | |
| 411 | + case 0x06: out = VK_NUMPAD2; break; | |
| 412 | + case 0x07: out = VK_NUMPAD3; break; | |
| 413 | + case 0x08: out = VK_NUMPAD4; break; | |
| 414 | + case 0x09: out = VK_NUMPAD5; break; | |
| 415 | + case 0x0A: out = VK_NUMPAD6; break; | |
| 416 | + case 0x0B: out = VK_NUMPAD7; break; | |
| 417 | + case 0x0C: out = VK_NUMPAD8; break; | |
| 418 | + case 0x0D: out = VK_NUMPAD9; break; | |
| 419 | + case 0x0E: out = VK_BACK; break; | |
| 420 | + case 0x0F: out = VK_RETURN; break; | |
| 421 | + | |
| 422 | + case 0x10: out = VK_TAB; break; | |
| 423 | + case 0x11: out = VK_SPACE; break; | |
| 424 | + case 0x12: out = -1; break; //MOUSE L | |
| 425 | + case 0x13: out = -2; break; //MOUSE R | |
| 426 | + case 0x14: out = VK_SHIFT; break; | |
| 427 | + case 0x15: out = VK_CONTROL; break; | |
| 428 | + case 0x16: out = '0'; break; | |
| 429 | + case 0x17: out = '1'; break; | |
| 430 | + case 0x18: out = '2'; break; | |
| 431 | + case 0x19: out = '3'; break; | |
| 432 | + case 0x1A: out = '4'; break; | |
| 433 | + case 0x1B: out = '5'; break; | |
| 434 | + case 0x1C: out = '6'; break; | |
| 435 | + case 0x1D: out = '7'; break; | |
| 436 | + case 0x1E: out = '8'; break; | |
| 437 | + case 0x1F: out = '9'; break; | |
| 438 | + | |
| 439 | + case 0x20: out = 'A'; break; | |
| 440 | + case 0x21: out = 'B'; break; | |
| 441 | + case 0x22: out = 'C'; break; | |
| 442 | + case 0x23: out = 'D'; break; | |
| 443 | + case 0x24: out = 'E'; break; | |
| 444 | + case 0x25: out = 'F'; break; | |
| 445 | + case 0x26: out = 'G'; break; | |
| 446 | + case 0x27: out = 'H'; break; | |
| 447 | + case 0x28: out = 'I'; break; | |
| 448 | + case 0x29: out = 'J'; break; | |
| 449 | + case 0x2A: out = 'K'; break; | |
| 450 | + case 0x2B: out = 'L'; break; | |
| 451 | + case 0x2C: out = 'M'; break; | |
| 452 | + case 0x2D: out = 'N'; break; | |
| 453 | + case 0x2E: out = 'O'; break; | |
| 454 | + case 0x2F: out = 'P'; break; | |
| 455 | + | |
| 456 | + case 0x30: out = 'Q'; break; | |
| 457 | + case 0x31: out = 'R'; break; | |
| 458 | + case 0x32: out = 'S'; break; | |
| 459 | + case 0x33: out = 'T'; break; | |
| 460 | + case 0x34: out = 'U'; break; | |
| 461 | + case 0x35: out = 'V'; break; | |
| 462 | + case 0x36: out = 'W'; break; | |
| 463 | + case 0x37: out = 'X'; break; | |
| 464 | + case 0x38: out = 'Y'; break; | |
| 465 | + case 0x39: out = 'Z'; break; | |
| 466 | + case 0x3A: out = VK_DIVIDE; break; | |
| 467 | + case 0x3B: out = VK_OEM_1; break; | |
| 468 | + case 0x3C: out = VK_OEM_PLUS; break; | |
| 469 | + case 0x3D: out = VK_OEM_MINUS; break; | |
| 470 | + case 0x3E: out = VK_OEM_3; break; | |
| 471 | + case 0x3F: out = VK_OEM_4; break; | |
| 472 | + | |
| 473 | + case 0x40: out = VK_OEM_6; break; | |
| 474 | + case 0x41: out = VK_OEM_102; break; | |
| 475 | + case 0x42: out = VK_OEM_5; break; | |
| 476 | + case 0x43: out = VK_OEM_COMMA; break; | |
| 477 | + case 0x44: out = VK_OEM_PERIOD; break; | |
| 478 | + case 0x45: out = VK_OEM_7; break; | |
| 479 | + case 0x46: out = VK_MULTIPLY ; break; | |
| 480 | + case 0x47: out = VK_DIVIDE; break; | |
| 481 | + case 0x48: out = VK_ADD; break; | |
| 482 | + case 0x49: out = VK_SUBTRACT; break; | |
| 483 | + case 0x4A: out = VK_DECIMAL; break; | |
| 484 | + | |
| 485 | + default : out = 0; | |
| 486 | + } | |
| 487 | +#endif | |
| 488 | + | |
| 489 | + return out; | |
| 490 | +} | |
| 491 | + | |
| 492 | +//! 左右キーのキーコード取得 | |
| 493 | +//! @param id Shiftキー:0 Ctrlキー:1 | |
| 494 | +//! @param *CodeL 左側キーのキーコードを受け取るポインタ | |
| 495 | +//! @param *CodeR 右側キーのキーコードを受け取るポインタ | |
| 496 | +//! @return 成功:ture 失敗:false | |
| 497 | +bool GetDoubleKeyCode(int id, int *CodeL, int *CodeR) | |
| 498 | +{ | |
| 499 | +#ifdef INPUT_DIRECTINPUT | |
| 500 | + if( id == 0 ){ | |
| 501 | + *CodeL = DIK_LSHIFT; | |
| 502 | + *CodeR = DIK_RSHIFT; | |
| 503 | + return true; | |
| 504 | + } | |
| 505 | + if( id == 1 ){ | |
| 506 | + *CodeL = DIK_LCONTROL; | |
| 507 | + *CodeR = DIK_RCONTROL; | |
| 508 | + return true; | |
| 509 | + } | |
| 510 | +#endif | |
| 511 | + | |
| 512 | + //エラー | |
| 513 | + *CodeL = 0x00; | |
| 514 | + *CodeR = 0x00; | |
| 515 | + return false; | |
| 516 | +} | |
| 517 | + | |
| 518 | +//! Escキーのキーコード取得 | |
| 519 | +//! @return キーコード | |
| 520 | +int GetEscKeycode() | |
| 521 | +{ | |
| 522 | +#ifdef INPUT_DIRECTINPUT | |
| 523 | + return DIK_ESCAPE; | |
| 524 | +#else | |
| 525 | + return VK_ESCAPE; | |
| 526 | +#endif | |
| 527 | +} | |
| 528 | + | |
| 529 | +//! Homeキーのキーコード取得 | |
| 530 | +//! @return キーコード | |
| 531 | +int GetHomeKeycode() | |
| 532 | +{ | |
| 533 | +#ifdef INPUT_DIRECTINPUT | |
| 534 | + return DIK_HOME; | |
| 535 | +#else | |
| 536 | + return VK_HOME; | |
| 537 | +#endif | |
| 538 | +} | |
| 539 | + | |
| 540 | +//! ファンクションキー(F1〜F12)のキーコードを取得 | |
| 541 | +//! @param key 番号(1〜12) | |
| 542 | +//! @return キーコード | |
| 543 | +int GetFunctionKeycode(int key) | |
| 544 | +{ | |
| 545 | + int out = 0; | |
| 546 | + | |
| 547 | +#ifdef INPUT_DIRECTINPUT | |
| 548 | + switch(key){ | |
| 549 | + case 1: out = DIK_F1; break; | |
| 550 | + case 2: out = DIK_F2; break; | |
| 551 | + case 3: out = DIK_F3; break; | |
| 552 | + case 4: out = DIK_F4; break; | |
| 553 | + case 5: out = DIK_F5; break; | |
| 554 | + case 6: out = DIK_F6; break; | |
| 555 | + case 7: out = DIK_F7; break; | |
| 556 | + case 8: out = DIK_F8; break; | |
| 557 | + case 9: out = DIK_F9; break; | |
| 558 | + case 10: out = DIK_F10; break; | |
| 559 | + case 11: out = DIK_F11; break; | |
| 560 | + case 12: out = DIK_F12; break; | |
| 561 | + | |
| 562 | + default : out = 0; | |
| 563 | + } | |
| 564 | +#else | |
| 565 | + switch(key){ | |
| 566 | + case 1: out = VK_F1; break; | |
| 567 | + case 2: out = VK_F2; break; | |
| 568 | + case 3: out = VK_F3; break; | |
| 569 | + case 4: out = VK_F4; break; | |
| 570 | + case 5: out = VK_F5; break; | |
| 571 | + case 6: out = VK_F6; break; | |
| 572 | + case 7: out = VK_F7; break; | |
| 573 | + case 8: out = VK_F8; break; | |
| 574 | + case 9: out = VK_F9; break; | |
| 575 | + case 10: out = VK_F10; break; | |
| 576 | + case 11: out = VK_F11; break; | |
| 577 | + case 12: out = VK_F12; break; | |
| 578 | + | |
| 579 | + default : out = 0; | |
| 580 | + } | |
| 581 | +#endif | |
| 582 | + | |
| 583 | + return out; | |
| 584 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,83 @@ | ||
| 1 | +//! @file collision.h | |
| 2 | +//! @brief Collisionクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef COLLISION_H | |
| 33 | +#define COLLISION_H | |
| 34 | + | |
| 35 | +#ifndef H_LAYERLEVEL | |
| 36 | + #define H_LAYERLEVEL 2 //!< Select include file. | |
| 37 | +#endif | |
| 38 | +#include "main.h" | |
| 39 | + | |
| 40 | +#pragma warning(disable:4819) //VC++警告防止 | |
| 41 | +#include <d3dx9math.h> | |
| 42 | +#pragma warning(default:4819) | |
| 43 | + | |
| 44 | +#pragma comment(lib, "d3dx9.lib") | |
| 45 | + | |
| 46 | +//! @brief 当たり判定を行うクラス | |
| 47 | +//! @details マップとして使用されるブロックデータへの当たり判定(追突検出)を行います。 | |
| 48 | +//! @details 内部ではDirectX 9を使用しています。 | |
| 49 | +class Collision | |
| 50 | +{ | |
| 51 | + class BlockDataInterface* blockdata; //!< 読み込んだブロックデータが格納されたクラスへのポインタ | |
| 52 | + D3DXPLANE bdata_plane[MAX_BLOCKS][6][2]; //!< 各ブロックの面情報 | |
| 53 | + float *bmin_x; //!< 各ブロック X座標の最大値 | |
| 54 | + float *bmin_y; //!< 各ブロック Y座標の最大値 | |
| 55 | + float *bmin_z; //!< 各ブロック Z座標の最大値 | |
| 56 | + float *bmax_x; //!< 各ブロック X座標の最小値 | |
| 57 | + float *bmax_y; //!< 各ブロック Y座標の最小値 | |
| 58 | + float *bmax_z; //!< 各ブロック Z座標の最小値 | |
| 59 | + bool *BoardBlock; //!< 各ブロック が厚さ0で板状になっているか | |
| 60 | + int *bdata_worldgroup; //!< 空間分割のグループ | |
| 61 | + | |
| 62 | +public: | |
| 63 | + Collision(); | |
| 64 | + ~Collision(); | |
| 65 | + int InitCollision(BlockDataInterface* in_blockdata); | |
| 66 | + void GetBlockPosMINMAX(struct blockdata data, float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z); | |
| 67 | + int GetWorldGroup(float x, float z); | |
| 68 | + bool CheckBlockInside(int blockid, float x, float y, float z, bool worldgroup, int *planeid); | |
| 69 | + bool CheckALLBlockInside(float x, float y, float z); | |
| 70 | + bool CheckBlockIntersectRay(int blockid, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, int *face, float *Dist, float maxDist); | |
| 71 | + bool CheckALLBlockIntersectRay(float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, int *id, int *face, float *Dist, float maxDist); | |
| 72 | + bool CheckALLBlockIntersectDummyRay(float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, int *id, int *face, float *Dist, float maxDist); | |
| 73 | + void ScratchVector(BlockDataInterface* in_blockdata, int id, int face, float in_vx, float in_vy, float in_vz, float *out_vx, float *out_vy, float *out_vz); | |
| 74 | + void ReflectVector(BlockDataInterface* in_blockdata, int id, int face, float in_vx, float in_vy, float in_vz, float *out_vx, float *out_vy, float *out_vz); | |
| 75 | +}; | |
| 76 | + | |
| 77 | +bool CollideBoxAABB(float box1_min_x, float box1_min_y, float box1_min_z, float box1_max_x, float box1_max_y, float box1_max_z, float box2_min_x, float box2_min_y, float box2_min_z, float box2_max_x, float box2_max_y, float box2_max_z); | |
| 78 | +bool CollideCylinder(float c1_x, float c1_y, float c1_z, float c1_r, float c1_h, float c2_x, float c2_y, float c2_z, float c2_r, float c2_h, float *angle, float *length); | |
| 79 | +bool CollideSphereRay(float s_x, float s_y, float s_z, float s_r, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float *Dist, float maxDist); | |
| 80 | +bool CollideAABBRay(float box_min_x, float box_min_y, float box_min_z, float box_max_x, float box_max_y, float box_max_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float *Dist, float maxDist); | |
| 81 | +float DistancePosRay(float Pos_x, float Pos_y, float Pos_z, float RayPos_x, float RayPos_y, float RayPos_z, float RayDir_x, float RayDir_y, float RayDir_z, float maxDist); | |
| 82 | + | |
| 83 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,1756 @@ | ||
| 1 | +//! @file objectmanager.cpp | |
| 2 | +//! @brief ObjectManagerクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "objectmanager.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +ObjectManager::ObjectManager() | |
| 36 | +{ | |
| 37 | + HumanIndex = new human[MAX_HUMAN]; | |
| 38 | + WeaponIndex = new weapon[MAX_WEAPON]; | |
| 39 | + SmallObjectIndex = new smallobject[MAX_SMALLOBJECT]; | |
| 40 | + BulletIndex = new bullet[MAX_BULLET]; | |
| 41 | + GrenadeIndex = new grenade[MAX_GRENADE]; | |
| 42 | + EffectIndex = new effect[MAX_EFFECT]; | |
| 43 | + | |
| 44 | + framecnt = 0; | |
| 45 | + Human_ontarget = new int[MAX_HUMAN]; | |
| 46 | + Human_kill = new int[MAX_HUMAN]; | |
| 47 | + Human_headshot = new int[MAX_HUMAN]; | |
| 48 | + Player_HumanID = 0; | |
| 49 | + AddHumanIndex_TextureID = -1; | |
| 50 | + | |
| 51 | + GameParamInfo = NULL; | |
| 52 | + d3dg = NULL; | |
| 53 | + Resource = NULL; | |
| 54 | + BlockData = NULL; | |
| 55 | + PointData = NULL; | |
| 56 | + CollD = NULL; | |
| 57 | +} | |
| 58 | + | |
| 59 | +//! ディストラクタ | |
| 60 | +ObjectManager::~ObjectManager() | |
| 61 | +{ | |
| 62 | + Cleanup(); | |
| 63 | + | |
| 64 | + if( HumanIndex != NULL ){ delete [] HumanIndex; } | |
| 65 | + if( WeaponIndex != NULL ){ delete [] WeaponIndex; } | |
| 66 | + if( SmallObjectIndex != NULL ){ delete [] SmallObjectIndex; } | |
| 67 | + if( BulletIndex != NULL ){ delete [] BulletIndex; } | |
| 68 | + if( GrenadeIndex != NULL ){ delete [] GrenadeIndex; } | |
| 69 | + if( EffectIndex != NULL ){ delete [] EffectIndex; } | |
| 70 | + | |
| 71 | + if( Human_ontarget != NULL ){ delete [] Human_ontarget; } | |
| 72 | + if( Human_kill != NULL ){ delete [] Human_kill; } | |
| 73 | + if( Human_headshot != NULL ){ delete [] Human_headshot; } | |
| 74 | +} | |
| 75 | + | |
| 76 | +//! 参照するクラスを設定 | |
| 77 | +//! @param in_GameParamInfo ゲーム設定データ管理クラス | |
| 78 | +//! @param in_d3dg 描画処理クラス | |
| 79 | +//! @param in_Resource リソース管理クラス | |
| 80 | +//! @param in_BlockData ブロックデータ管理クラス | |
| 81 | +//! @param in_PointData ポイントデータ管理クラス | |
| 82 | +//! @param in_CollD 当たり判定処理クラス | |
| 83 | +//! @param in_GameSound 効果音再生クラス | |
| 84 | +//! @param in_MIFdata MIFコントロールクラス | |
| 85 | +//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。 | |
| 86 | +void ObjectManager::SetClass(ParameterInfo *in_GameParamInfo, D3DGraphics *in_d3dg, ResourceManager *in_Resource, BlockDataInterface *in_BlockData, PointDataInterface *in_PointData, Collision *in_CollD, SoundManager *in_GameSound, MIFInterface *in_MIFdata) | |
| 87 | +{ | |
| 88 | + GameParamInfo = in_GameParamInfo; | |
| 89 | + d3dg = in_d3dg; | |
| 90 | + Resource = in_Resource; | |
| 91 | + BlockData = in_BlockData; | |
| 92 | + PointData = in_PointData; | |
| 93 | + CollD = in_CollD; | |
| 94 | + GameSound = in_GameSound; | |
| 95 | + MIFdata = in_MIFdata; | |
| 96 | + | |
| 97 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 98 | + HumanIndex[i].SetParameterInfoClass(GameParamInfo); | |
| 99 | + } | |
| 100 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 101 | + WeaponIndex[i].SetParameterInfoClass(GameParamInfo); | |
| 102 | + } | |
| 103 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 104 | + SmallObjectIndex[i].SetParameterInfoClass(GameParamInfo); | |
| 105 | + SmallObjectIndex[i].SetMIFInterfaceClass(MIFdata); | |
| 106 | + } | |
| 107 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 108 | + GrenadeIndex[i].SetParameterInfoClass(GameParamInfo); | |
| 109 | + } | |
| 110 | + | |
| 111 | + int bulletmodel, bullettexture; | |
| 112 | + Resource->GetBulletModelTexture(&bulletmodel, &bullettexture); | |
| 113 | + for(int i=0; i<MAX_BULLET; i++){ | |
| 114 | + BulletIndex[i].SetModel(bulletmodel, 1.0f); | |
| 115 | + BulletIndex[i].SetTexture(bullettexture); | |
| 116 | + } | |
| 117 | + | |
| 118 | + int grenademodel, grenadetexture; | |
| 119 | + float model_size = 1.0f; | |
| 120 | + WeaponParameter ParamData; | |
| 121 | + | |
| 122 | + //リソースとモデルサイズを取得 | |
| 123 | + Resource->GetWeaponModelTexture(ID_WEAPON_GRENADE, &grenademodel, &grenadetexture); | |
| 124 | + if( GameParamInfo->GetWeapon(ID_WEAPON_GRENADE, &ParamData) == 0 ){ | |
| 125 | + model_size = ParamData.size; | |
| 126 | + } | |
| 127 | + | |
| 128 | + //適用 | |
| 129 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 130 | + GrenadeIndex[i].SetModel(grenademodel, model_size); | |
| 131 | + GrenadeIndex[i].SetTexture(grenadetexture); | |
| 132 | + } | |
| 133 | +} | |
| 134 | + | |
| 135 | +//! 人追加 | |
| 136 | +//! @param data 人のポイントデータ (pointdata構造体) | |
| 137 | +//! @param infodata 参照する人情報のポイントデータ (〃) | |
| 138 | +//! @return 成功:データ番号(0以上) 失敗:-1 | |
| 139 | +//! @attention 無効な人の種類番号が指定された場合は 通称:謎人間 が登場します。テクスチャはマップテクスチャ0番が使用され、HPは 0 が指定(=即死)されます。 | |
| 140 | +int ObjectManager::AddHumanIndex(pointdata data, pointdata infodata) | |
| 141 | +{ | |
| 142 | + int GetHumanFlag; | |
| 143 | + HumanParameter HumanParam; | |
| 144 | + GetHumanFlag = GameParamInfo->GetHuman(infodata.p2, &HumanParam); | |
| 145 | + int Humanindexid = -1; | |
| 146 | + int Weaponindexid = -1; | |
| 147 | + class weapon *Weapon[TOTAL_HAVEWEAPON]; | |
| 148 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 149 | + Weapon[i] = NULL; | |
| 150 | + } | |
| 151 | + | |
| 152 | + //人のモデル番号を取得 | |
| 153 | + int upmodel[TOTAL_UPMODE]; | |
| 154 | + int armmodel[TOTAL_ARMMODE]; | |
| 155 | + int legmodel; | |
| 156 | + int walkmodel[TOTAL_WALKMODE]; | |
| 157 | + int runmodel[TOTAL_RUNMODE]; | |
| 158 | + Resource->GetHumanModel(upmodel, armmodel, &legmodel, walkmodel, runmodel); | |
| 159 | + | |
| 160 | + for(int j=0; j<MAX_HUMAN; j++){ | |
| 161 | + if( HumanIndex[j].GetDrawFlag() == false ){ | |
| 162 | + //初期化する | |
| 163 | + HumanIndex[j].SetPosData(data.x, data.y, data.z, data.r); | |
| 164 | + HumanIndex[j].SetParamData(infodata.p2, data.id, data.p4, infodata.p3, true); | |
| 165 | + if( GetHumanFlag == 0 ){ | |
| 166 | + int id = Resource->GetHumanTexture(infodata.p2); | |
| 167 | + if( id == -1 ){ | |
| 168 | + id = AddHumanIndex_TextureID; | |
| 169 | + } | |
| 170 | + else{ | |
| 171 | + AddHumanIndex_TextureID = id; | |
| 172 | + } | |
| 173 | + | |
| 174 | + HumanIndex[j].SetTexture(id); | |
| 175 | + HumanIndex[j].SetModel(upmodel[ HumanParam.model ], armmodel, legmodel, walkmodel, runmodel); | |
| 176 | + } | |
| 177 | + else{ | |
| 178 | + AddHumanIndex_TextureID = d3dg->GetMapTextureID(0); | |
| 179 | + | |
| 180 | + HumanIndex[j].SetTexture(AddHumanIndex_TextureID); | |
| 181 | + HumanIndex[j].SetModel(upmodel[0], armmodel, legmodel, walkmodel, runmodel); | |
| 182 | + } | |
| 183 | + HumanIndex[j].SetDrawFlag(true); | |
| 184 | + Humanindexid = j; | |
| 185 | + break; | |
| 186 | + } | |
| 187 | + } | |
| 188 | + | |
| 189 | + //初期化できなかったらエラーとして返す | |
| 190 | + if( Humanindexid == -1 ){ | |
| 191 | + return -1; | |
| 192 | + } | |
| 193 | + | |
| 194 | + //人の設定データが正しく読めていれば〜 | |
| 195 | + if( GetHumanFlag == 0 ){ | |
| 196 | + //武器Bを仮想武器として追加 | |
| 197 | + Weaponindexid = AddVisualWeaponIndex(HumanParam.Weapon[0], true); | |
| 198 | + if( Weaponindexid != -1 ){ | |
| 199 | + //成功すれば配列に記録 | |
| 200 | + Weapon[0] = &WeaponIndex[Weaponindexid]; | |
| 201 | + } | |
| 202 | + if( data.p1 == 1 ){ | |
| 203 | + //武器Aの仮想武器として追加 | |
| 204 | + Weaponindexid = AddVisualWeaponIndex(HumanParam.Weapon[1], true); | |
| 205 | + if( Weaponindexid != -1 ){ | |
| 206 | + //成功すれば配列に記録 | |
| 207 | + Weapon[1] = &WeaponIndex[Weaponindexid]; | |
| 208 | + } | |
| 209 | + } | |
| 210 | + | |
| 211 | + //人に持たせる | |
| 212 | + HumanIndex[Humanindexid].SetWeapon(Weapon); | |
| 213 | + } | |
| 214 | + | |
| 215 | + //プレイヤーならば、番号を記録 | |
| 216 | + if( ( (data.p1 == 1)||(data.p1 == 6) )&&(data.p4 == 0) ){ | |
| 217 | + Player_HumanID = Humanindexid; | |
| 218 | + } | |
| 219 | + | |
| 220 | + return Humanindexid; | |
| 221 | +} | |
| 222 | + | |
| 223 | +//! 人追加(ゲーム中用) | |
| 224 | +//! @param px X座標 | |
| 225 | +//! @param py Y座標 | |
| 226 | +//! @param pz Z座標 | |
| 227 | +//! @param rx X軸向き | |
| 228 | +//! @param paramID 種類番号 | |
| 229 | +//! @param TeamID チーム番号 | |
| 230 | +//! @param WeaponID 武器種類番号の配列(要素数:TOTAL_HAVEWEAPON) | |
| 231 | +//! @return 成功:データ番号(0以上) 失敗:-1 | |
| 232 | +//! @attention 無効な人の種類番号が指定された場合は 通称:謎人間 が登場します。テクスチャはマップテクスチャ0番が使用され、HPは 0 が指定(=即死)されます。 | |
| 233 | +int ObjectManager::AddHumanIndex(float px, float py, float pz, float rx, int paramID, int TeamID, int WeaponID[]) | |
| 234 | +{ | |
| 235 | + int GetHumanFlag; | |
| 236 | + HumanParameter HumanParam; | |
| 237 | + GetHumanFlag = GameParamInfo->GetHuman(paramID, &HumanParam); | |
| 238 | + int Humanindexid = -1; | |
| 239 | + int Weaponindexid = -1; | |
| 240 | + class weapon *Weapon[TOTAL_HAVEWEAPON]; | |
| 241 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 242 | + Weapon[i] = NULL; | |
| 243 | + } | |
| 244 | + | |
| 245 | + //人のモデル番号を取得 | |
| 246 | + int upmodel[TOTAL_UPMODE]; | |
| 247 | + int armmodel[TOTAL_ARMMODE]; | |
| 248 | + int legmodel; | |
| 249 | + int walkmodel[TOTAL_WALKMODE]; | |
| 250 | + int runmodel[TOTAL_RUNMODE]; | |
| 251 | + Resource->GetHumanModel(upmodel, armmodel, &legmodel, walkmodel, runmodel); | |
| 252 | + | |
| 253 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 254 | + if( HumanIndex[i].GetDrawFlag() == false ){ | |
| 255 | + //初期化する | |
| 256 | + HumanIndex[i].SetPosData(px, py, pz, rx); | |
| 257 | + HumanIndex[i].SetParamData(paramID, -1, 0, TeamID, true); | |
| 258 | + if( GetHumanFlag == 0 ){ | |
| 259 | + //読み込めなければ、前回読み込んだテクスチャ番号を利用 | |
| 260 | + //読み込めれば、今回読み込むテクスチャ番号を上書き | |
| 261 | + int id = Resource->GetHumanTexture(paramID); | |
| 262 | + if( id == -1 ){ | |
| 263 | + id = AddHumanIndex_TextureID; | |
| 264 | + } | |
| 265 | + else{ | |
| 266 | + AddHumanIndex_TextureID = id; | |
| 267 | + } | |
| 268 | + | |
| 269 | + HumanIndex[i].SetTexture(id); | |
| 270 | + HumanIndex[i].SetModel(upmodel[ HumanParam.model ], armmodel, legmodel, walkmodel, runmodel); | |
| 271 | + } | |
| 272 | + else{ | |
| 273 | + //今回読み込むテクスチャ番号を上書き | |
| 274 | + AddHumanIndex_TextureID = d3dg->GetMapTextureID(0); | |
| 275 | + | |
| 276 | + HumanIndex[i].SetTexture(AddHumanIndex_TextureID); | |
| 277 | + HumanIndex[i].SetModel(upmodel[0], armmodel, legmodel, walkmodel, runmodel); | |
| 278 | + } | |
| 279 | + HumanIndex[i].SetDrawFlag(true); | |
| 280 | + Humanindexid = i; | |
| 281 | + break; | |
| 282 | + } | |
| 283 | + } | |
| 284 | + | |
| 285 | + //初期化できなかったらエラーとして返す | |
| 286 | + if( Humanindexid == -1 ){ | |
| 287 | + return -1; | |
| 288 | + } | |
| 289 | + | |
| 290 | + if( GetHumanFlag == 0 ){ | |
| 291 | + //仮想武器を追加 | |
| 292 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 293 | + Weaponindexid = AddVisualWeaponIndex(WeaponID[i], true); | |
| 294 | + if( Weaponindexid != -1 ){ | |
| 295 | + //成功すれば配列に記録 | |
| 296 | + Weapon[i] = &WeaponIndex[Weaponindexid]; | |
| 297 | + } | |
| 298 | + } | |
| 299 | + | |
| 300 | + //人に持たせる | |
| 301 | + HumanIndex[Humanindexid].SetWeapon(Weapon); | |
| 302 | + } | |
| 303 | + | |
| 304 | + return Humanindexid; | |
| 305 | +} | |
| 306 | + | |
| 307 | +//! 武器追加 | |
| 308 | +//! @param data 武器のポイントデータ (pointdata構造体) | |
| 309 | +//! @return 成功:データ番号(0以上) 失敗:-1 | |
| 310 | +int ObjectManager::AddWeaponIndex(pointdata data) | |
| 311 | +{ | |
| 312 | + //武器番号と弾数を仮登録 | |
| 313 | + int WeaponID = data.p2; | |
| 314 | + int nbs = (unsigned char)data.p3; | |
| 315 | + | |
| 316 | + //ランダムな武器ならば | |
| 317 | + if( data.p1 == 7 ){ | |
| 318 | + WeaponParameter WeaponParam; | |
| 319 | + | |
| 320 | + if( GetRand(2) == 0 ){ | |
| 321 | + if( GameParamInfo->GetWeapon(data.p2, &WeaponParam) == 1 ){ return -1; } | |
| 322 | + nbs = (int)WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET; //弾数上書き | |
| 323 | + } | |
| 324 | + else{ | |
| 325 | + if( GameParamInfo->GetWeapon(data.p3, &WeaponParam) == 1 ){ return -1; } | |
| 326 | + WeaponID = data.p3; //武器番号上書き | |
| 327 | + nbs = (int)WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET; //弾数上書き | |
| 328 | + } | |
| 329 | + } | |
| 330 | + | |
| 331 | + //NONEならば失敗 | |
| 332 | + if( WeaponID == ID_WEAPON_NONE ){ return -1; } | |
| 333 | + | |
| 334 | + //モデルとテクスチャを取得 | |
| 335 | + int model, texture; | |
| 336 | + if( Resource->GetWeaponModelTexture(WeaponID, &model, &texture) == 1 ){ | |
| 337 | + return -1; | |
| 338 | + } | |
| 339 | + | |
| 340 | + //設定値を取得 | |
| 341 | + WeaponParameter WeaponParam; | |
| 342 | + if( GameParamInfo->GetWeapon(data.p2, &WeaponParam) == 1 ){ return -1; } | |
| 343 | + | |
| 344 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 345 | + if( WeaponIndex[i].GetDrawFlag() == false ){ | |
| 346 | + //初期化する | |
| 347 | + WeaponIndex[i].SetPosData(data.x, data.y, data.z, data.r); | |
| 348 | + WeaponIndex[i].SetParamData(WeaponID, 0, nbs, true); | |
| 349 | + WeaponIndex[i].SetModel(model, WeaponParam.size); | |
| 350 | + WeaponIndex[i].SetTexture(texture); | |
| 351 | + WeaponIndex[i].SetDrawFlag(true); | |
| 352 | + WeaponIndex[i].RunReload(); | |
| 353 | + return i; | |
| 354 | + } | |
| 355 | + } | |
| 356 | + return -1; | |
| 357 | +} | |
| 358 | + | |
| 359 | +//! 仮想武器追加 | |
| 360 | +//! @param WeaponID 武器の種類番号 | |
| 361 | +//! @param loadbullet 弾をロードする | |
| 362 | +//! @return 成功:データ番号(0以上) 失敗:-1 | |
| 363 | +//! @attention 人が最初から所持している武器を、武器データ(オブジェクト)として追加処理するための関数です。 | |
| 364 | +//! @attention 武器単体として配置する場合は、AddWeaponIndex()関数を使用してください。 | |
| 365 | +int ObjectManager::AddVisualWeaponIndex(int WeaponID, bool loadbullet) | |
| 366 | +{ | |
| 367 | + //NONEならば失敗 | |
| 368 | + if( WeaponID == ID_WEAPON_NONE ){ return -1; } | |
| 369 | + | |
| 370 | + //情報を取得 | |
| 371 | + WeaponParameter WeaponParam; | |
| 372 | + if( GameParamInfo->GetWeapon(WeaponID, &WeaponParam) == 1 ){ return -1; } | |
| 373 | + | |
| 374 | + //モデルとテクスチャを取得 | |
| 375 | + int model, texture; | |
| 376 | + if( Resource->GetWeaponModelTexture(WeaponID, &model, &texture) == 1 ){ | |
| 377 | + return -1; | |
| 378 | + } | |
| 379 | + | |
| 380 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 381 | + if( WeaponIndex[i].GetDrawFlag() == false ){ | |
| 382 | + //初期化 | |
| 383 | + WeaponIndex[i].SetPosData(0.0f, 0.0f, 0.0f, 0.0f); | |
| 384 | + if( loadbullet == false ){ | |
| 385 | + WeaponIndex[i].SetParamData(WeaponID, 0, 0, true); | |
| 386 | + } | |
| 387 | + else{ | |
| 388 | + WeaponIndex[i].SetParamData(WeaponID, WeaponParam.nbsmax, WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET, true); | |
| 389 | + } | |
| 390 | + WeaponIndex[i].SetModel(model, WeaponParam.size); | |
| 391 | + WeaponIndex[i].SetTexture(texture); | |
| 392 | + WeaponIndex[i].SetDrawFlag(true); | |
| 393 | + return i; | |
| 394 | + } | |
| 395 | + } | |
| 396 | + return -1; | |
| 397 | +} | |
| 398 | + | |
| 399 | +//! 小物追加 | |
| 400 | +//! @param data 小物のポイントデータ (pointdata構造体) | |
| 401 | +//! @return 成功:データ番号(0以上) 失敗:-1 | |
| 402 | +int ObjectManager::AddSmallObjectIndex(pointdata data) | |
| 403 | +{ | |
| 404 | + //モデルとテクスチャを取得 | |
| 405 | + int model, texture; | |
| 406 | + if( Resource->GetSmallObjectModelTexture(data.p2, &model, &texture) == 1 ){ | |
| 407 | + return -1; | |
| 408 | + } | |
| 409 | + | |
| 410 | + for(int j=0; j<MAX_SMALLOBJECT; j++){ | |
| 411 | + if( SmallObjectIndex[j].GetDrawFlag() == false ){ | |
| 412 | + //初期化 | |
| 413 | + SmallObjectIndex[j].SetPosData(data.x, data.y, data.z, data.r); | |
| 414 | + SmallObjectIndex[j].SetParamData(data.p2, data.p4, true); | |
| 415 | + SmallObjectIndex[j].SetModel(model, 5.0f); | |
| 416 | + SmallObjectIndex[j].SetTexture(texture); | |
| 417 | + SmallObjectIndex[j].SetDrawFlag(true); | |
| 418 | + | |
| 419 | + //位置修正フラグが有効ならば、マップと判定 | |
| 420 | + if( data.p3 !=0 ){ | |
| 421 | + SmallObjectIndex[j].CollisionMap(CollD); | |
| 422 | + } | |
| 423 | + return j; | |
| 424 | + } | |
| 425 | + } | |
| 426 | + return -1; | |
| 427 | +} | |
| 428 | + | |
| 429 | +//! 出血させる | |
| 430 | +//! @param x X座標 | |
| 431 | +//! @param y Y座標 | |
| 432 | +//! @param z Z座標 | |
| 433 | +void ObjectManager::SetHumanBlood(float x, float y, float z) | |
| 434 | +{ | |
| 435 | + if( GameConfig.GetBloodFlag() == true ){ | |
| 436 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 437 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 438 | + EffectIndex[i].SetPosData(x+1.0f, y+1.0f, z+1.0f, 0.0f); | |
| 439 | + EffectIndex[i].SetParamData(10.0f, (float)M_PI/18*GetRand(18), (int)GAMEFPS * 1, Resource->GetEffectBloodTexture(), EFFECT_FALL, true); | |
| 440 | + EffectIndex[i].SetDrawFlag(true); | |
| 441 | + break; | |
| 442 | + } | |
| 443 | + } | |
| 444 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 445 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 446 | + EffectIndex[i].SetPosData(x-1.0f, y-1.0f, z-1.0f, 0.0f); | |
| 447 | + EffectIndex[i].SetParamData(10.0f, (float)M_PI/18*GetRand(18), (int)GAMEFPS * 1, Resource->GetEffectBloodTexture(), EFFECT_FALL, true); | |
| 448 | + EffectIndex[i].SetDrawFlag(true); | |
| 449 | + break; | |
| 450 | + } | |
| 451 | + } | |
| 452 | + } | |
| 453 | +} | |
| 454 | + | |
| 455 | +//! 人同士の当たり判定 | |
| 456 | +//! @param in_humanA 対象の人オブジェクトA | |
| 457 | +//! @param in_humanB 対象の人オブジェクトB | |
| 458 | +//! @return 当たっている:true 当たっていない:false | |
| 459 | +//! @warning in_humanAとin_humanBで区別はありません。 | |
| 460 | +//! @warning in_humanAとin_humanBでの組み合せは、1フレーム間に1度だけ実行してください。 | |
| 461 | +//! @attention 両クラスは自動的にAddPosOrder()を用いて、お互いを押し合います。 | |
| 462 | +bool ObjectManager::CollideHuman(human *in_humanA, human *in_humanB) | |
| 463 | +{ | |
| 464 | + float h1_x, h1_y, h1_z; | |
| 465 | + float h2_x, h2_y, h2_z; | |
| 466 | + float angle, length; | |
| 467 | + | |
| 468 | + //初期化されていないか、死亡して入れば判定しない | |
| 469 | + if( in_humanA->GetDrawFlag() == false ){ return false; } | |
| 470 | + if( in_humanB->GetDrawFlag() == false ){ return false; } | |
| 471 | + if( in_humanA->GetHP() <= 0 ){ return false; } | |
| 472 | + if( in_humanB->GetHP() <= 0 ){ return false; } | |
| 473 | + | |
| 474 | + //お互いの座標を取得 | |
| 475 | + in_humanA->GetPosData(&h1_x, &h1_y, &h1_z, NULL); | |
| 476 | + in_humanB->GetPosData(&h2_x, &h2_y, &h2_z, NULL); | |
| 477 | + | |
| 478 | + //円柱の当たり判定 | |
| 479 | + if( CollideCylinder(h1_x, h1_y, h1_z, 3.0f, HUMAN_HEIGTH, h2_x, h2_y, h2_z, 3.0f, HUMAN_HEIGTH, &angle, &length) == true ){ | |
| 480 | + //めり込んだ分だけ押し出す | |
| 481 | + in_humanA->AddPosOrder(angle, length/2); | |
| 482 | + in_humanB->AddPosOrder(angle + (float)M_PI, length/2); | |
| 483 | + return true; | |
| 484 | + } | |
| 485 | + | |
| 486 | + return false; | |
| 487 | +} | |
| 488 | + | |
| 489 | +//! 弾の当たり判定と処理 | |
| 490 | +//! @param in_bullet 対象の弾オブジェクト | |
| 491 | +//! @return 当たった:true 当たっていない:false | |
| 492 | +//! @attention 判定を行う対象は「マップ」「人(頭・上半身・下半身)」「小物」です。 | |
| 493 | +//! @attention 判定に限らず、ダメージ計算や効果音再生まで一貫して行います。 | |
| 494 | +bool ObjectManager::CollideBullet(bullet *in_bullet) | |
| 495 | +{ | |
| 496 | + //使用されていない弾丸ならば、処理せずに返す。 | |
| 497 | + if( in_bullet->GetDrawFlag() == false ){ return false; } | |
| 498 | + | |
| 499 | + float bx, by, bz; | |
| 500 | + float brx, bry; | |
| 501 | + int attacks; | |
| 502 | + int penetration; | |
| 503 | + int speed; | |
| 504 | + int teamid; | |
| 505 | + int humanid; | |
| 506 | + float vx, vy, vz; | |
| 507 | + int HumanHead_id; | |
| 508 | + int HumanUp_id; | |
| 509 | + int HumanLeg_id; | |
| 510 | + int SmallObject_id; | |
| 511 | + float map_Dist; | |
| 512 | + float HumanHead_Dist; | |
| 513 | + float HumanUp_Dist; | |
| 514 | + float HumanLeg_Dist; | |
| 515 | + float SmallObject_Dist; | |
| 516 | + float CheckDist; | |
| 517 | + bool CollideFlag; | |
| 518 | + | |
| 519 | + int id, face; | |
| 520 | + float Dist; | |
| 521 | + | |
| 522 | + //弾丸の座標を取得し、ベクトルを算出。 | |
| 523 | + in_bullet->GetPosData(&bx, &by, &bz, &brx, &bry); | |
| 524 | + in_bullet->GetParamData(&attacks, &penetration, &speed, &teamid, &humanid); | |
| 525 | + vx = cos(brx)*cos(bry); | |
| 526 | + vy = sin(bry); | |
| 527 | + vz = sin(brx)*cos(bry); | |
| 528 | + | |
| 529 | + CheckDist = 0; | |
| 530 | + CollideFlag = false; | |
| 531 | + | |
| 532 | + for(float TotalDist=0.0f; TotalDist<speed; TotalDist+=CheckDist){ | |
| 533 | + CheckDist = speed - TotalDist; | |
| 534 | + | |
| 535 | + //貫通力が残っていなければ | |
| 536 | + if( penetration < 0 ){ | |
| 537 | + //弾は無効にする | |
| 538 | + in_bullet->SetDrawFlag(false); | |
| 539 | + break; | |
| 540 | + } | |
| 541 | + | |
| 542 | + float bvx, bvy, bvz; | |
| 543 | + bvx = bx + vx*TotalDist; | |
| 544 | + bvy = by + vy*TotalDist; | |
| 545 | + bvz = bz + vz*TotalDist; | |
| 546 | + | |
| 547 | + HumanHead_id = -1; | |
| 548 | + HumanUp_id = -1; | |
| 549 | + HumanLeg_id = -1; | |
| 550 | + SmallObject_id = -1; | |
| 551 | + map_Dist = (float)speed - TotalDist + 1; | |
| 552 | + HumanHead_Dist = (float)speed - TotalDist + 1; | |
| 553 | + HumanUp_Dist = (float)speed - TotalDist + 1; | |
| 554 | + HumanLeg_Dist = (float)speed - TotalDist + 1; | |
| 555 | + SmallObject_Dist = (float)speed - TotalDist + 1; | |
| 556 | + | |
| 557 | + //マップとの当たり判定 | |
| 558 | + if( CollD->CheckALLBlockIntersectRay(bvx, bvy, bvz, vx, vy, vz, &id, &face, &Dist, (float)speed - TotalDist) == true ){ | |
| 559 | + map_Dist = Dist; | |
| 560 | + } | |
| 561 | + | |
| 562 | + //人との当たり判定 | |
| 563 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 564 | + //使用されていないか、死亡していれば処理しない。 | |
| 565 | + if( HumanIndex[i].GetDrawFlag() == false ){ continue; } | |
| 566 | + if( HumanIndex[i].GetHP() <= 0 ){ continue; } | |
| 567 | + | |
| 568 | + //座標を取得 | |
| 569 | + float ox, oy, oz; | |
| 570 | + int h_teamid; | |
| 571 | + HumanIndex[i].GetPosData(&ox, &oy, &oz, NULL); | |
| 572 | + HumanIndex[i].GetParamData(NULL, NULL, NULL, &h_teamid); | |
| 573 | + | |
| 574 | + //同じチーム番号(味方)なら処理しない | |
| 575 | + if( h_teamid == teamid ){ continue; } | |
| 576 | + | |
| 577 | + //人全体の当たり判定 | |
| 578 | + if( CollideAABBRay(ox-3.0f, oy, oz-3.0f, ox+3.0f, oy+HUMAN_HEIGTH, oz+3.0f, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){ | |
| 579 | + | |
| 580 | + //頭の当たり判定 | |
| 581 | + if( CollideAABBRay(ox-1.0f, oy+17.5f, oz-1.0f, ox+1.0f, oy+20.0f, oz+1.0f, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){ | |
| 582 | + if( Dist < HumanHead_Dist ){ | |
| 583 | + HumanHead_id = i; | |
| 584 | + HumanHead_Dist = Dist; | |
| 585 | + } | |
| 586 | + } | |
| 587 | + | |
| 588 | + //上半身と当たり判定 | |
| 589 | + if( CollideAABBRay(ox-3.0f, oy+10.0f, oz-3.0f, ox+3.0f, oy+17.5f, oz+3.0f, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){ | |
| 590 | + if( Dist < HumanUp_Dist ){ | |
| 591 | + HumanUp_id = i; | |
| 592 | + HumanUp_Dist = Dist; | |
| 593 | + } | |
| 594 | + } | |
| 595 | + | |
| 596 | + //足と当たり判定 | |
| 597 | + if( CollideAABBRay(ox-3.0f, oy, oz-3.0f, ox+3.0f, oy+10.0f, oz+3.0f, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){ | |
| 598 | + if( Dist < HumanLeg_Dist ){ | |
| 599 | + HumanLeg_id = i; | |
| 600 | + HumanLeg_Dist = Dist; | |
| 601 | + } | |
| 602 | + } | |
| 603 | + | |
| 604 | + } | |
| 605 | + } | |
| 606 | + | |
| 607 | + //小物との当たり判定 | |
| 608 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 609 | + //使用されていなければ処理しない | |
| 610 | + if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; } | |
| 611 | + | |
| 612 | + //座標を取得 | |
| 613 | + float ox, oy, oz; | |
| 614 | + int id; | |
| 615 | + float decide; | |
| 616 | + SmallObjectIndex[i].GetPosData(&ox, &oy, &oz, NULL); | |
| 617 | + SmallObjectIndex[i].GetParamData(&id, NULL); | |
| 618 | + | |
| 619 | + //当たり判定の大きさを取得 | |
| 620 | + if( id == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){ | |
| 621 | + decide = (float)MIFdata->GetAddSmallobjectDecide()*SMALLOBJECT_SCALE; | |
| 622 | + } | |
| 623 | + else{ | |
| 624 | + SmallObjectParameter Param; | |
| 625 | + GameParamInfo->GetSmallObject(id, &Param); | |
| 626 | + decide = (float)Param.decide*SMALLOBJECT_SCALE; | |
| 627 | + } | |
| 628 | + | |
| 629 | + //当たり判定 | |
| 630 | + if( CollideSphereRay(ox, oy, oz, decide, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){ | |
| 631 | + if( Dist < SmallObject_Dist ){ | |
| 632 | + SmallObject_id = i; | |
| 633 | + SmallObject_Dist = Dist; | |
| 634 | + } | |
| 635 | + } | |
| 636 | + } | |
| 637 | + | |
| 638 | + //マップとの衝突距離が最短ならば〜 | |
| 639 | + if( (map_Dist <= speed)&&(map_Dist < HumanHead_Dist)&&(map_Dist < HumanUp_Dist)&&(map_Dist < HumanLeg_Dist)&&(map_Dist < SmallObject_Dist) ){ | |
| 640 | + //弾がマップに当たった処理 | |
| 641 | + HitBulletMap(bx + vx*(map_Dist+TotalDist), by + vy*(map_Dist+TotalDist), bz + vz*(map_Dist+TotalDist)); | |
| 642 | + | |
| 643 | + int Penetration_Dist; | |
| 644 | + | |
| 645 | + //マップにめり込んでいる量を調べる | |
| 646 | + // 最終地点がマップにめり込んでいるならば | |
| 647 | + if( CollD->CheckALLBlockIntersectRay(bx + vx*speed, by + vy*speed, bz + vz*speed, vx*-1, vy*-1, vz*-1, &id, &face, &Dist, (float)speed - map_Dist+TotalDist) == true ){ | |
| 648 | + //発射地点と最終地点、それぞれからの激突点から貫通距離を求める | |
| 649 | + Penetration_Dist = (int)( ((float)speed - map_Dist+TotalDist - Dist) / 2 ); | |
| 650 | + } | |
| 651 | + else{ | |
| 652 | + //衝突点から最終地点まで移動距離 | |
| 653 | + Penetration_Dist = (int)( ((float)speed - map_Dist+TotalDist) / 2 ); | |
| 654 | + } | |
| 655 | + | |
| 656 | + //攻撃力と貫通力を計算 | |
| 657 | + for(int i=0; i<Penetration_Dist; i++){ | |
| 658 | + attacks = (int)((float)attacks * 0.6f); | |
| 659 | + } | |
| 660 | + penetration -= Penetration_Dist; | |
| 661 | + | |
| 662 | + CheckDist = map_Dist + 1.0f; | |
| 663 | + } | |
| 664 | + | |
| 665 | + //人の頭との衝突距離が最短ならば〜 | |
| 666 | + if( (HumanHead_Dist <= speed)&&(HumanHead_Dist < map_Dist)&&(HumanHead_Dist < HumanUp_Dist)&&(HumanHead_Dist < HumanLeg_Dist)&&(HumanHead_Dist < SmallObject_Dist) ){ | |
| 667 | + //人に当たった処理 | |
| 668 | + HitBulletHuman(HumanHead_id, 0, bx + vx*(HumanHead_Dist+TotalDist), by + vy*(HumanHead_Dist+TotalDist), bz + vz*(HumanHead_Dist+TotalDist), brx, attacks, humanid); | |
| 669 | + | |
| 670 | + //攻撃力と貫通力を計算 | |
| 671 | + attacks = (int)((float)attacks * 0.6f); | |
| 672 | + penetration -= 1; | |
| 673 | + | |
| 674 | + CheckDist = HumanHead_Dist + 1.0f; | |
| 675 | + } | |
| 676 | + | |
| 677 | + //人の上半身との衝突距離が最短ならば〜 | |
| 678 | + if( (HumanUp_Dist <= speed)&&(HumanUp_Dist < map_Dist)&&(HumanUp_Dist < HumanHead_Dist)&&(HumanUp_Dist < HumanLeg_Dist)&&(HumanUp_Dist < SmallObject_Dist) ){ | |
| 679 | + //人に当たった処理 | |
| 680 | + HitBulletHuman(HumanUp_id, 1, bx + vx*(HumanUp_Dist+TotalDist), by + vy*(HumanUp_Dist+TotalDist), bz + vz*(HumanUp_Dist+TotalDist), brx, attacks, humanid); | |
| 681 | + | |
| 682 | + //攻撃力と貫通力を計算 | |
| 683 | + attacks = (int)((float)attacks * 0.6f); | |
| 684 | + penetration -= 1; | |
| 685 | + | |
| 686 | + CheckDist = HumanUp_Dist + 1.0f; | |
| 687 | + } | |
| 688 | + | |
| 689 | + //人の足との衝突距離が最短ならば〜 | |
| 690 | + if( (HumanLeg_Dist <= speed)&&(HumanLeg_Dist < map_Dist)&&(HumanLeg_Dist < HumanHead_Dist)&&(HumanLeg_Dist < HumanUp_Dist)&&(HumanLeg_Dist < SmallObject_Dist) ){ | |
| 691 | + //人に当たった処理 | |
| 692 | + HitBulletHuman(HumanLeg_id, 2, bx + vx*(HumanLeg_Dist+TotalDist), by + vy*(HumanLeg_Dist+TotalDist), bz + vz*(HumanLeg_Dist+TotalDist), brx, attacks, humanid); | |
| 693 | + | |
| 694 | + //攻撃力と貫通力を計算 | |
| 695 | + attacks = (int)((float)attacks * 0.7f); | |
| 696 | + penetration -= 1; | |
| 697 | + | |
| 698 | + CheckDist = HumanLeg_Dist + 1.0f; | |
| 699 | + } | |
| 700 | + | |
| 701 | + //小物との衝突距離が最短ならば〜 | |
| 702 | + if( (SmallObject_Dist <= speed)&&(SmallObject_Dist < map_Dist)&&(SmallObject_Dist < HumanHead_Dist)&&(SmallObject_Dist < HumanUp_Dist)&&(SmallObject_Dist < HumanLeg_Dist) ){ | |
| 703 | + //小物に当たった処理 | |
| 704 | + HitBulletSmallObject(SmallObject_id, bx + vx*(SmallObject_Dist+TotalDist), by + vy*(SmallObject_Dist+TotalDist), bz + vz*(SmallObject_Dist+TotalDist), attacks); | |
| 705 | + | |
| 706 | + //小物の種類番号を取得 | |
| 707 | + int id; | |
| 708 | + int decide; | |
| 709 | + SmallObjectIndex[SmallObject_id].GetParamData(&id, NULL); | |
| 710 | + | |
| 711 | + //小物の設定値を取得 | |
| 712 | + SmallObjectParameter Param; | |
| 713 | + GameParamInfo->GetSmallObject(id, &Param); | |
| 714 | + decide = (int)( (float)Param.decide*SMALLOBJECT_SCALE ); | |
| 715 | + | |
| 716 | + //貫通力を計算 | |
| 717 | + for(int i=0; i<decide; i++){ | |
| 718 | + attacks = (int)((float)attacks * 0.7f); | |
| 719 | + } | |
| 720 | + | |
| 721 | + CheckDist = SmallObject_Dist + 1.0f; | |
| 722 | + } | |
| 723 | + | |
| 724 | + //設定を適用(特に攻撃力・貫通力) | |
| 725 | + in_bullet->SetParamData(attacks, penetration, speed, teamid, humanid, false); | |
| 726 | + } | |
| 727 | + | |
| 728 | + return CollideFlag; | |
| 729 | +} | |
| 730 | + | |
| 731 | +//! 弾がマップに当たった処理 | |
| 732 | +//! @param x 着弾X座標 | |
| 733 | +//! @param y 着弾Y座標 | |
| 734 | +//! @param z 着弾Z座標 | |
| 735 | +void ObjectManager::HitBulletMap(float x, float y, float z) | |
| 736 | +{ | |
| 737 | + //エフェクト(煙)を表示 | |
| 738 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 739 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 740 | + EffectIndex[i].SetPosData(x, y, z, 0.0f); | |
| 741 | + EffectIndex[i].SetParamData(5.0f, (float)M_PI/18*GetRand(18), (int)(GAMEFPS * 0.5f), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY, true); | |
| 742 | + EffectIndex[i].SetDrawFlag(true); | |
| 743 | + break; | |
| 744 | + } | |
| 745 | + } | |
| 746 | + | |
| 747 | + //効果音を再生 | |
| 748 | + GameSound->HitMap(x, y, z); | |
| 749 | +} | |
| 750 | + | |
| 751 | +//! 弾が人に当たった処理 | |
| 752 | +//! @param HitHuman_id 人の番号 | |
| 753 | +//! @param Hit_id 被弾箇所(頭:0 胴体:1 足:2) | |
| 754 | +//! @param x 被弾X座標 | |
| 755 | +//! @param y 被弾Y座標 | |
| 756 | +//! @param z 被弾Z座標 | |
| 757 | +//! @param brx 水平角度 | |
| 758 | +//! @param attacks 攻撃力 | |
| 759 | +//! @param Shothuman_id 発射した人の番号 | |
| 760 | +void ObjectManager::HitBulletHuman(int HitHuman_id, int Hit_id, float x, float y, float z, float brx, int attacks, int Shothuman_id) | |
| 761 | +{ | |
| 762 | + //使用されていないか、死亡していれば処理しない。 | |
| 763 | + if( HumanIndex[HitHuman_id].GetDrawFlag() == false ){ return; } | |
| 764 | + if( HumanIndex[HitHuman_id].GetHP() <= 0 ){ return; } | |
| 765 | + | |
| 766 | + //人にダメージと衝撃を与える | |
| 767 | + if( Hit_id == 0 ){ HumanIndex[HitHuman_id].HitBulletHead(attacks); } | |
| 768 | + if( Hit_id == 1 ){ HumanIndex[HitHuman_id].HitBulletUp(attacks); } | |
| 769 | + if( Hit_id == 2 ){ HumanIndex[HitHuman_id].HitBulletLeg(attacks); } | |
| 770 | + HumanIndex[HitHuman_id].AddPosOrder(brx, 2.0f); | |
| 771 | + | |
| 772 | + //エフェクト(血)を表示 | |
| 773 | + SetHumanBlood(x, y, z); | |
| 774 | + | |
| 775 | + //効果音を再生 | |
| 776 | + GameSound->HitHuman(x, y, z); | |
| 777 | + | |
| 778 | + //弾を発射した人の成果に加算 | |
| 779 | + Human_ontarget[Shothuman_id] += 1; | |
| 780 | + if( Hit_id == 0 ){ Human_headshot[Shothuman_id] += 1; } | |
| 781 | + if( HumanIndex[HitHuman_id].GetHP() <= 0 ){ | |
| 782 | + Human_kill[Shothuman_id] += 1; | |
| 783 | + } | |
| 784 | +} | |
| 785 | + | |
| 786 | +//! 弾が小物に当たった処理 | |
| 787 | +//! @param HitSmallObject_id 小物の番号 | |
| 788 | +//! @param x 着弾X座標 | |
| 789 | +//! @param y 着弾Y座標 | |
| 790 | +//! @param z 着弾Z座標 | |
| 791 | +//! @param attacks 攻撃力 | |
| 792 | +void ObjectManager::HitBulletSmallObject(int HitSmallObject_id, float x, float y, float z, int attacks) | |
| 793 | +{ | |
| 794 | + int hp; | |
| 795 | + | |
| 796 | + //使用されていなければ処理しない。 | |
| 797 | + if( SmallObjectIndex[HitSmallObject_id].GetDrawFlag() == false ){ return; } | |
| 798 | + | |
| 799 | + //体力がなければ処理しない | |
| 800 | + hp = SmallObjectIndex[HitSmallObject_id].GetHP(); | |
| 801 | + if( hp <= 0 ){ return; } | |
| 802 | + | |
| 803 | + //小物にダメージを与える | |
| 804 | + SmallObjectIndex[HitSmallObject_id].HitBullet(attacks); | |
| 805 | + | |
| 806 | + //エフェクト(煙)を表示 | |
| 807 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 808 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 809 | + EffectIndex[i].SetPosData(x, y, z, 0.0f); | |
| 810 | + EffectIndex[i].SetParamData(5.0f, (float)M_PI/18*GetRand(18), (int)(GAMEFPS * 0.5f), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY, true); | |
| 811 | + EffectIndex[i].SetDrawFlag(true); | |
| 812 | + break; | |
| 813 | + } | |
| 814 | + } | |
| 815 | + | |
| 816 | + //効果音を再生 | |
| 817 | + int id; | |
| 818 | + SmallObjectIndex[HitSmallObject_id].GetParamData(&id, NULL); | |
| 819 | + GameSound->HitSmallObject(x, y, z, id); | |
| 820 | +} | |
| 821 | + | |
| 822 | +//! 武器を拾う | |
| 823 | +//! @param in_human 対象の人オブジェクト | |
| 824 | +//! @param in_weapon 対象の武器オブジェクト | |
| 825 | +void ObjectManager::PickupWeapon(human *in_human, weapon *in_weapon) | |
| 826 | +{ | |
| 827 | + //無効な人ならば処理しない | |
| 828 | + if( in_human->GetDrawFlag() == false ){ return; } | |
| 829 | + if( in_human->GetHP() <= 0 ){ return; } | |
| 830 | + | |
| 831 | + //初期化されている武器で、かつ誰も使っていない武器ならば〜 | |
| 832 | + if( (in_weapon->GetDrawFlag() == true)&&(in_weapon->GetUsingFlag() == false) ){ | |
| 833 | + float human_x, human_y, human_z; | |
| 834 | + float weapon_x, weapon_y, weapon_z; | |
| 835 | + float x, z; | |
| 836 | + float r; | |
| 837 | + | |
| 838 | + //人と武器の座標を取得 | |
| 839 | + in_human->GetPosData(&human_x, &human_y, &human_z, NULL); | |
| 840 | + in_weapon->GetPosData(&weapon_x, &weapon_y, &weapon_z, NULL); | |
| 841 | + | |
| 842 | + //高さが範囲内ならば | |
| 843 | + if( (human_y-2.0f <= weapon_y)&&(human_y+16.0f > weapon_y) ){ | |
| 844 | + //距離を計算 | |
| 845 | + x = human_x - weapon_x; | |
| 846 | + z = human_z - weapon_z; | |
| 847 | + r = x*x + z*z; | |
| 848 | + //距離も範囲内ならば、拾わせる。 | |
| 849 | + if( r < (5.0f * 5.0f) ){ | |
| 850 | + in_human->PickupWeapon(in_weapon); | |
| 851 | + } | |
| 852 | + } | |
| 853 | + } | |
| 854 | +} | |
| 855 | + | |
| 856 | +//! オブジェクトを解放 | |
| 857 | +void ObjectManager::CleanupPointDataToObject() | |
| 858 | +{ | |
| 859 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 860 | + HumanIndex[i].SetDrawFlag(false); | |
| 861 | + } | |
| 862 | + | |
| 863 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 864 | + WeaponIndex[i].SetDrawFlag(false); | |
| 865 | + } | |
| 866 | + | |
| 867 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 868 | + SmallObjectIndex[i].SetDrawFlag(false); | |
| 869 | + } | |
| 870 | + | |
| 871 | + for(int i=0; i<MAX_BULLET; i++){ | |
| 872 | + BulletIndex[i].SetDrawFlag(false); | |
| 873 | + } | |
| 874 | + | |
| 875 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 876 | + GrenadeIndex[i].SetDrawFlag(false); | |
| 877 | + } | |
| 878 | + | |
| 879 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 880 | + EffectIndex[i].SetDrawFlag(false); | |
| 881 | + } | |
| 882 | + | |
| 883 | + | |
| 884 | + if( Resource != NULL ){ | |
| 885 | + Resource->CleanupHumanTexture(); | |
| 886 | + } | |
| 887 | +} | |
| 888 | + | |
| 889 | +//! ポイントデータを元にオブジェクトを配置 | |
| 890 | +void ObjectManager::LoadPointData() | |
| 891 | +{ | |
| 892 | + Player_HumanID = 0; | |
| 893 | + | |
| 894 | + /* | |
| 895 | + //人情報ポイントを探す | |
| 896 | + for(int i=0; i<PointData->GetTotaldatas(); i++){ | |
| 897 | + pointdata data; | |
| 898 | + PointData->Getdata(&data, i); | |
| 899 | + | |
| 900 | + if( data.p1 == 4 ){ | |
| 901 | + //人のテクスチャを登録 | |
| 902 | + Resource->AddHumanTexture(data.p2); | |
| 903 | + } | |
| 904 | + } | |
| 905 | + */ | |
| 906 | + | |
| 907 | + //人・武器・小物を探す | |
| 908 | + for(int i=0; i<PointData->GetTotaldatas(); i++){ | |
| 909 | + pointdata data; | |
| 910 | + PointData->Getdata(&data, i); | |
| 911 | + | |
| 912 | + //人ならば | |
| 913 | + if( (data.p1 == 1)||(data.p1 == 6) ){ | |
| 914 | + pointdata humaninfodata; | |
| 915 | + | |
| 916 | + //人情報ポイントを探す | |
| 917 | + if( PointData->SearchPointdata(&humaninfodata, 0x01 + 0x08, 4, 0, 0, data.p2, 0) == 0 ){ | |
| 918 | + //continue; | |
| 919 | + | |
| 920 | + //人情報ポイントが見つからなかったら、とりあえず「特殊 黒 A」として追加。(バグの再現) | |
| 921 | + | |
| 922 | + HumanParameter HumanParam; | |
| 923 | + int Weapon[TOTAL_HAVEWEAPON]; | |
| 924 | + GameParamInfo->GetHuman(0, &HumanParam); | |
| 925 | + for(int j=0; j<TOTAL_HAVEWEAPON; j++){ | |
| 926 | + Weapon[j] = HumanParam.Weapon[j]; | |
| 927 | + } | |
| 928 | + | |
| 929 | + //人のテクスチャを登録 | |
| 930 | + Resource->AddHumanTexture(0); | |
| 931 | + | |
| 932 | + //人を追加 | |
| 933 | + if( data.p1 == 6 ){ | |
| 934 | + Weapon[1] = ID_WEAPON_NONE; | |
| 935 | + } | |
| 936 | + | |
| 937 | + //プレイヤーならば、番号を記録 | |
| 938 | + if( (data.p4 == 0)&&(Player_HumanID == 0) ){ | |
| 939 | + Player_HumanID = AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon); | |
| 940 | + } | |
| 941 | + else{ | |
| 942 | + AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon); | |
| 943 | + } | |
| 944 | + } | |
| 945 | + else{ | |
| 946 | + //人のテクスチャを登録 | |
| 947 | + Resource->AddHumanTexture(humaninfodata.p2); | |
| 948 | + | |
| 949 | + //人として追加 | |
| 950 | + AddHumanIndex(data, humaninfodata); | |
| 951 | + } | |
| 952 | + } | |
| 953 | + | |
| 954 | + //武器ならば | |
| 955 | + if( (data.p1 == 2)||(data.p1 == 7) ){ | |
| 956 | + AddWeaponIndex(data); | |
| 957 | + } | |
| 958 | + | |
| 959 | + //小物ならば | |
| 960 | + if( data.p1 == 5 ){ | |
| 961 | + AddSmallObjectIndex(data); | |
| 962 | + } | |
| 963 | + } | |
| 964 | +} | |
| 965 | + | |
| 966 | +//! humanクラスを取得 | |
| 967 | +//! @deprecated この関数で各オブジェクトを直接呼び出すことは避け、このクラスの各種メンバー関数を使用してください。この関数は将来的に削除されます。 | |
| 968 | +human* ObjectManager::GetHumanList() | |
| 969 | +{ | |
| 970 | + return HumanIndex; | |
| 971 | +} | |
| 972 | + | |
| 973 | +//! weaponクラスを取得 | |
| 974 | +//! @deprecated この関数で各オブジェクトを直接呼び出すことは避け、このクラスの各種メンバー関数を使用してください。この関数は将来的に削除されます。 | |
| 975 | +weapon* ObjectManager::GetWeaponList() | |
| 976 | +{ | |
| 977 | + return WeaponIndex; | |
| 978 | +} | |
| 979 | + | |
| 980 | +//! smallobjectクラスを取得 | |
| 981 | +//! @deprecated この関数で各オブジェクトを直接呼び出すことは避け、このクラスの各種メンバー関数を使用してください。この関数は将来的に削除されます。 | |
| 982 | +smallobject* ObjectManager::GetSmallObjectList() | |
| 983 | +{ | |
| 984 | + return SmallObjectIndex; | |
| 985 | +} | |
| 986 | + | |
| 987 | +//! bulletクラスを取得 | |
| 988 | +//! @deprecated この関数で各オブジェクトを直接呼び出すことは避け、このクラスの各種メンバー関数を使用してください。この関数は将来的に削除されます。 | |
| 989 | +bullet* ObjectManager::GetBulletList() | |
| 990 | +{ | |
| 991 | + return BulletIndex; | |
| 992 | +} | |
| 993 | + | |
| 994 | +//! プレイヤー番号を取得 | |
| 995 | +//! @return プレイヤーのデータ番号 | |
| 996 | +int ObjectManager::GetPlayerID() | |
| 997 | +{ | |
| 998 | + return Player_HumanID; | |
| 999 | +} | |
| 1000 | + | |
| 1001 | +//! プレイヤー番号を設定 | |
| 1002 | +//! @param id プレイヤーのデータ番号 | |
| 1003 | +void ObjectManager::SetPlayerID(int id) | |
| 1004 | +{ | |
| 1005 | + Player_HumanID = id; | |
| 1006 | +} | |
| 1007 | + | |
| 1008 | +//! 指定したデータ番号のhumanクラスを取得 | |
| 1009 | +//! @param id データ番号 | |
| 1010 | +//! @return 人オブジェクトのポインタ (無効なデータ番号で NULL) | |
| 1011 | +human* ObjectManager::GeHumanObject(int id) | |
| 1012 | +{ | |
| 1013 | + if( (id < 0)||(MAX_HUMAN-1 < id) ){ return NULL; } | |
| 1014 | + return &(HumanIndex[id]); | |
| 1015 | +} | |
| 1016 | + | |
| 1017 | +//! プレイヤーのhumanクラスを取得 | |
| 1018 | +//! @return 人オブジェクト(プレイヤー)のポインタ | |
| 1019 | +human* ObjectManager::GetPlayerHumanObject() | |
| 1020 | +{ | |
| 1021 | + return GeHumanObject(Player_HumanID); | |
| 1022 | +} | |
| 1023 | + | |
| 1024 | +//! 指定したデータ番号のweaponクラスを取得 | |
| 1025 | +//! @param id データ番号 | |
| 1026 | +//! @return 武器オブジェクトのポインタ (無効なデータ番号で NULL) | |
| 1027 | +weapon* ObjectManager::GeWeaponObject(int id) | |
| 1028 | +{ | |
| 1029 | + if( (id < 0)||(MAX_WEAPON-1 < id) ){ return NULL; } | |
| 1030 | + return &(WeaponIndex[id]); | |
| 1031 | +} | |
| 1032 | + | |
| 1033 | +//! 指定したデータ番号のbulletクラスを取得 | |
| 1034 | +//! @param id データ番号 | |
| 1035 | +//! @return 弾オブジェクトのポインタ (無効なデータ番号で NULL) | |
| 1036 | +bullet* ObjectManager::GeBulletObject(int id) | |
| 1037 | +{ | |
| 1038 | + if( (id < 0)||(MAX_BULLET-1 < id) ){ return NULL; } | |
| 1039 | + return &(BulletIndex[id]); | |
| 1040 | +} | |
| 1041 | + | |
| 1042 | +//! 使用されていないbulletクラスを取得 | |
| 1043 | +//! @return 現在未使用の弾オブジェクトのポインタ (失敗すると NULL) | |
| 1044 | +bullet* ObjectManager::GetNewBulletObject() | |
| 1045 | +{ | |
| 1046 | + for(int i=0; i<MAX_BULLET; i++){ | |
| 1047 | + if( BulletIndex[i].GetDrawFlag() == false ){ | |
| 1048 | + return &(BulletIndex[i]); | |
| 1049 | + } | |
| 1050 | + } | |
| 1051 | + return NULL; | |
| 1052 | +} | |
| 1053 | + | |
| 1054 | +//! 使用されていないgrenadeクラスを取得 | |
| 1055 | +//! @return 現在未使用の手榴弾オブジェクトのポインタ (失敗すると NULL) | |
| 1056 | +grenade* ObjectManager::GetNewGrenadeObject() | |
| 1057 | +{ | |
| 1058 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 1059 | + if( GrenadeIndex[i].GetDrawFlag() == false ){ | |
| 1060 | + return &(GrenadeIndex[i]); | |
| 1061 | + } | |
| 1062 | + } | |
| 1063 | + return NULL; | |
| 1064 | +} | |
| 1065 | + | |
| 1066 | +//! 人を検索 | |
| 1067 | +//! @param p4 検索対象の認識番号 | |
| 1068 | +//! @return 該当したhumanクラスのポインタ (見つからない場合はNULL) | |
| 1069 | +//! @attention 複数該当する場合、最初に該当したデータを返します。 | |
| 1070 | +human* ObjectManager::SearchHuman(signed char p4) | |
| 1071 | +{ | |
| 1072 | + signed char humanp4; | |
| 1073 | + | |
| 1074 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1075 | + //使われていない人ならば処理しない | |
| 1076 | + if( HumanIndex[i].GetDrawFlag() == false ){ continue; } | |
| 1077 | + | |
| 1078 | + //第4パラメータを取得 | |
| 1079 | + HumanIndex[i].GetParamData(NULL, NULL, &humanp4, NULL); | |
| 1080 | + | |
| 1081 | + //指定されたp4と一致すれば返す | |
| 1082 | + if( humanp4 == p4 ){ | |
| 1083 | + return &(HumanIndex[i]); | |
| 1084 | + } | |
| 1085 | + } | |
| 1086 | + return NULL; | |
| 1087 | +} | |
| 1088 | + | |
| 1089 | +//! 小物を検索 | |
| 1090 | +//! @param p4 検索対象の認識番号 | |
| 1091 | +//! @return 該当したsmallobjectクラスのポインタ (見つからない場合はNULL) | |
| 1092 | +//! @attention 複数該当する場合、最初に該当したデータを返します。 | |
| 1093 | +smallobject* ObjectManager::SearchSmallobject(signed char p4) | |
| 1094 | +{ | |
| 1095 | + signed char smallobjectp4; | |
| 1096 | + | |
| 1097 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 1098 | + //使われていない人ならば処理しない | |
| 1099 | + // 【破壊積みのオブジェクトも判定するため、無効】 | |
| 1100 | + //if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; } | |
| 1101 | + | |
| 1102 | + //第4パラメータを取得 | |
| 1103 | + SmallObjectIndex[i].GetParamData(NULL, &smallobjectp4); | |
| 1104 | + | |
| 1105 | + //指定されたp4と一致すれば返す | |
| 1106 | + if( smallobjectp4 == p4 ){ | |
| 1107 | + return &(SmallObjectIndex[i]); | |
| 1108 | + } | |
| 1109 | + } | |
| 1110 | + return NULL; | |
| 1111 | +} | |
| 1112 | + | |
| 1113 | +//! 発砲 | |
| 1114 | +//! @param MyHuman 発砲する人 | |
| 1115 | +//! @return 通常弾発射:1 手榴弾発射:2 失敗:0 | |
| 1116 | +int ObjectManager::ShotWeapon(human *MyHuman) | |
| 1117 | +{ | |
| 1118 | + //オブジェクトのポインタから、データ番号を取得 | |
| 1119 | + int humanid; | |
| 1120 | + for(humanid=0; humanid<MAX_HUMAN; humanid++){ | |
| 1121 | + if( &(HumanIndex[humanid]) == MyHuman ){ break; } | |
| 1122 | + } | |
| 1123 | + if( humanid == MAX_HUMAN ){ return 0; } //見つからなければ「失敗」として返す | |
| 1124 | + | |
| 1125 | + float pos_x, pos_y, pos_z; | |
| 1126 | + int teamid; | |
| 1127 | + float rotation_x, armrotation_y; | |
| 1128 | + int weapon_paramid; | |
| 1129 | + int GunsightErrorRange; | |
| 1130 | + WeaponParameter ParamData; | |
| 1131 | + bool playerflag; | |
| 1132 | + bool grenadeflag; | |
| 1133 | + | |
| 1134 | + //人の座標と角度を取得 | |
| 1135 | + MyHuman->GetPosData(&pos_x, &pos_y, &pos_z, NULL); | |
| 1136 | + MyHuman->GetParamData(NULL, NULL, NULL, &teamid); | |
| 1137 | + MyHuman->GetRxRy(&rotation_x, &armrotation_y); | |
| 1138 | + | |
| 1139 | + //対象者がプレイヤー自身か判定 | |
| 1140 | + if( MyHuman == &(HumanIndex[Player_HumanID]) ){ | |
| 1141 | + playerflag = true; | |
| 1142 | + } | |
| 1143 | + else{ | |
| 1144 | + playerflag = false; | |
| 1145 | + } | |
| 1146 | + | |
| 1147 | + //弾の発射を要求 | |
| 1148 | + if( MyHuman->ShotWeapon(&weapon_paramid, &GunsightErrorRange) == false ){ return 0; } | |
| 1149 | + | |
| 1150 | + //武器の情報を取得 | |
| 1151 | + if( GameParamInfo->GetWeapon(weapon_paramid, &ParamData) != 0 ){ return 0; } | |
| 1152 | + | |
| 1153 | + //誤差の範囲を計算 | |
| 1154 | + int ErrorRange; | |
| 1155 | + ErrorRange = GunsightErrorRange; | |
| 1156 | + if( ErrorRange < ParamData.ErrorRangeMIN ){ ErrorRange = ParamData.ErrorRangeMIN; } | |
| 1157 | + | |
| 1158 | + //手榴弾か判定 | |
| 1159 | + if( weapon_paramid == ID_WEAPON_GRENADE ){ grenadeflag = true; } | |
| 1160 | + else{ grenadeflag = false; } | |
| 1161 | + | |
| 1162 | + class bullet* newbullet; | |
| 1163 | + class grenade* newgrenade; | |
| 1164 | + | |
| 1165 | + //(ショットガンなど)発射する弾の数分繰り返す | |
| 1166 | + for(int i=0; i<ParamData.burst; i++){ | |
| 1167 | + //発射する未使用のオブジェクトを取得 | |
| 1168 | + if( grenadeflag == false ){ | |
| 1169 | + newbullet = GetNewBulletObject(); | |
| 1170 | + if( newbullet == NULL ){ break; } | |
| 1171 | + | |
| 1172 | + //番号を取得 | |
| 1173 | + int index; | |
| 1174 | + for(index=0; index<MAX_BULLET; index++){ | |
| 1175 | + if( &BulletIndex[index] == newbullet ){ break; } | |
| 1176 | + } | |
| 1177 | + } | |
| 1178 | + else{ | |
| 1179 | + newgrenade = GetNewGrenadeObject(); | |
| 1180 | + if( newgrenade == NULL ){ break; } | |
| 1181 | + } | |
| 1182 | + | |
| 1183 | + //発射角度を決定 | |
| 1184 | + float rx, ry; | |
| 1185 | + rx = rotation_x*-1 + (float)M_PI/2; | |
| 1186 | + ry = armrotation_y; | |
| 1187 | + | |
| 1188 | + //誤差分 加算する | |
| 1189 | + float a; | |
| 1190 | + a = (float)M_PI/180 * GetRand(360); | |
| 1191 | + rx += cos(a)*ErrorRange * ((float)M_PI/180*0.15f); | |
| 1192 | + ry += sin(a)*ErrorRange * ((float)M_PI/180*0.15f); | |
| 1193 | + | |
| 1194 | + //手榴弾でなければ | |
| 1195 | + if( grenadeflag == false ){ | |
| 1196 | + int attacks; | |
| 1197 | + | |
| 1198 | + //(ショットガンなど)発射する弾が複数あれば | |
| 1199 | + if( ParamData.burst > 1 ){ | |
| 1200 | + //1個の弾当たりの攻撃力を算出 | |
| 1201 | + // 全弾合わせて、攻撃力の2倍になるようにする。 | |
| 1202 | + attacks = (int)( (float)ParamData.attacks / ((float)ParamData.burst/2) ); | |
| 1203 | + } | |
| 1204 | + else{ | |
| 1205 | + //そのまま攻撃力へ反映 | |
| 1206 | + attacks = ParamData.attacks; | |
| 1207 | + } | |
| 1208 | + | |
| 1209 | + //銃弾を発射 | |
| 1210 | + newbullet->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry); | |
| 1211 | + newbullet->SetParamData(attacks, ParamData.penetration, ParamData.speed * BULLET_SPEEDSCALE, teamid, humanid, true); | |
| 1212 | + newbullet->SetDrawFlag(true); | |
| 1213 | + } | |
| 1214 | + else{ | |
| 1215 | + //手榴弾発射 | |
| 1216 | + newgrenade->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry); | |
| 1217 | + newgrenade->SetParamData(8.0f, humanid, true); | |
| 1218 | + newgrenade->SetDrawFlag(true); | |
| 1219 | + } | |
| 1220 | + | |
| 1221 | + //誤差を加算(ショットガン用) | |
| 1222 | + ErrorRange += ParamData.ErrorRangeMIN; | |
| 1223 | + } | |
| 1224 | + | |
| 1225 | + //手榴弾でなければ | |
| 1226 | + if( grenadeflag == false ){ | |
| 1227 | + float x, y, z; | |
| 1228 | + | |
| 1229 | + //マズルフラッシュと煙のサイズを決定 | |
| 1230 | + float flashsize = 3.0f; | |
| 1231 | + if( ParamData.silencer == true ){ | |
| 1232 | + flashsize = 1.0f; | |
| 1233 | + } | |
| 1234 | + | |
| 1235 | + //行列でエフェクト座標を計算 | |
| 1236 | + d3dg->SetWorldTransformHumanWeapon(pos_x, pos_y + 16.0f, pos_z, ParamData.flashx/10, ParamData.flashy/10, ParamData.flashz/10, rotation_x, armrotation_y*-1, 1.0f); | |
| 1237 | + d3dg->GetWorldTransformPos(&x, &y, &z); | |
| 1238 | + d3dg->ResetWorldTransform(); | |
| 1239 | + | |
| 1240 | + //マズルフラッシュ描画 | |
| 1241 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1242 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 1243 | + //エフェクト設定 | |
| 1244 | + EffectIndex[i].SetPosData(x, y, z, 0.0f); | |
| 1245 | + EffectIndex[i].SetParamData(flashsize, (float)M_PI/18*GetRand(18), 1, Resource->GetEffectMflashTexture(), EFFECT_NORMAL, true); | |
| 1246 | + EffectIndex[i].SetDrawFlag(true); | |
| 1247 | + break; | |
| 1248 | + } | |
| 1249 | + } | |
| 1250 | + | |
| 1251 | + //エフェクト(煙)の表示 | |
| 1252 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1253 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 1254 | + //エフェクト設定 | |
| 1255 | + EffectIndex[i].SetPosData(x, y, z, 0.0f); | |
| 1256 | + EffectIndex[i].SetParamData(flashsize, (float)M_PI/18*GetRand(18), (int)(GAMEFPS/3), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION, true); | |
| 1257 | + EffectIndex[i].SetDrawFlag(true); | |
| 1258 | + break; | |
| 1259 | + } | |
| 1260 | + } | |
| 1261 | + | |
| 1262 | + //行列でエフェクト座標を計算 | |
| 1263 | + d3dg->SetWorldTransformHumanWeapon(pos_x, pos_y + 16.0f, pos_z, ParamData.yakkyou_px/10, ParamData.yakkyou_py/10, ParamData.yakkyou_pz/10, rotation_x, armrotation_y*-1, 1.0f); | |
| 1264 | + d3dg->GetWorldTransformPos(&x, &y, &z); | |
| 1265 | + d3dg->ResetWorldTransform(); | |
| 1266 | + | |
| 1267 | + //薬莢描画 | |
| 1268 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1269 | + if( EffectIndex[i].GetDrawFlag() == false ){ | |
| 1270 | + //エフェクト設定 | |
| 1271 | + EffectIndex[i].SetPosData(x, y, z, 0.0f); | |
| 1272 | + EffectIndex[i].SetParamData(/*3.0f*/2.0f, (float)M_PI/18*GetRand(18), (int)(GAMEFPS/2), Resource->GetEffectYakkyouTexture(), EFFECT_ROTATION | EFFECT_FALL, true); | |
| 1273 | + EffectIndex[i].SetDrawFlag(true); | |
| 1274 | + break; | |
| 1275 | + } | |
| 1276 | + } | |
| 1277 | + } | |
| 1278 | + | |
| 1279 | + if( ParamData.soundvolume > 0 ){ | |
| 1280 | + //銃声を再生 | |
| 1281 | + GameSound->ShotWeapon(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, weapon_paramid, teamid, playerflag); | |
| 1282 | + } | |
| 1283 | + | |
| 1284 | + if( grenadeflag == true ){ | |
| 1285 | + return 2; | |
| 1286 | + } | |
| 1287 | + return 1; | |
| 1288 | +} | |
| 1289 | + | |
| 1290 | +//! 武器をリロード | |
| 1291 | +//! @param in_human 対象の人オブジェクト | |
| 1292 | +void ObjectManager::ReloadWeapon(human *in_human) | |
| 1293 | +{ | |
| 1294 | + //無効な人ならば処理しない | |
| 1295 | + if( in_human->GetDrawFlag() == false ){ return; } | |
| 1296 | + if( in_human->GetHP() <= 0 ){ return; } | |
| 1297 | + | |
| 1298 | + //リロードを実行 | |
| 1299 | + if( in_human->ReloadWeapon() == true ){ | |
| 1300 | + float x, y, z; | |
| 1301 | + int id; | |
| 1302 | + | |
| 1303 | + //人の座標とチーム番号を取得 | |
| 1304 | + in_human->GetPosData(&x, &y, &z, NULL); | |
| 1305 | + in_human->GetParamData(NULL, NULL, NULL, &id); | |
| 1306 | + y += 16.0f; | |
| 1307 | + | |
| 1308 | + //音源を配置 | |
| 1309 | + GameSound->ReloadWeapon(x, y, z, id); | |
| 1310 | + } | |
| 1311 | +} | |
| 1312 | + | |
| 1313 | +//! ゾンビの攻撃を受けるか判定 | |
| 1314 | +//! @param MyHuman 攻撃する人オブジェクト(ゾンビ側)のポインタ | |
| 1315 | +//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ | |
| 1316 | +//! @return 成立:true 不成立:false | |
| 1317 | +//! @warning MyHuman はゾンビ以外も指定できます。<b>ゾンビかどうかは判定しない</b>ため、ゾンビであるか予め確認しておく必要があります。 | |
| 1318 | +//! @attention 判定のみを実施します。この判定が成立したら HitZombieAttack()関数 を呼び出してください。 | |
| 1319 | +bool ObjectManager::CheckZombieAttack(human* MyHuman, human* EnemyHuman) | |
| 1320 | +{ | |
| 1321 | + if( MyHuman == NULL ){ return false; } | |
| 1322 | + if( EnemyHuman == NULL ){ return false; } | |
| 1323 | + | |
| 1324 | + //使用されていないか、死亡していれば処理しない。 | |
| 1325 | + if( MyHuman->GetDrawFlag() == false ){ return false; } | |
| 1326 | + if( MyHuman->GetHP() <= 0 ){ return false; } | |
| 1327 | + if( EnemyHuman->GetDrawFlag() == false ){ return false; } | |
| 1328 | + if( EnemyHuman->GetHP() <= 0 ){ return false; } | |
| 1329 | + | |
| 1330 | + float mx, my, mz, mrx, tx, ty, tz; | |
| 1331 | + int mteam, tteam; | |
| 1332 | + float AttackPoint_x, AttackPoint_y, AttackPoint_z; | |
| 1333 | + float ax, az; | |
| 1334 | + | |
| 1335 | + MyHuman->GetPosData(&mx, &my, &mz, &mrx); | |
| 1336 | + MyHuman->GetParamData(NULL, NULL, NULL, &mteam); | |
| 1337 | + my += VIEW_HEIGHT; | |
| 1338 | + EnemyHuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 1339 | + EnemyHuman->GetParamData(NULL, NULL, NULL, &tteam); | |
| 1340 | + ty += VIEW_HEIGHT; | |
| 1341 | + | |
| 1342 | + //味方ならば処理しない | |
| 1343 | + if( mteam == tteam ){ return false; } | |
| 1344 | + | |
| 1345 | + //攻撃ポイント(腕の先端)を求める | |
| 1346 | + AttackPoint_x = mx + cos(mrx*-1 + (float)M_PI/2) * 2.0f; | |
| 1347 | + AttackPoint_y = my + VIEW_HEIGHT - 0.5f; | |
| 1348 | + AttackPoint_z = mz + sin(mrx*-1 + (float)M_PI/2) * 2.0f; | |
| 1349 | + ax = AttackPoint_x - tx; | |
| 1350 | + az = AttackPoint_z - tz; | |
| 1351 | + | |
| 1352 | + //敵(攻撃対象)が攻撃ポイントに触れていれば、当たっている | |
| 1353 | + if( (ax*ax + az*az) < 3.3f*3.3f ){ | |
| 1354 | + if( (AttackPoint_y >= ty)&&(AttackPoint_y <= (ty + HUMAN_HEIGTH)) ){ | |
| 1355 | + return true; | |
| 1356 | + } | |
| 1357 | + } | |
| 1358 | + | |
| 1359 | + return false; | |
| 1360 | +} | |
| 1361 | + | |
| 1362 | +//! ゾンビの攻撃を受けた処理 | |
| 1363 | +//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ | |
| 1364 | +void ObjectManager::HitZombieAttack(human* EnemyHuman) | |
| 1365 | +{ | |
| 1366 | + if( EnemyHuman == NULL ){ return; } | |
| 1367 | + | |
| 1368 | + //使用されていないか、死亡していれば処理しない。 | |
| 1369 | + if( EnemyHuman->GetDrawFlag() == false ){ return; } | |
| 1370 | + if( EnemyHuman->GetHP() <= 0 ){ return; } | |
| 1371 | + | |
| 1372 | + float tx, ty, tz; | |
| 1373 | + | |
| 1374 | + EnemyHuman->GetPosData(&tx, &ty, &tz, NULL); | |
| 1375 | + ty += VIEW_HEIGHT; | |
| 1376 | + | |
| 1377 | + //ダメージなどを計算 | |
| 1378 | + EnemyHuman->HitZombieAttack(); | |
| 1379 | + | |
| 1380 | + //エフェクト(血)を表示 | |
| 1381 | + SetHumanBlood(tx, ty, tz); | |
| 1382 | + | |
| 1383 | + //効果音を再生 | |
| 1384 | + GameSound->HitHuman(tx, ty, tz); | |
| 1385 | +} | |
| 1386 | + | |
| 1387 | +//! ゲームクリアー・ゲームオーバーの判定 | |
| 1388 | +//! @return ゲームクリアー:1 ゲームオーバー:2 判定なし:0 | |
| 1389 | +//! @attention ゲームクリア―とゲームオーバーが同時に成立する条件では、本家XOPSと同様に「ゲームクリアー」と判定されます。 | |
| 1390 | +int ObjectManager::CheckGameOverorComplete() | |
| 1391 | +{ | |
| 1392 | + //メモ: | |
| 1393 | + // | |
| 1394 | + // 本来は、ゲームオーバー判定を先に行い、次にゲームクリアー判定を実装した方が効率的です。 | |
| 1395 | + // プレイヤーのHPが 0 ならば即ゲームオーバーとして判定し、敵の中でHPが残っている者を見つけた時点で 判定なし、 | |
| 1396 | + // 2つの条件に当てはまらなければ、自動的にゲームクリアーとなります。 | |
| 1397 | + // | |
| 1398 | + // しかし、本家XOPSはゲームクリアーの判定を優先するため、先にゲームクリアーの判定を行っています。 | |
| 1399 | + // 生きている敵の数を(総HPとして)数え、敵の数(総HP)が 0 ならば、ゲームクリアーと判定します。 | |
| 1400 | + // まぁこのように1つの関数で処理しようとせずに、ゲームクリアーとゲームオーバーで関数自体を分けても良いのですがね・・。 | |
| 1401 | + | |
| 1402 | + //ゲームクリアー判定 | |
| 1403 | + int MyTeamid, teamid; | |
| 1404 | + int TotalEnemyHP = 0; | |
| 1405 | + HumanIndex[Player_HumanID].GetParamData(NULL, NULL, NULL, &MyTeamid); //プレイヤーのチーム番号を取得 | |
| 1406 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1407 | + //初期化されていなければ処理しない | |
| 1408 | + if( HumanIndex[i].GetDrawFlag() == false ){ continue; } | |
| 1409 | + | |
| 1410 | + //調べる対象のチーム番号を取得 | |
| 1411 | + HumanIndex[i].GetParamData(NULL, NULL, NULL, &teamid); | |
| 1412 | + | |
| 1413 | + //異なるチーム番号(=敵)ならば | |
| 1414 | + if( teamid != MyTeamid ){ | |
| 1415 | + //生きていれば、敵のHPとして加算 | |
| 1416 | + //if( HumanIndex[i].GetHP() > 0 ){ | |
| 1417 | + if( HumanIndex[i].GetDeadFlag() == false ){ | |
| 1418 | + TotalEnemyHP += HumanIndex[i].GetHP(); | |
| 1419 | + } | |
| 1420 | + } | |
| 1421 | + } | |
| 1422 | + if( TotalEnemyHP == 0 ){ //全敵のHPが 0 ならば | |
| 1423 | + return 1; | |
| 1424 | + } | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + //ゲームオーバー判定 | |
| 1428 | + if( HumanIndex[Player_HumanID].GetDrawFlag() == true ){ //操作対象が有効ならば (注:裏技による変更対策) | |
| 1429 | + if( HumanIndex[Player_HumanID].GetDeadFlag() == true ){ //プレイヤーが死亡していれば | |
| 1430 | + return 2; | |
| 1431 | + } | |
| 1432 | + } | |
| 1433 | + | |
| 1434 | + return 0; | |
| 1435 | +} | |
| 1436 | + | |
| 1437 | +//! オブジェクトの主計算処理 | |
| 1438 | +//! @param cmdF5id 上昇機能(F5裏技)させる人データ番号(-1で機能無効) | |
| 1439 | +//! @param camera_x カメラのX座標 | |
| 1440 | +//! @param camera_y カメラのY座標 | |
| 1441 | +//! @param camera_z カメラのZ座標 | |
| 1442 | +//! @param camera_rx カメラの横軸角度 | |
| 1443 | +//! @param camera_ry カメラの縦軸角度 | |
| 1444 | +//! @return 常に 0 | |
| 1445 | +//! @attention 一般的に cmdF5id は、F5裏技使用中はプレイヤー番号(GetPlayerID()関数で取得)、未使用時は -1 を指定します。 | |
| 1446 | +int ObjectManager::Process(int cmdF5id, float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry) | |
| 1447 | +{ | |
| 1448 | + //このフレームの戦歴を初期化 | |
| 1449 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1450 | + Human_ontarget[i] = 0; | |
| 1451 | + Human_kill[i] = 0; | |
| 1452 | + Human_headshot[i] = 0; | |
| 1453 | + } | |
| 1454 | + | |
| 1455 | + //人オブジェクトの処理 | |
| 1456 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1457 | + //走る足音 | |
| 1458 | + if( HumanIndex[i].GetMovemode(true) == 2 ){ | |
| 1459 | + float posx, posy, posz; | |
| 1460 | + int teamid; | |
| 1461 | + HumanIndex[i].GetPosData(&posx, &posy, &posz, NULL); | |
| 1462 | + HumanIndex[i].GetParamData(NULL, NULL, NULL, &teamid); | |
| 1463 | + GameSound->SetFootsteps(posx, posy, posz, teamid); | |
| 1464 | + } | |
| 1465 | + | |
| 1466 | + if( i == cmdF5id ){ | |
| 1467 | + HumanIndex[i].RunFrame(CollD, BlockData, true); | |
| 1468 | + } | |
| 1469 | + else{ | |
| 1470 | + HumanIndex[i].RunFrame(CollD, BlockData, false); | |
| 1471 | + } | |
| 1472 | + } | |
| 1473 | + | |
| 1474 | + //武器オブジェクトの処理 | |
| 1475 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 1476 | + WeaponIndex[i].RunFrame(CollD); | |
| 1477 | + } | |
| 1478 | + | |
| 1479 | + //小物オブジェクトの処理 | |
| 1480 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 1481 | + SmallObjectIndex[i].RunFrame(); | |
| 1482 | + } | |
| 1483 | + | |
| 1484 | + //弾オブジェクトの処理 | |
| 1485 | + for(int i=0; i<MAX_BULLET; i++){ | |
| 1486 | + float bx, by, bz, brx, bry; | |
| 1487 | + int speed; | |
| 1488 | + float mx, my, mz; | |
| 1489 | + | |
| 1490 | + CollideBullet(&BulletIndex[i]); //当たり判定を実行 | |
| 1491 | + BulletIndex[i].RunFrame(); //主計算 | |
| 1492 | + | |
| 1493 | + if( BulletIndex[i].GetDrawFlag() == true ){ | |
| 1494 | + //弾の座標と角度を取得 | |
| 1495 | + BulletIndex[i].GetParamData(NULL, NULL, &speed, NULL, NULL); | |
| 1496 | + BulletIndex[i].GetPosData(&bx, &by, &bz, &brx, &bry); | |
| 1497 | + mx = cos(brx)*cos(bry)*speed; | |
| 1498 | + my = sin(bry)*speed; | |
| 1499 | + mz = sin(brx)*cos(bry)*speed; | |
| 1500 | + GameSound->PassingBullet(bx, by, bz, mx, my, mz); | |
| 1501 | + } | |
| 1502 | + } | |
| 1503 | + | |
| 1504 | + //エフェクトオブジェクトの処理 | |
| 1505 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1506 | + EffectIndex[i].RunFrame(camera_rx, camera_ry); | |
| 1507 | + } | |
| 1508 | + | |
| 1509 | + //手榴弾の処理 | |
| 1510 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 1511 | + //主計算 | |
| 1512 | + int rcr = GrenadeIndex[i].RunFrame(CollD, BlockData); | |
| 1513 | + | |
| 1514 | + //バウンド・跳ね返ったならば | |
| 1515 | + if( rcr == 1 ){ | |
| 1516 | + //座標を取得し、効果音再生 | |
| 1517 | + float x, y, z; | |
| 1518 | + GrenadeIndex[i].GetPosData(&x, &y, &z, NULL, NULL); | |
| 1519 | + GameSound->GrenadeBound(x, y, z); | |
| 1520 | + } | |
| 1521 | + | |
| 1522 | + //爆発したなら | |
| 1523 | + if( rcr == 2 ){ | |
| 1524 | + //座標を取得 | |
| 1525 | + float x, y, z; | |
| 1526 | + int humanid; | |
| 1527 | + GrenadeIndex[i].GetPosData(&x, &y, &z, NULL, NULL); | |
| 1528 | + GrenadeIndex[i].GetParamData(NULL, NULL, NULL, NULL, &humanid); | |
| 1529 | + | |
| 1530 | + //エフェクト(フラッシュ)の表示 | |
| 1531 | + for(int j=0; j<MAX_EFFECT; j++){ | |
| 1532 | + if( EffectIndex[j].GetDrawFlag() == false ){ | |
| 1533 | + EffectIndex[j].SetPosData(x, y, z, 0.0f); | |
| 1534 | + EffectIndex[j].SetParamData(30.0f, 0.0f, 2, Resource->GetEffectMflashTexture(), EFFECT_NORMAL, true); | |
| 1535 | + EffectIndex[j].SetDrawFlag(true); | |
| 1536 | + break; | |
| 1537 | + } | |
| 1538 | + } | |
| 1539 | + | |
| 1540 | + //エフェクト(煙)の表示 | |
| 1541 | + float rnd = (float)M_PI/18*GetRand(18); | |
| 1542 | + for(int j=0; j<MAX_EFFECT; j++){ | |
| 1543 | + if( EffectIndex[j].GetDrawFlag() == false ){ | |
| 1544 | + EffectIndex[j].SetPosData(x+1.0f, y+1.0f, z+1.0f, 0.0f); | |
| 1545 | + EffectIndex[j].SetParamData(10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION, true); | |
| 1546 | + EffectIndex[j].SetDrawFlag(true); | |
| 1547 | + break; | |
| 1548 | + } | |
| 1549 | + } | |
| 1550 | + for(int j=0; j<MAX_EFFECT; j++){ | |
| 1551 | + if( EffectIndex[j].GetDrawFlag() == false ){ | |
| 1552 | + EffectIndex[j].SetPosData(x-1.0f, y-1.0f, z-1.0f, 0.0f); | |
| 1553 | + EffectIndex[j].SetParamData(10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION, true); | |
| 1554 | + EffectIndex[j].SetDrawFlag(true); | |
| 1555 | + break; | |
| 1556 | + } | |
| 1557 | + } | |
| 1558 | + for(int j=0; j<MAX_EFFECT; j++){ | |
| 1559 | + if( EffectIndex[j].GetDrawFlag() == false ){ | |
| 1560 | + EffectIndex[j].SetPosData(x-1.0f, y-1.0f, z+1.0f, 0.0f); | |
| 1561 | + EffectIndex[j].SetParamData(10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION, true); | |
| 1562 | + EffectIndex[j].SetDrawFlag(true); | |
| 1563 | + break; | |
| 1564 | + } | |
| 1565 | + } | |
| 1566 | + for(int j=0; j<MAX_EFFECT; j++){ | |
| 1567 | + if( EffectIndex[j].GetDrawFlag() == false ){ | |
| 1568 | + EffectIndex[j].SetPosData(x+1.0f, y+1.0f, z-1.0f, 0.0f); | |
| 1569 | + EffectIndex[j].SetParamData(10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION, true); | |
| 1570 | + EffectIndex[j].SetDrawFlag(true); | |
| 1571 | + break; | |
| 1572 | + } | |
| 1573 | + } | |
| 1574 | + | |
| 1575 | + //効果音を再生 | |
| 1576 | + GameSound->GrenadeExplosion(x, y, z); | |
| 1577 | + | |
| 1578 | + //人に爆風の当たり判定 | |
| 1579 | + for(int j=0; j<MAX_HUMAN; j++){ | |
| 1580 | + if( HumanIndex[j].GrenadeExplosion(CollD, &(GrenadeIndex[i])) ){ | |
| 1581 | + float x, y, z; | |
| 1582 | + | |
| 1583 | + //倒していれば、発射した人の成果に加算 | |
| 1584 | + if( HumanIndex[j].GetHP() <= 0 ){ | |
| 1585 | + Human_kill[humanid] += 1; | |
| 1586 | + } | |
| 1587 | + | |
| 1588 | + //エフェクト(血)を表示 | |
| 1589 | + HumanIndex[j].GetPosData(&x, &y, &z, NULL); | |
| 1590 | + SetHumanBlood(x, y+15.0f, z); | |
| 1591 | + } | |
| 1592 | + } | |
| 1593 | + | |
| 1594 | + //小物に爆風の当たり判定 | |
| 1595 | + for(int j=0; j<MAX_SMALLOBJECT; j++){ | |
| 1596 | + //もし爆風に当たったら | |
| 1597 | + if( SmallObjectIndex[j].GrenadeExplosion(CollD, &(GrenadeIndex[i])) ){ | |
| 1598 | + //小物から効果音を発する | |
| 1599 | + float sx, sy, sz; | |
| 1600 | + int id; | |
| 1601 | + SmallObjectIndex[j].GetPosData(&sx, &sy, &sz, NULL); | |
| 1602 | + SmallObjectIndex[j].GetParamData(&id, NULL); | |
| 1603 | + GameSound->HitSmallObject(sx, sy, sz, id); | |
| 1604 | + } | |
| 1605 | + } | |
| 1606 | + } | |
| 1607 | + } | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + //武器を拾う処理 | |
| 1611 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1612 | + //武器を拾うだけで毎フレーム総当たりで処理する意味はないので、各武器2フレームに1回処理にケチってます (^^; | |
| 1613 | + //フレーム数が偶数目の時は、データ番号が偶数の武器。奇数の時は、奇数の武器を処理。 | |
| 1614 | + for(int j=(framecnt%2); j<MAX_WEAPON; j+=2){ | |
| 1615 | + PickupWeapon(&HumanIndex[i], &WeaponIndex[j]); | |
| 1616 | + } | |
| 1617 | + } | |
| 1618 | + | |
| 1619 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1620 | + for(int j=i+1; j<MAX_HUMAN; j++){ | |
| 1621 | + //人同士の当たり判定(押し合い) | |
| 1622 | + CollideHuman(&HumanIndex[i], &HumanIndex[j]); | |
| 1623 | + } | |
| 1624 | + } | |
| 1625 | + | |
| 1626 | + framecnt += 1; | |
| 1627 | + | |
| 1628 | + return 0; | |
| 1629 | +} | |
| 1630 | + | |
| 1631 | +//! 現フレームの 命中率・倒した敵の数・ヘットショット数 の取得 | |
| 1632 | +//! @param id 取得する人のデータ番号 | |
| 1633 | +//! @param ontarget 命中数を受け取るポインタ | |
| 1634 | +//! @param kill 倒した敵の数を受け取るポインタ | |
| 1635 | +//! @param headshot 敵の頭部に命中した数を受け取るポインタ | |
| 1636 | +//! @return 成功:true 失敗:false | |
| 1637 | +bool ObjectManager::GetHumanShotInfo(int id, int *ontarget, int *kill, int *headshot) | |
| 1638 | +{ | |
| 1639 | + if( (id < 0)||(MAX_HUMAN-1 < id) ){ return false; } | |
| 1640 | + *ontarget = Human_ontarget[id]; | |
| 1641 | + *kill = Human_kill[id]; | |
| 1642 | + *headshot = Human_headshot[id]; | |
| 1643 | + return true; | |
| 1644 | +} | |
| 1645 | + | |
| 1646 | +//!エフェクトをソートする | |
| 1647 | +//! @param camera_x カメラのX座標 | |
| 1648 | +//! @param camera_y カメラのY座標 | |
| 1649 | +//! @param camera_z カメラのZ座標 | |
| 1650 | +//! @param data 結果を受け取る effectdata構造体 (要素数:MAX_EFFECT) | |
| 1651 | +//! @return 有効なエフェクトの数 | |
| 1652 | +int ObjectManager::SortEffect(float camera_x, float camera_y, float camera_z, effectdata data[]) | |
| 1653 | +{ | |
| 1654 | + int cnt = 0; | |
| 1655 | + | |
| 1656 | + //カメラからの距離を求めつつ、総数を数える。 | |
| 1657 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1658 | + if( EffectIndex[i].GetDrawFlag() == true ){ | |
| 1659 | + float ex, ey, ez; | |
| 1660 | + float x, y, z; | |
| 1661 | + | |
| 1662 | + //座標を取得し、距離を計算、データに登録。 | |
| 1663 | + EffectIndex[i].GetPosData(&ex, &ey, &ez, NULL); | |
| 1664 | + x = ex - camera_x; | |
| 1665 | + y = ey - camera_y; | |
| 1666 | + z = ez - camera_z; | |
| 1667 | + data[cnt].id = i; | |
| 1668 | + data[cnt].dist = x*x + y*y + z*z; | |
| 1669 | + | |
| 1670 | + //カウントを加算 | |
| 1671 | + cnt += 1; | |
| 1672 | + } | |
| 1673 | + } | |
| 1674 | + | |
| 1675 | + //単純挿入ソート | |
| 1676 | + effectdata temp; | |
| 1677 | + for(int i=1; i<cnt; i++) { | |
| 1678 | + int j; | |
| 1679 | + temp = data[i]; | |
| 1680 | + for(j=i; j>0 && data[j-1].dist<temp.dist; j--){ | |
| 1681 | + data[j] = data[j-1]; | |
| 1682 | + } | |
| 1683 | + data[j] = temp; | |
| 1684 | + } | |
| 1685 | + | |
| 1686 | + return cnt; | |
| 1687 | +} | |
| 1688 | + | |
| 1689 | +//! オブジェクトの描画処理 | |
| 1690 | +//! @param camera_x カメラのX座標 | |
| 1691 | +//! @param camera_y カメラのY座標 | |
| 1692 | +//! @param camera_z カメラのZ座標 | |
| 1693 | +//! @param HidePlayer プレイヤーの非表示設定 (表示:0 非表示:1 腕と武器のみ表示:2) | |
| 1694 | +void ObjectManager::Render(float camera_x, float camera_y, float camera_z, int HidePlayer) | |
| 1695 | +{ | |
| 1696 | + //ワールド座標を原点へ | |
| 1697 | + d3dg->ResetWorldTransform(); | |
| 1698 | + | |
| 1699 | + //人描画 | |
| 1700 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1701 | + if( HidePlayer == 0 ){ | |
| 1702 | + HumanIndex[i].Render(d3dg, Resource, false); | |
| 1703 | + } | |
| 1704 | + else if( Player_HumanID != i ){ // HidePlayer != 0 | |
| 1705 | + HumanIndex[i].Render(d3dg, Resource, false); | |
| 1706 | + } | |
| 1707 | + else if( HidePlayer == 2 ){ // Player_HumanID == i | |
| 1708 | + HumanIndex[i].Render(d3dg, Resource, true); | |
| 1709 | + } | |
| 1710 | + } | |
| 1711 | + | |
| 1712 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1713 | + if( (HidePlayer == false)||(Player_HumanID != i) ){ | |
| 1714 | + HumanIndex[i].Render(d3dg, Resource, true); | |
| 1715 | + } | |
| 1716 | + } | |
| 1717 | + | |
| 1718 | + //武器描画 | |
| 1719 | + for(int i=0; i<MAX_WEAPON; i++){ | |
| 1720 | + WeaponIndex[i].Render(d3dg); | |
| 1721 | + } | |
| 1722 | + | |
| 1723 | + //小物描画 | |
| 1724 | + for(int i=0; i<MAX_SMALLOBJECT; i++){ | |
| 1725 | + SmallObjectIndex[i].Render(d3dg); | |
| 1726 | + } | |
| 1727 | + | |
| 1728 | + //弾描画 | |
| 1729 | + for(int i=0; i<MAX_BULLET; i++){ | |
| 1730 | + BulletIndex[i].Render(d3dg); | |
| 1731 | + } | |
| 1732 | + | |
| 1733 | + //手榴弾描画 | |
| 1734 | + for(int i=0; i<MAX_GRENADE; i++){ | |
| 1735 | + GrenadeIndex[i].Render(d3dg); | |
| 1736 | + } | |
| 1737 | + | |
| 1738 | + //エフェクト描画 | |
| 1739 | + /* | |
| 1740 | + for(int i=0; i<MAX_EFFECT; i++){ | |
| 1741 | + EffectIndex[i].Render(d3dg); | |
| 1742 | + } | |
| 1743 | + */ | |
| 1744 | + effectdata data[MAX_EFFECT]; | |
| 1745 | + int cnt = SortEffect(camera_x, camera_y, camera_z, data); | |
| 1746 | + for(int i=0; i<cnt; i++) { | |
| 1747 | + EffectIndex[ data[i].id ].Render(d3dg); | |
| 1748 | + } | |
| 1749 | +} | |
| 1750 | + | |
| 1751 | +//! データの解放 | |
| 1752 | +void ObjectManager::Cleanup() | |
| 1753 | +{ | |
| 1754 | + //ポイントデータ解放 | |
| 1755 | + CleanupPointDataToObject(); | |
| 1756 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,103 @@ | ||
| 1 | +//! @file scene.h | |
| 2 | +//! @brief 各画面を管理するクラスの宣言 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef SCENE_H | |
| 33 | +#define SCENE_H | |
| 34 | + | |
| 35 | +//#include "main.h" | |
| 36 | +// ヘッダーファイル中の下で宣言する。 | |
| 37 | + | |
| 38 | +//! @brief 画面管理クラス(基底クラス) | |
| 39 | +//! @details ゲームの画面を管理する最も基底のクラスです。 | |
| 40 | +class scene | |
| 41 | +{ | |
| 42 | +protected: | |
| 43 | + class StateMachine *GameState; //!< ゲーム全体の状態遷移クラス | |
| 44 | + class D3DGraphics *d3dg; //!< 描画クラス | |
| 45 | + class InputControl *inputCtrl; //!< 入力取得クラス | |
| 46 | + unsigned int framecnt; //!< フレーム数のカウント | |
| 47 | + | |
| 48 | +public: | |
| 49 | + scene(); | |
| 50 | + ~scene(); | |
| 51 | + virtual void SetClass(StateMachine *in_GameState, D3DGraphics *in_d3dg, InputControl *in_inputCtrl); | |
| 52 | + virtual int Create(); | |
| 53 | + virtual void Input(); | |
| 54 | + virtual void Process(); | |
| 55 | + virtual void RenderMain(); | |
| 56 | + virtual void Destroy(); | |
| 57 | +}; | |
| 58 | + | |
| 59 | +//! @brief 2D画面管理クラス(基底クラス) | |
| 60 | +//! @details ゲーム画面の中で、2D描画のみを行うシーンを管理する基底のクラスです。 | |
| 61 | +class D2Dscene : public scene | |
| 62 | +{ | |
| 63 | +protected: | |
| 64 | + int gametitle; //!< ゲームタイトル画像 | |
| 65 | + virtual void Render2D(); | |
| 66 | + | |
| 67 | +public: | |
| 68 | + D2Dscene(); | |
| 69 | + ~D2Dscene(); | |
| 70 | + virtual int Create(); | |
| 71 | + virtual void RenderMain(); | |
| 72 | + virtual void Destroy(); | |
| 73 | +}; | |
| 74 | + | |
| 75 | +//! @brief 3D画面管理クラス(基底クラス) | |
| 76 | +//! @details ゲーム画面の中で、3D描画を行うシーンを管理する基底のクラスです。 | |
| 77 | +class D3Dscene : public scene | |
| 78 | +{ | |
| 79 | +protected: | |
| 80 | + class SoundManager *GameSound; //!< ゲーム効果音管理クラス | |
| 81 | + float camera_x; //!< カメラ座標 | |
| 82 | + float camera_y; //!< カメラ座標 | |
| 83 | + float camera_z; //!< カメラ座標 | |
| 84 | + float camera_rx; //!< カメラ座標 | |
| 85 | + float camera_ry; //!< カメラ座標 | |
| 86 | + virtual void Render3D(); | |
| 87 | + virtual void Render2D(); | |
| 88 | + | |
| 89 | +public: | |
| 90 | + D3Dscene(); | |
| 91 | + ~D3Dscene(); | |
| 92 | + virtual void SetClass(StateMachine *in_GameState, D3DGraphics *in_d3dg, InputControl *in_inputCtrl, SoundManager *in_GameSound); | |
| 93 | + virtual void Process(); | |
| 94 | + virtual void Sound(); | |
| 95 | + virtual void RenderMain(); | |
| 96 | +}; | |
| 97 | + | |
| 98 | +#ifndef H_LAYERLEVEL | |
| 99 | + #define H_LAYERLEVEL 3 //!< Select include file. | |
| 100 | +#endif | |
| 101 | +#include "main.h" | |
| 102 | + | |
| 103 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,200 @@ | ||
| 1 | +//! @file config.cpp | |
| 2 | +//! @brief configクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "config.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +Config::Config() | |
| 36 | +{ | |
| 37 | + //各種メンバー変数初期化 | |
| 38 | + for(int i=0; i<TOTAL_ControlKey; i++){ | |
| 39 | + Keycode[i] = 0; | |
| 40 | + } | |
| 41 | + MouseSensitivity = 0; | |
| 42 | + FullscreenFlag = false; | |
| 43 | + SoundFlag = false; | |
| 44 | + BloodFlag = false; | |
| 45 | + Brightness = 0; | |
| 46 | + InvertMouseFlag = false; | |
| 47 | + FrameskipFlag = false; | |
| 48 | + AnotherGunsightFlag = false; | |
| 49 | + strcpy(PlayerName, ""); | |
| 50 | +} | |
| 51 | + | |
| 52 | +//! ディストラクタ | |
| 53 | +Config::~Config() | |
| 54 | +{} | |
| 55 | + | |
| 56 | +//! 設定ファイルを読み込む | |
| 57 | +//! @param fname ファイル名 | |
| 58 | +//! @return 成功:0 失敗:1 | |
| 59 | +int Config::LoadFile(char *fname) | |
| 60 | +{ | |
| 61 | + FILE *fp; | |
| 62 | + char buf; | |
| 63 | + | |
| 64 | + //ファイルを開く | |
| 65 | + fp = fopen(fname, "rb"); | |
| 66 | + if( fp == NULL ){ | |
| 67 | + return 1; | |
| 68 | + } | |
| 69 | + | |
| 70 | + //キーコードを取得 | |
| 71 | + for(int i=0; i<TOTAL_ControlKey; i++){ | |
| 72 | + fread(&buf, 1, 1, fp); | |
| 73 | + Keycode[i] = buf; | |
| 74 | + } | |
| 75 | + | |
| 76 | + //マウス感度 | |
| 77 | + fread(&buf, 1, 1, fp); | |
| 78 | + MouseSensitivity = buf; | |
| 79 | + | |
| 80 | + //フルスクリーン有効 | |
| 81 | + fread(&buf, 1, 1, fp); | |
| 82 | + if( buf == 0x00 ){ FullscreenFlag = false; } | |
| 83 | + else{ FullscreenFlag = true; } | |
| 84 | + | |
| 85 | + //効果音有効 | |
| 86 | + fread(&buf, 1, 1, fp); | |
| 87 | + if( buf == 0x00 ){ SoundFlag = false; } | |
| 88 | + else{ SoundFlag = true; } | |
| 89 | + | |
| 90 | + //出血有効 | |
| 91 | + fread(&buf, 1, 1, fp); | |
| 92 | + if( buf == 0x00 ){ BloodFlag = false; } | |
| 93 | + else{ BloodFlag = true; } | |
| 94 | + | |
| 95 | + //画面の明るさ | |
| 96 | + fread(&buf, 1, 1, fp); | |
| 97 | + Brightness = buf; | |
| 98 | + | |
| 99 | + //マウス反転 | |
| 100 | + fread(&buf, 1, 1, fp); | |
| 101 | + if( buf == 0x00 ){ InvertMouseFlag = false; } | |
| 102 | + else{ InvertMouseFlag = true; } | |
| 103 | + | |
| 104 | + //フレームスキップ | |
| 105 | + fread(&buf, 1, 1, fp); | |
| 106 | + if( buf == 0x00 ){ FrameskipFlag = false; } | |
| 107 | + else{ FrameskipFlag = true; } | |
| 108 | + | |
| 109 | + //別の標準を使用 | |
| 110 | + fread(&buf, 1, 1, fp); | |
| 111 | + if( buf == 0x00 ){ AnotherGunsightFlag = false; } | |
| 112 | + else{ AnotherGunsightFlag = true; } | |
| 113 | + | |
| 114 | + //プレイヤー名 | |
| 115 | + fread(PlayerName, 1, MAX_PLAYERNAME, fp); | |
| 116 | + | |
| 117 | + //ファイルハンドルを閉じる | |
| 118 | + fclose(fp); | |
| 119 | + return 0; | |
| 120 | +} | |
| 121 | + | |
| 122 | +//! オリジナルキーコードを取得 | |
| 123 | +//! @param id 定数 | |
| 124 | +//! @return オリジナルキーコード | |
| 125 | +int Config::GetKeycode(int id) | |
| 126 | +{ | |
| 127 | + if( (id < 0)||((TOTAL_ControlKey -1) < id) ){ return 0; } | |
| 128 | + | |
| 129 | + return Keycode[id]; | |
| 130 | +} | |
| 131 | + | |
| 132 | +//! マウス感度取得 | |
| 133 | +//! @return 生の値 | |
| 134 | +int Config::GetMouseSensitivity() | |
| 135 | +{ | |
| 136 | + return MouseSensitivity; | |
| 137 | +} | |
| 138 | + | |
| 139 | +//! 画面表示モード取得 | |
| 140 | +//! @return ウィンドウ:false フルスクリーン:true | |
| 141 | +bool Config::GetFullscreenFlag() | |
| 142 | +{ | |
| 143 | + return FullscreenFlag; | |
| 144 | +} | |
| 145 | + | |
| 146 | +//! 効果音設定取得 | |
| 147 | +//! @return 無効:false 有効:true | |
| 148 | +bool Config::GetSoundFlag() | |
| 149 | +{ | |
| 150 | + return SoundFlag; | |
| 151 | +} | |
| 152 | + | |
| 153 | +//! 出血設定取得 | |
| 154 | +//! @return 無効:false 有効:true | |
| 155 | +bool Config::GetBloodFlag() | |
| 156 | +{ | |
| 157 | + return BloodFlag; | |
| 158 | +} | |
| 159 | + | |
| 160 | +//! 画面の明るさ設定取得 | |
| 161 | +//! @return 生の値 | |
| 162 | +int Config::GetBrightness() | |
| 163 | +{ | |
| 164 | + return Brightness; | |
| 165 | +} | |
| 166 | + | |
| 167 | +//! マウス反転設定取得 | |
| 168 | +//! @return 無効:false 有効:true | |
| 169 | +bool Config::GetInvertMouseFlag() | |
| 170 | +{ | |
| 171 | + return InvertMouseFlag; | |
| 172 | +} | |
| 173 | + | |
| 174 | +//! フレームスキップ設定取得 | |
| 175 | +//! @return 無効:false 有効:true | |
| 176 | +bool Config::GetFrameskipFlag() | |
| 177 | +{ | |
| 178 | + return FrameskipFlag; | |
| 179 | +} | |
| 180 | + | |
| 181 | +//! 別の照準を使用設定取得 | |
| 182 | +//! @return 無効:false 有効:true | |
| 183 | +bool Config::GetAnotherGunsightFlag() | |
| 184 | +{ | |
| 185 | + return AnotherGunsightFlag; | |
| 186 | +} | |
| 187 | + | |
| 188 | +//! プレイヤー名取得 | |
| 189 | +//! @param out_str 受け取る文字列型ポインタ | |
| 190 | +//! @return プレイヤー名文字数 | |
| 191 | +int Config::GetPlayerName(char *out_str) | |
| 192 | +{ | |
| 193 | + if( out_str == NULL ){ return 0; } | |
| 194 | + | |
| 195 | + //ポインタにコピーする | |
| 196 | + strcpy(out_str, PlayerName); | |
| 197 | + | |
| 198 | + //文字数を返す | |
| 199 | + return strlen(PlayerName); | |
| 200 | +} |
| @@ -0,0 +1,150 @@ | ||
| 1 | +//! @file statemachine.cpp | |
| 2 | +//! @brief StateMachineクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "statemachine.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +StateMachine::StateMachine() | |
| 36 | +{ | |
| 37 | + NowState = STATE_CREATE_OPENING; | |
| 38 | + back = false; | |
| 39 | + f12 = false; | |
| 40 | +} | |
| 41 | + | |
| 42 | +//! ディストラクタ | |
| 43 | +StateMachine::~StateMachine() | |
| 44 | +{} | |
| 45 | + | |
| 46 | +//! 次の状態へ移行 | |
| 47 | +void StateMachine::NextState() | |
| 48 | +{ | |
| 49 | + switch(NowState){ | |
| 50 | + case STATE_CREATE_OPENING: | |
| 51 | + NowState = STATE_NOW_OPENING; | |
| 52 | + break; | |
| 53 | + case STATE_NOW_OPENING: | |
| 54 | + NowState = STATE_DESTROY_OPENING; | |
| 55 | + break; | |
| 56 | + case STATE_DESTROY_OPENING: | |
| 57 | + NowState = STATE_CREATE_MENU; | |
| 58 | + break; | |
| 59 | + case STATE_CREATE_MENU: | |
| 60 | + NowState = STATE_NOW_MENU; | |
| 61 | + break; | |
| 62 | + case STATE_NOW_MENU: | |
| 63 | + NowState = STATE_DESTROY_MENU; | |
| 64 | + break; | |
| 65 | + case STATE_DESTROY_MENU: | |
| 66 | + if( back == false ){ | |
| 67 | + NowState = STATE_CREATE_BRIEFING; | |
| 68 | + } | |
| 69 | + else{ | |
| 70 | + NowState = STATE_EXIT; | |
| 71 | + } | |
| 72 | + break; | |
| 73 | + case STATE_CREATE_BRIEFING: | |
| 74 | + NowState = STATE_NOW_BRIEFING; | |
| 75 | + break; | |
| 76 | + case STATE_NOW_BRIEFING: | |
| 77 | + NowState = STATE_DESTROY_BRIEFING; | |
| 78 | + break; | |
| 79 | + case STATE_DESTROY_BRIEFING: | |
| 80 | + if( back == false ){ | |
| 81 | + NowState = STATE_CREATE_MAINGAME; | |
| 82 | + } | |
| 83 | + else{ | |
| 84 | + NowState = STATE_CREATE_MENU; | |
| 85 | + } | |
| 86 | + break; | |
| 87 | + case STATE_CREATE_MAINGAME: | |
| 88 | + NowState = STATE_NOW_MAINGAME; | |
| 89 | + break; | |
| 90 | + case STATE_NOW_MAINGAME: | |
| 91 | + NowState = STATE_DESTROY_MAINGAME; | |
| 92 | + break; | |
| 93 | + case STATE_DESTROY_MAINGAME: | |
| 94 | + if( f12 == true ){ | |
| 95 | + NowState = STATE_CREATE_MAINGAME; | |
| 96 | + } | |
| 97 | + else if( back == false ){ | |
| 98 | + NowState = STATE_CREATE_RESULT; | |
| 99 | + } | |
| 100 | + else{ | |
| 101 | + NowState = STATE_CREATE_MENU; | |
| 102 | + } | |
| 103 | + break; | |
| 104 | + case STATE_CREATE_RESULT: | |
| 105 | + NowState = STATE_NOW_RESULT; | |
| 106 | + break; | |
| 107 | + case STATE_NOW_RESULT: | |
| 108 | + NowState = STATE_DESTROY_RESULT; | |
| 109 | + break; | |
| 110 | + case STATE_DESTROY_RESULT: | |
| 111 | + NowState = STATE_CREATE_MENU; | |
| 112 | + break; | |
| 113 | + case STATE_EXIT: | |
| 114 | + NowState = STATE_EXIT; | |
| 115 | + break; | |
| 116 | + default: | |
| 117 | + NowState = STATE_NULL; | |
| 118 | + } | |
| 119 | +} | |
| 120 | + | |
| 121 | +//! マウスクリック を受けた | |
| 122 | +void StateMachine::PushMouseButton() | |
| 123 | +{ | |
| 124 | + back = false; | |
| 125 | + f12 = false; | |
| 126 | + NextState(); | |
| 127 | +} | |
| 128 | + | |
| 129 | +//! BackSpace キーを受けた | |
| 130 | +void StateMachine::PushBackSpaceKey() | |
| 131 | +{ | |
| 132 | + back = true; | |
| 133 | + f12 = false; | |
| 134 | + NextState(); | |
| 135 | +} | |
| 136 | + | |
| 137 | +//! F12 キーを受けた | |
| 138 | +void StateMachine::PushF12Key() | |
| 139 | +{ | |
| 140 | + if( NowState != STATE_NOW_MAINGAME ){ return; } | |
| 141 | + back = false; | |
| 142 | + f12 = true; | |
| 143 | + NextState(); | |
| 144 | +} | |
| 145 | + | |
| 146 | +//! 現在の状態を返す | |
| 147 | +int StateMachine::GetState() | |
| 148 | +{ | |
| 149 | + return NowState; | |
| 150 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,2559 @@ | ||
| 1 | +//! @file object.cpp | |
| 2 | +//! @brief objectクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "object.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +object::object(class ParameterInfo *in_Param, float x, float y, float z, float rx, float size, bool flag) | |
| 36 | +{ | |
| 37 | + Param = in_Param; | |
| 38 | + pos_x = x; | |
| 39 | + pos_y = y; | |
| 40 | + pos_z = z; | |
| 41 | + rotation_x = rx; | |
| 42 | + RenderFlag = flag; | |
| 43 | + model_size = size; | |
| 44 | + | |
| 45 | + id_parameter = 0; | |
| 46 | + id_model = -1; | |
| 47 | + id_texture = -1; | |
| 48 | +} | |
| 49 | + | |
| 50 | +//! ディストラクタ | |
| 51 | +object::~object() | |
| 52 | +{} | |
| 53 | + | |
| 54 | +//! 設定値を管理するクラスを登録 | |
| 55 | +//! @attention 各関数を使用する前に実行すること。 | |
| 56 | +void object::SetParameterInfoClass(class ParameterInfo *in_Param) | |
| 57 | +{ | |
| 58 | + Param = in_Param; | |
| 59 | +} | |
| 60 | + | |
| 61 | +//! 座標と角度を設定 | |
| 62 | +//! @param x X座標 | |
| 63 | +//! @param y Y座標 | |
| 64 | +//! @param z Z座標 | |
| 65 | +//! @param rx 横軸回転 | |
| 66 | +void object::SetPosData(float x, float y, float z, float rx) | |
| 67 | +{ | |
| 68 | + pos_x = x; | |
| 69 | + pos_y = y; | |
| 70 | + pos_z = z; | |
| 71 | + rotation_x = rx; | |
| 72 | +} | |
| 73 | + | |
| 74 | +//! 座標と角度を取得 | |
| 75 | +//! @param x X座標を受け取るポインタ(NULL可) | |
| 76 | +//! @param y Y座標を受け取るポインタ(NULL可) | |
| 77 | +//! @param z Z座標を受け取るポインタ(NULL可) | |
| 78 | +//! @param rx 横軸回転を受け取るポインタ(NULL可) | |
| 79 | +void object::GetPosData(float *x, float *y, float *z, float *rx) | |
| 80 | +{ | |
| 81 | + if( x != NULL ){ *x = pos_x; } | |
| 82 | + if( y != NULL ){ *y = pos_y; } | |
| 83 | + if( z != NULL ){ *z = pos_z; } | |
| 84 | + if( rx != NULL ){ *rx = rotation_x; } | |
| 85 | +} | |
| 86 | + | |
| 87 | +//! 描画フラグを設定 | |
| 88 | +//! @param flag 設定するフラグ | |
| 89 | +void object::SetDrawFlag(bool flag) | |
| 90 | +{ | |
| 91 | + RenderFlag = flag; | |
| 92 | +} | |
| 93 | + | |
| 94 | +//! 描画フラグを取得 | |
| 95 | +//! @return 現在設定されているフラグ | |
| 96 | +bool object::GetDrawFlag() | |
| 97 | +{ | |
| 98 | + return RenderFlag; | |
| 99 | +} | |
| 100 | + | |
| 101 | +//! モデルデータを設定 | |
| 102 | +//! @param id モデル認識番号 | |
| 103 | +//! @param size 表示倍率 | |
| 104 | +void object::SetModel(int id, float size) | |
| 105 | +{ | |
| 106 | + id_model = id; | |
| 107 | + model_size = size; | |
| 108 | +} | |
| 109 | + | |
| 110 | +//! テクスチャを設定 | |
| 111 | +//! @param id テクスチャ認識番号 | |
| 112 | +void object::SetTexture(int id) | |
| 113 | +{ | |
| 114 | + id_texture = id; | |
| 115 | +} | |
| 116 | + | |
| 117 | +//! 計算を実行(自由落下など) | |
| 118 | +int object::RunFrame() | |
| 119 | +{ | |
| 120 | + return 0; | |
| 121 | +} | |
| 122 | + | |
| 123 | +//! 描画 | |
| 124 | +//! @param d3dg D3DGraphicsのポインタ | |
| 125 | +void object::Render(D3DGraphics *d3dg) | |
| 126 | +{ | |
| 127 | + if( d3dg == NULL ){ return; } | |
| 128 | + if( RenderFlag == false ){ return; } | |
| 129 | + | |
| 130 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, 0.0f, model_size); | |
| 131 | + d3dg->RenderModel(id_model, id_texture); | |
| 132 | +} | |
| 133 | + | |
| 134 | +//! コンストラクタ | |
| 135 | +human::human(class ParameterInfo *in_Param, float x, float y, float z, float rx, int id_param, int dataid, signed char p4, int team, bool flag) | |
| 136 | +{ | |
| 137 | + //HumanParameter data; | |
| 138 | + | |
| 139 | + Param = in_Param; | |
| 140 | + pos_x = x; | |
| 141 | + pos_y = y; | |
| 142 | + pos_z = z; | |
| 143 | + move_x = 0.0f; | |
| 144 | + move_y = 0.0f; | |
| 145 | + move_z = 0.0f; | |
| 146 | + move_y_flag = false; | |
| 147 | + rotation_x = rx; | |
| 148 | + id_parameter = id_param; | |
| 149 | + upmodel_size = 9.4f; | |
| 150 | + armmodel_size = 9.0f; | |
| 151 | + legmodel_size = 9.0f; | |
| 152 | + RenderFlag = flag; | |
| 153 | + rotation_y = 0.0f; | |
| 154 | + armrotation_y = 0.0f; | |
| 155 | + reaction_y = 0.0f; | |
| 156 | + point_dataid = dataid; | |
| 157 | + point_p4 = p4; | |
| 158 | + teamid = team; | |
| 159 | + | |
| 160 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 161 | + weapon[i] = NULL; | |
| 162 | + } | |
| 163 | + selectweapon = 1; | |
| 164 | + //if( Param->GetHuman(id_param, &data) == 0 ){ | |
| 165 | + // hp = data.hp; | |
| 166 | + //} | |
| 167 | + //else{ | |
| 168 | + hp = 0; | |
| 169 | + //} | |
| 170 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 171 | + deadstate = 0; | |
| 172 | +#endif | |
| 173 | + id_texture = -1; | |
| 174 | + id_upmodel = -1; | |
| 175 | + for(int i=0; i<TOTAL_ARMMODE; i++){ | |
| 176 | + id_armmodel[i] = -1; | |
| 177 | + } | |
| 178 | + id_legmodel = -1; | |
| 179 | + for(int i=0; i<TOTAL_WALKMODE; i++){ | |
| 180 | + id_walkmodel[i] = -1; | |
| 181 | + } | |
| 182 | + for(int i=0; i<TOTAL_RUNMODE; i++){ | |
| 183 | + id_runmodel[i] = -1; | |
| 184 | + } | |
| 185 | + | |
| 186 | + addposorder_x = 0.0f; | |
| 187 | + addposorder_z = 0.0f; | |
| 188 | + move_rx = 0.0f; | |
| 189 | + MoveFlag = 0x00; | |
| 190 | + MoveFlag_lt = MoveFlag; | |
| 191 | + scopemode = 0; | |
| 192 | + HitFlag = false; | |
| 193 | + legmode = LEG_STOP; | |
| 194 | + walkcnt = 0; | |
| 195 | + runcnt = 0; | |
| 196 | + totalmove = 0.0f; | |
| 197 | + StateGunsightErrorRange = 0; | |
| 198 | + ReactionGunsightErrorRange = 0; | |
| 199 | +} | |
| 200 | + | |
| 201 | +//! ディストラクタ | |
| 202 | +human::~human() | |
| 203 | +{} | |
| 204 | + | |
| 205 | +//! 設定値を設定 | |
| 206 | +//! @param id_param 人の種類番号 | |
| 207 | +//! @param dataid ポイントのデータ番号 | |
| 208 | +//! @param p4 第4パラメータ | |
| 209 | +//! @param team チーム番号 | |
| 210 | +//! @param init オブジェクトを初期化 | |
| 211 | +void human::SetParamData(int id_param, int dataid, signed char p4, int team, bool init) | |
| 212 | +{ | |
| 213 | + id_parameter = id_param; | |
| 214 | + point_dataid = dataid; | |
| 215 | + point_p4 = p4; | |
| 216 | + teamid = team; | |
| 217 | + | |
| 218 | + if( init == true ){ | |
| 219 | + HumanParameter data; | |
| 220 | + | |
| 221 | + move_x = 0.0f; | |
| 222 | + move_y = 0.0f; | |
| 223 | + move_z = 0.0f; | |
| 224 | + move_y_flag = false; | |
| 225 | + rotation_y = 0.0f; | |
| 226 | + armrotation_y = (float)M_PI/18 * -3; | |
| 227 | + reaction_y = 0.0f; | |
| 228 | + | |
| 229 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 230 | + weapon[i] = NULL; | |
| 231 | + } | |
| 232 | + selectweapon = 1; | |
| 233 | + if( Param->GetHuman(id_param, &data) == 0 ){ | |
| 234 | + hp = data.hp; | |
| 235 | + } | |
| 236 | + else{ | |
| 237 | + hp = 0; | |
| 238 | + } | |
| 239 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 240 | + deadstate = 0; | |
| 241 | +#endif | |
| 242 | + MoveFlag = 0x00; | |
| 243 | + MoveFlag_lt = MoveFlag; | |
| 244 | + scopemode = 0; | |
| 245 | + HitFlag = false; | |
| 246 | + totalmove = 0.0f; | |
| 247 | + } | |
| 248 | +} | |
| 249 | + | |
| 250 | +//! 設定値を取得 | |
| 251 | +//! @param id_param 人の種類番号を受け取るポインタ(NULL可) | |
| 252 | +//! @param dataid ポイントのデータ番号を受け取るポインタ(NULL可) | |
| 253 | +//! @param p4 第4パラメータを受け取るポインタ(NULL可) | |
| 254 | +//! @param team チーム番号を受け取るポインタ(NULL可) | |
| 255 | +void human::GetParamData(int *id_param, int *dataid, signed char *p4, int *team) | |
| 256 | +{ | |
| 257 | + if( id_param != NULL ){ *id_param = id_parameter; } | |
| 258 | + if( dataid != NULL ){ *dataid = point_dataid; } | |
| 259 | + if( p4 != NULL ){ *p4 = point_p4; } | |
| 260 | + if( team != NULL ){ *team = teamid; } | |
| 261 | +} | |
| 262 | + | |
| 263 | +//! HPを取得 | |
| 264 | +//! @return HP | |
| 265 | +int human::GetHP() | |
| 266 | +{ | |
| 267 | + return hp; | |
| 268 | +} | |
| 269 | + | |
| 270 | +//! 死体かどうか判定 | |
| 271 | +//! @return 死体:true 死体でない:false | |
| 272 | +//! @warning 完全に静止した状態を「死体」と判定します。倒れている最中の人は対象に含まれないため、hp <= 0 が全て死体と判定されるとは限りません。 | |
| 273 | +bool human::GetDeadFlag() | |
| 274 | +{ | |
| 275 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 276 | + if( deadstate == 4 ){ return true; } | |
| 277 | + return false; | |
| 278 | +#else | |
| 279 | + if( hp <= 0 ){ return true; } | |
| 280 | + return false; | |
| 281 | +#endif | |
| 282 | +} | |
| 283 | + | |
| 284 | +//! チーム番号を設定(上書き) | |
| 285 | +//! @param id 新しいチーム番号 | |
| 286 | +void human::SetTeamID(int id) | |
| 287 | +{ | |
| 288 | + teamid = id; | |
| 289 | +} | |
| 290 | + | |
| 291 | +//! 前処理の移動量を取得 | |
| 292 | +//! @param *x X軸移動量を取得するポインタ(NULL可) | |
| 293 | +//! @param *y Y軸移動量を取得するポインタ(NULL可) | |
| 294 | +//! @param *z Z軸移動量を取得するポインタ(NULL可) | |
| 295 | +void human::GetMovePos(float *x, float *y, float *z) | |
| 296 | +{ | |
| 297 | + if( x != NULL ){ *x = move_x; } | |
| 298 | + if( y != NULL ){ *y = move_y; } | |
| 299 | + if( z != NULL ){ *z = move_z; } | |
| 300 | +} | |
| 301 | + | |
| 302 | +//! モデルデータを設定 | |
| 303 | +//! @param upmodel 上半身のモデル | |
| 304 | +//! @param armmodel[] 腕のモデルの配列(配列数:TOTAL_ARMMODE) | |
| 305 | +//! @param legmodel 足(静止状態)のモデル | |
| 306 | +//! @param walkmodel[] 腕のモデルの配列(配列数:TOTAL_WALKMODE) | |
| 307 | +//! @param runmodel[] 腕のモデルの配列(配列数:TOTAL_RUNMODE) | |
| 308 | +void human::SetModel(int upmodel, int armmodel[], int legmodel, int walkmodel[], int runmodel[]) | |
| 309 | +{ | |
| 310 | + id_upmodel = upmodel; | |
| 311 | + for(int i=0; i<TOTAL_ARMMODE; i++){ | |
| 312 | + id_armmodel[i] = armmodel[i]; | |
| 313 | + } | |
| 314 | + id_legmodel = legmodel; | |
| 315 | + for(int i=0; i<TOTAL_WALKMODE; i++){ | |
| 316 | + id_walkmodel[i] = walkmodel[i]; | |
| 317 | + } | |
| 318 | + for(int i=0; i<TOTAL_RUNMODE; i++){ | |
| 319 | + id_runmodel[i] = runmodel[i]; | |
| 320 | + } | |
| 321 | +} | |
| 322 | + | |
| 323 | +//! 武器を設定 | |
| 324 | +//! @param in_weapon[] 設定するweaponクラスのポインタ配列 | |
| 325 | +//! @warning 初期化時のみ使用すること | |
| 326 | +void human::SetWeapon(class weapon *in_weapon[]) | |
| 327 | +{ | |
| 328 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 329 | + if( in_weapon[i] == NULL ){ | |
| 330 | + weapon[i] = NULL; | |
| 331 | + } | |
| 332 | + else{ | |
| 333 | + //武器を正しく拾えれば、所持武器として登録 | |
| 334 | + if( in_weapon[i]->Pickup() == 0 ){ | |
| 335 | + weapon[i] = in_weapon[i]; | |
| 336 | + } | |
| 337 | + } | |
| 338 | + } | |
| 339 | +} | |
| 340 | + | |
| 341 | +//! 武器を拾う | |
| 342 | +//! @param in_weapon[] 設定するweaponクラスのポインタ | |
| 343 | +//! @return 成功:1 失敗:0 | |
| 344 | +//! @attention 人の種類が ゾンビ の場合、この関数は失敗します。 | |
| 345 | +int human::PickupWeapon(class weapon *in_weapon) | |
| 346 | +{ | |
| 347 | + if( in_weapon == NULL ){ | |
| 348 | + return 0; | |
| 349 | + } | |
| 350 | + | |
| 351 | + //人の種類が ゾンビ ならば、失敗 | |
| 352 | + HumanParameter Paraminfo; | |
| 353 | + Param->GetHuman(id_parameter, &Paraminfo); | |
| 354 | + if( Paraminfo.type == 2 ){ | |
| 355 | + return 0; | |
| 356 | + } | |
| 357 | + | |
| 358 | + if( weapon[selectweapon] == NULL ){ | |
| 359 | + //武器を正しく拾えれば、所持武器として登録 | |
| 360 | + if( in_weapon->Pickup() == 0 ){ | |
| 361 | + weapon[selectweapon] = in_weapon; | |
| 362 | + | |
| 363 | + //切り替え完了のカウント | |
| 364 | + selectweaponcnt = 10; | |
| 365 | + | |
| 366 | + return 1; | |
| 367 | + } | |
| 368 | + } | |
| 369 | + return 0; | |
| 370 | +} | |
| 371 | + | |
| 372 | +//! 武器を切り替える(持ち替える) | |
| 373 | +//! @param id 持ち替える武器 (-1 で次の武器) | |
| 374 | +void human::ChangeWeapon(int id) | |
| 375 | +{ | |
| 376 | + //リロード中なら失敗 | |
| 377 | + if( weapon[selectweapon] != NULL ){ | |
| 378 | + if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return; } | |
| 379 | + } | |
| 380 | + | |
| 381 | + //同じ武器に切り替えようとしているなら、失敗 | |
| 382 | + if( selectweapon == id ){ return; } | |
| 383 | + | |
| 384 | + //武器切り替え中なら失敗 | |
| 385 | + if( selectweaponcnt > 0 ){ return; } | |
| 386 | + | |
| 387 | + if( id == -1 ){ | |
| 388 | + //次の武器番号を選択 | |
| 389 | + selectweapon += 1; | |
| 390 | + if( selectweapon == TOTAL_HAVEWEAPON ){ | |
| 391 | + selectweapon = 0; | |
| 392 | + } | |
| 393 | + } | |
| 394 | + else{ | |
| 395 | + //武器番号が範囲内か確認 | |
| 396 | + if( (id < 0)||((TOTAL_HAVEWEAPON -1) < id ) ){ return; } | |
| 397 | + selectweapon = id; | |
| 398 | + } | |
| 399 | + | |
| 400 | + //スコープ表示を解除 | |
| 401 | + SetDisableScope(); | |
| 402 | + | |
| 403 | + //腕の角度(反動)を設定 | |
| 404 | + reaction_y = (float)M_PI/18*2 * -1; | |
| 405 | + | |
| 406 | + //切り替え完了のカウント | |
| 407 | + selectweaponcnt = 10; | |
| 408 | +} | |
| 409 | + | |
| 410 | +//! 武器の切り替えカウントを取得 | |
| 411 | +//! @return カウント数 (1以上で切り替え中) | |
| 412 | +int human::GetChangeWeaponCnt() | |
| 413 | +{ | |
| 414 | + return selectweaponcnt; | |
| 415 | +} | |
| 416 | + | |
| 417 | +//! 武器を取得 | |
| 418 | +//! @param out_selectweapon 選択されている武器 (0 〜 [TOTAL_HAVEWEAPON]-1) | |
| 419 | +//! @param out_weapon 受け取るweaponクラスのポインタ配列 (配列数:TOTAL_HAVEWEAPON) | |
| 420 | +void human::GetWeapon(int *out_selectweapon, class weapon *out_weapon[]) | |
| 421 | +{ | |
| 422 | + *out_selectweapon = selectweapon; | |
| 423 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 424 | + out_weapon[i] = weapon[i]; | |
| 425 | + } | |
| 426 | +} | |
| 427 | + | |
| 428 | +//! 現在装備している武器の種類番号を取得 | |
| 429 | +//! @return 武器の種類番号(0 〜 TOTAL_PARAMETERINFO_WEAPON -1) | |
| 430 | +//! @attention 現在手に持っている武器の種類番号です。 GetWeapon()関数 を用いて調べるのと同等です。 | |
| 431 | +int human::GetMainWeaponTypeNO() | |
| 432 | +{ | |
| 433 | + if( weapon[selectweapon] == NULL ){ | |
| 434 | + return ID_WEAPON_NONE; | |
| 435 | + } | |
| 436 | + | |
| 437 | + int id_param; | |
| 438 | + weapon[selectweapon]->GetParamData(&id_param, NULL, NULL); | |
| 439 | + return id_param; | |
| 440 | +} | |
| 441 | + | |
| 442 | +//! 連射設定を取得 | |
| 443 | +//! @return 連射可能:true 連射不可:false | |
| 444 | +bool human::GetWeaponBlazingmode() | |
| 445 | +{ | |
| 446 | + int param_id; | |
| 447 | + WeaponParameter data; | |
| 448 | + | |
| 449 | + //武器を装備していなければ、失敗 | |
| 450 | + if( weapon[selectweapon] == NULL ){ return false; } | |
| 451 | + | |
| 452 | + //装備している武器の種類番号を取得 | |
| 453 | + weapon[selectweapon]->GetParamData(¶m_id, NULL, NULL); | |
| 454 | + | |
| 455 | + //連射設定を返す | |
| 456 | + Param->GetWeapon(param_id, &data); | |
| 457 | + return data.blazingmode; | |
| 458 | +} | |
| 459 | + | |
| 460 | +//! 発砲処理 | |
| 461 | +//! @param weapon_paramid 発砲した武器の番号を受け取るポインタ | |
| 462 | +//! @param GunsightErrorRange 発砲した際の照準誤差を受け取るポインタ | |
| 463 | +//! @return 成功:1 失敗:0 | |
| 464 | +//! @attention 弾オブジェクトの処理や、発砲音の再生は別途行う必要があります。 | |
| 465 | +bool human::ShotWeapon(int *weapon_paramid, int *GunsightErrorRange) | |
| 466 | +{ | |
| 467 | + int param_id; | |
| 468 | + | |
| 469 | + //武器切り替え中なら失敗 | |
| 470 | + if( selectweaponcnt > 0 ){ return false; } | |
| 471 | + | |
| 472 | + //武器を装備していなければ、失敗 | |
| 473 | + if( weapon[selectweapon] == NULL ){ return false; } | |
| 474 | + | |
| 475 | + //弾の発射処理を行う | |
| 476 | + if( weapon[selectweapon]->Shot() != 0 ){ return false; } | |
| 477 | + | |
| 478 | + //武器の種類番号を取得 | |
| 479 | + weapon[selectweapon]->GetParamData(¶m_id, NULL, NULL); | |
| 480 | + | |
| 481 | + | |
| 482 | + //武器の設定値を取得 | |
| 483 | + WeaponParameter ParamData; | |
| 484 | + if( Param->GetWeapon(param_id, &ParamData) != 0 ){ return false; } | |
| 485 | + | |
| 486 | + //精密スコープの武器でスコープを覗いていなければ、誤差 20。 | |
| 487 | + if( (scopemode == 0)&&(ParamData.scopemode == 2) ){ | |
| 488 | + ReactionGunsightErrorRange = 20; | |
| 489 | + } | |
| 490 | + | |
| 491 | + | |
| 492 | + //武器の種類番号と誤差を返す | |
| 493 | + *weapon_paramid = param_id; | |
| 494 | + *GunsightErrorRange = StateGunsightErrorRange + ReactionGunsightErrorRange; | |
| 495 | + | |
| 496 | + | |
| 497 | + //精密スコープ以外の武器を、スコープを使わずに使っていたら、設定された誤差を加算。 | |
| 498 | + if( (ParamData.scopemode != 2)&&(scopemode == 0) ){ | |
| 499 | + ReactionGunsightErrorRange += ParamData.reaction; | |
| 500 | + } | |
| 501 | + | |
| 502 | + //スコープを使用している状態の反動を加算 | |
| 503 | + if( (ParamData.scopemode == 1)&&(scopemode != 0) ){ | |
| 504 | + armrotation_y += (float)M_PI/180 * (WEAPONERRORRANGE_SCALE * ParamData.reaction); | |
| 505 | + } | |
| 506 | + if( ParamData.scopemode == 2 ){ | |
| 507 | + armrotation_y += (float)M_PI/180 * (WEAPONERRORRANGE_SCALE * ParamData.reaction); | |
| 508 | + } | |
| 509 | + | |
| 510 | + //腕に反動を伝える | |
| 511 | + if( param_id == ID_WEAPON_GRENADE ){ | |
| 512 | + reaction_y = (float)M_PI/18*2; | |
| 513 | + } | |
| 514 | + else{ | |
| 515 | + reaction_y = (float)M_PI/360 * ParamData.reaction; | |
| 516 | + } | |
| 517 | + | |
| 518 | + //武器が無くなっていれば、装備から外した扱いに。 (手榴弾用) | |
| 519 | + if( weapon[selectweapon]->GetDrawFlag() == false ){ | |
| 520 | + weapon[selectweapon] = NULL; | |
| 521 | + } | |
| 522 | + return true; | |
| 523 | +} | |
| 524 | + | |
| 525 | +//! リロード | |
| 526 | +//! @return 成功:true 失敗:false | |
| 527 | +bool human::ReloadWeapon() | |
| 528 | +{ | |
| 529 | + //武器切り替え中なら失敗 | |
| 530 | + if( selectweaponcnt > 0 ){ return false; } | |
| 531 | + | |
| 532 | + //何かしらの武器を装備していれば〜 | |
| 533 | + if( weapon[selectweapon] != NULL ){ | |
| 534 | + //リロード中なら失敗 | |
| 535 | + if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return false; } | |
| 536 | + | |
| 537 | + //リロード処理を開始 | |
| 538 | + if( weapon[selectweapon]->StartReload() != 0 ){ return false; } | |
| 539 | + | |
| 540 | + //スコープモードを解除 | |
| 541 | + SetDisableScope(); | |
| 542 | + return true; | |
| 543 | + } | |
| 544 | + return false; | |
| 545 | +} | |
| 546 | + | |
| 547 | +//! 武器を捨てる | |
| 548 | +//! @return 成功:true 失敗:false | |
| 549 | +bool human::DumpWeapon() | |
| 550 | +{ | |
| 551 | + //武器切り替え中なら失敗 | |
| 552 | + if( selectweaponcnt > 0 ){ return false; } | |
| 553 | + | |
| 554 | + //何かしらの武器を装備していれば〜 | |
| 555 | + if( weapon[selectweapon] != NULL ){ | |
| 556 | + //リロード中なら失敗 | |
| 557 | + if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return false; } | |
| 558 | + | |
| 559 | + //武器を捨て、装備を解除 | |
| 560 | + weapon[selectweapon]->Dropoff(pos_x, pos_y, pos_z, rotation_x, 1.63f); | |
| 561 | + weapon[selectweapon] = NULL; | |
| 562 | + | |
| 563 | + //スコープモードを解除 | |
| 564 | + SetDisableScope(); | |
| 565 | + | |
| 566 | + return true; | |
| 567 | + } | |
| 568 | + | |
| 569 | + return false; | |
| 570 | +} | |
| 571 | + | |
| 572 | +//! 武器のショットモード切り替え | |
| 573 | +//! @return 成功:0 失敗:1 | |
| 574 | +int human::ChangeShotMode() | |
| 575 | +{ | |
| 576 | + //武器を装備してなければ失敗 | |
| 577 | + if( weapon[selectweapon] == NULL ){ return 1; } | |
| 578 | + | |
| 579 | + //装備している武器の情報を取得 | |
| 580 | + int param_id, lnbs, nbs; | |
| 581 | + weapon[selectweapon]->GetParamData(¶m_id, &lnbs, &nbs); | |
| 582 | + | |
| 583 | + //武器のショットモード切り替え先(新しい武器番号)を調べる | |
| 584 | + WeaponParameter ParamData; | |
| 585 | + int ChangeWeapon; | |
| 586 | + if( Param->GetWeapon(param_id, &ParamData) != 0 ){ return 1; } | |
| 587 | + ChangeWeapon = ParamData.ChangeWeapon; | |
| 588 | + | |
| 589 | + //新しい武器番号が正しいか確認 | |
| 590 | + if( ChangeWeapon == param_id ){ return 1; } | |
| 591 | + if( (ChangeWeapon < 0)||(TOTAL_PARAMETERINFO_WEAPON-1 < ChangeWeapon) ){ return 1; } | |
| 592 | + | |
| 593 | + //設定を適用 | |
| 594 | + weapon[selectweapon]->SetParamData(ChangeWeapon, lnbs, nbs, false); | |
| 595 | + return 0; | |
| 596 | +} | |
| 597 | + | |
| 598 | +//! 前進(走り)を設定 | |
| 599 | +void human::SetMoveForward() | |
| 600 | +{ | |
| 601 | + SetFlag(MoveFlag, MOVEFLAG_FORWARD); | |
| 602 | +} | |
| 603 | + | |
| 604 | +//! 後退を設定 | |
| 605 | +void human::SetMoveBack() | |
| 606 | +{ | |
| 607 | + SetFlag(MoveFlag, MOVEFLAG_BACK); | |
| 608 | +} | |
| 609 | + | |
| 610 | +//! 左走りを設定 | |
| 611 | +void human::SetMoveLeft() | |
| 612 | +{ | |
| 613 | + SetFlag(MoveFlag, MOVEFLAG_LEFT); | |
| 614 | +} | |
| 615 | + | |
| 616 | +//! 右走りを設定 | |
| 617 | +void human::SetMoveRight() | |
| 618 | +{ | |
| 619 | + SetFlag(MoveFlag, MOVEFLAG_RIGHT); | |
| 620 | +} | |
| 621 | + | |
| 622 | +//! 歩きを設定 | |
| 623 | +void human::SetMoveWalk() | |
| 624 | +{ | |
| 625 | + SetFlag(MoveFlag, MOVEFLAG_WALK); | |
| 626 | +} | |
| 627 | + | |
| 628 | +//! 人の移動モードを取得 | |
| 629 | +// @param nowdata 現在の値を取得:true 前フレームの値を使用:false | |
| 630 | +//! @return 歩き:1 走り:2 移動してない:0 | |
| 631 | +int human::GetMovemode(bool nowdata) | |
| 632 | +{ | |
| 633 | + //使用されていないか、処理されていなければ終了 | |
| 634 | + if( RenderFlag == false ){ return 0; } | |
| 635 | + if( hp <= 0 ){ return 0; } | |
| 636 | + | |
| 637 | + if( nowdata == false ){ //前のデータ | |
| 638 | + //歩きならば 1 | |
| 639 | + if( GetFlag(MoveFlag_lt, MOVEFLAG_WALK) ){ | |
| 640 | + return 1; | |
| 641 | + } | |
| 642 | + //走りならば 2 | |
| 643 | + if( GetFlag(MoveFlag_lt, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){ | |
| 644 | + return 2; | |
| 645 | + } | |
| 646 | + } | |
| 647 | + else{ //現在のデータ | |
| 648 | + //歩きならば 1 | |
| 649 | + if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){ | |
| 650 | + return 1; | |
| 651 | + } | |
| 652 | + //走りならば 2 | |
| 653 | + if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){ | |
| 654 | + return 2; | |
| 655 | + } | |
| 656 | + } | |
| 657 | + | |
| 658 | + //移動してない | |
| 659 | + return 0; | |
| 660 | +} | |
| 661 | + | |
| 662 | +//! スコープを設定 | |
| 663 | +//! @return 成功:true 失敗:false | |
| 664 | +bool human::SetEnableScope() | |
| 665 | +{ | |
| 666 | + int param_id; | |
| 667 | + WeaponParameter data; | |
| 668 | + | |
| 669 | + //何も武器を装備してなければ失敗 | |
| 670 | + if( weapon[selectweapon] == NULL ){ return false; } | |
| 671 | + | |
| 672 | + //武器の種類番号を取得 | |
| 673 | + weapon[selectweapon]->GetParamData(¶m_id, NULL, NULL); | |
| 674 | + | |
| 675 | + //武器の設定値を取得 | |
| 676 | + Param->GetWeapon(param_id, &data); | |
| 677 | + | |
| 678 | + //スコープを設定 | |
| 679 | + scopemode = data.scopemode; | |
| 680 | + return true; | |
| 681 | +} | |
| 682 | + | |
| 683 | +//! スコープを解除 | |
| 684 | +void human::SetDisableScope() | |
| 685 | +{ | |
| 686 | + scopemode = 0; | |
| 687 | +} | |
| 688 | + | |
| 689 | +//! スコープ設定を取得 | |
| 690 | +int human::GetScopeMode() | |
| 691 | +{ | |
| 692 | + return scopemode; | |
| 693 | +} | |
| 694 | + | |
| 695 | +//! 横軸と縦軸の向きを取得 | |
| 696 | +//! @param rx 横軸を取得するポインタ | |
| 697 | +//! @param ry 縦軸を取得するポインタ | |
| 698 | +void human::GetRxRy(float *rx, float *ry) | |
| 699 | +{ | |
| 700 | + *rx = rotation_x; | |
| 701 | + *ry = armrotation_y; | |
| 702 | +} | |
| 703 | + | |
| 704 | +//! 横軸と縦軸の向きを設定 | |
| 705 | +//! @param rx 設定する横軸 | |
| 706 | +//! @param ry 設定する縦軸 | |
| 707 | +void human::SetRxRy(float rx, float ry) | |
| 708 | +{ | |
| 709 | + rotation_x = rx; | |
| 710 | + armrotation_y = ry; | |
| 711 | +} | |
| 712 | + | |
| 713 | +//! ジャンプ | |
| 714 | +//! @return 成功:0 失敗:1 | |
| 715 | +int human::Jump() | |
| 716 | +{ | |
| 717 | + //地面に触れており、落下速度が0.0ならば | |
| 718 | + if( move_y_flag == false ){ | |
| 719 | + if( move_y == 0.0f ){ | |
| 720 | + move_y = HUMAN_JUMP_SPEED; | |
| 721 | + return 0; | |
| 722 | + } | |
| 723 | + } | |
| 724 | + return 1; | |
| 725 | +} | |
| 726 | + | |
| 727 | +//! 押しだす・力を加える | |
| 728 | +//! @param rx 横軸 | |
| 729 | +//! @param speed 速度 | |
| 730 | +void human::AddPosOrder(float rx, float speed) | |
| 731 | +{ | |
| 732 | + addposorder_x += cos(rx)*speed; | |
| 733 | + addposorder_z += sin(rx)*speed; | |
| 734 | +} | |
| 735 | + | |
| 736 | +//! 弾が 頭 にヒット | |
| 737 | +//! @param attacks 弾の攻撃力 | |
| 738 | +void human::HitBulletHead(int attacks) | |
| 739 | +{ | |
| 740 | + hp -= (int)((float)attacks * HUMAN_DAMAGE_HEAD); | |
| 741 | + HitFlag = true; | |
| 742 | +} | |
| 743 | + | |
| 744 | +//! 弾が 上半身 にヒット | |
| 745 | +//! @param attacks 弾の攻撃力 | |
| 746 | +void human::HitBulletUp(int attacks) | |
| 747 | +{ | |
| 748 | + hp -= (int)((float)attacks * HUMAN_DAMAGE_UP); | |
| 749 | + HitFlag = true; | |
| 750 | +} | |
| 751 | + | |
| 752 | +//! 弾が 下半身 にヒット | |
| 753 | +//! @param attacks 弾の攻撃力 | |
| 754 | +void human::HitBulletLeg(int attacks) | |
| 755 | +{ | |
| 756 | + hp -= (int)((float)attacks * HUMAN_DAMAGE_LEG); | |
| 757 | + HitFlag = true; | |
| 758 | +} | |
| 759 | + | |
| 760 | +//! ゾンビの攻撃がヒット | |
| 761 | +void human::HitZombieAttack() | |
| 762 | +{ | |
| 763 | + hp -= HUMAN_DAMAGE_ZOMBIEU + GetRand(HUMAN_DAMAGE_ZOMBIEA); | |
| 764 | + HitFlag = true; | |
| 765 | +} | |
| 766 | + | |
| 767 | +//! 手榴弾が爆発した | |
| 768 | +//! @param CollD Collisionクラス | |
| 769 | +//! @param tGrenade 爆発したgrenadeクラスのポインタ | |
| 770 | +//! @return 当たった:1 当たっていない:0 | |
| 771 | +int human::GrenadeExplosion(class Collision *CollD, class grenade *tGrenade) | |
| 772 | +{ | |
| 773 | + //初期化されていないか、死亡していれば処理しない。 | |
| 774 | + if( RenderFlag == false ){ return 0; } | |
| 775 | + if( hp <= 0 ){ return 0; } | |
| 776 | + | |
| 777 | + //手榴弾の座標を取得し、距離を計算 | |
| 778 | + float gre_x, gre_y, gre_z; | |
| 779 | + float x, y, z, r; | |
| 780 | + tGrenade->GetPosData(&gre_x, &gre_y, &gre_z, NULL, NULL); | |
| 781 | + x = pos_x - gre_x; | |
| 782 | + y = pos_y - gre_y; | |
| 783 | + z = pos_z - gre_z; | |
| 784 | + r = sqrt(x*x + y*y + z*z); | |
| 785 | + | |
| 786 | + //100.0より遠ければ計算しない | |
| 787 | + if( r > MAX_DAMAGE_GRENADE_DISTANCE + HUMAN_HEIGTH ){ return 0; } | |
| 788 | + | |
| 789 | + float dummy = 0.0f; | |
| 790 | + int damage; | |
| 791 | + int returncode = 0; | |
| 792 | + | |
| 793 | + //足元に当たり判定 | |
| 794 | + y = pos_y + 2.0f - gre_y; | |
| 795 | + r = sqrt(x*x + y*y + z*z); | |
| 796 | + //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ) | |
| 797 | + if( CollD->CheckALLBlockIntersectRay(gre_x, gre_y, gre_z, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){ | |
| 798 | + //ダメージ量を計算し、反映 | |
| 799 | + damage = HUMAN_DAMAGE_GRENADE_LEG - (int)((float)HUMAN_DAMAGE_GRENADE_LEG/MAX_DAMAGE_GRENADE_DISTANCE * r); | |
| 800 | + if( damage > 0 ){ | |
| 801 | + hp -= damage; | |
| 802 | + HitFlag = true; | |
| 803 | + returncode = 1; | |
| 804 | + } | |
| 805 | + } | |
| 806 | + | |
| 807 | + //頭に当たり判定 | |
| 808 | + y = pos_y + 18.0f - gre_y; | |
| 809 | + r = sqrt(x*x + y*y + z*z); | |
| 810 | + //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ) | |
| 811 | + if( CollD->CheckALLBlockIntersectRay(gre_x, gre_y, gre_z, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){ | |
| 812 | + //ダメージ量を計算し、反映 | |
| 813 | + damage = HUMAN_DAMAGE_GRENADE_HEAD - (int)((float)HUMAN_DAMAGE_GRENADE_HEAD/MAX_DAMAGE_GRENADE_DISTANCE * r); | |
| 814 | + if( damage > 0 ){ | |
| 815 | + hp -= damage; | |
| 816 | + HitFlag = true; | |
| 817 | + returncode = 1; | |
| 818 | + } | |
| 819 | + } | |
| 820 | + | |
| 821 | + return returncode; | |
| 822 | +} | |
| 823 | + | |
| 824 | +//! 被弾したかチェックする | |
| 825 | +//! @return 被弾した:true 被弾してない:false | |
| 826 | +//! @attention 実行すると、フラグは false に初期化されます。 | |
| 827 | +bool human::CheckHit() | |
| 828 | +{ | |
| 829 | + bool returnflag = HitFlag; | |
| 830 | + HitFlag = false; | |
| 831 | + return returnflag; | |
| 832 | +} | |
| 833 | + | |
| 834 | +//! 合計移動量を取得 | |
| 835 | +//! @return 合計移動量 | |
| 836 | +float human::GetTotalMove() | |
| 837 | +{ | |
| 838 | + return totalmove; | |
| 839 | +} | |
| 840 | + | |
| 841 | +//! 照準の状態誤差の処理 | |
| 842 | +//! @attention ControlProcess()より前で処理すること | |
| 843 | +void human::GunsightErrorRange() | |
| 844 | +{ | |
| 845 | + //初期化 | |
| 846 | + StateGunsightErrorRange = 0; | |
| 847 | + | |
| 848 | + //各操作による誤差を設定 | |
| 849 | + if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){ | |
| 850 | + StateGunsightErrorRange = 4; | |
| 851 | + } | |
| 852 | + if( GetFlag(MoveFlag, MOVEFLAG_FORWARD) ){ | |
| 853 | + StateGunsightErrorRange = 8; | |
| 854 | + } | |
| 855 | + if( GetFlag(MoveFlag, MOVEFLAG_BACK) ){ | |
| 856 | + StateGunsightErrorRange = 6; | |
| 857 | + } | |
| 858 | + if( GetFlag(MoveFlag, (MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){ | |
| 859 | + StateGunsightErrorRange = 7; | |
| 860 | + } | |
| 861 | + if( move_y_flag == true ){ | |
| 862 | + StateGunsightErrorRange = 22; | |
| 863 | + } | |
| 864 | + if( hp < 40 ){ | |
| 865 | + StateGunsightErrorRange += 3; | |
| 866 | + } | |
| 867 | + | |
| 868 | + //何か武器を装備していれば | |
| 869 | + if( weapon[selectweapon] != NULL ){ | |
| 870 | + //武器の設定データを取得 | |
| 871 | + int param; | |
| 872 | + WeaponParameter data; | |
| 873 | + weapon[selectweapon]->GetParamData(¶m, NULL, NULL); | |
| 874 | + Param->GetWeapon(param, &data); | |
| 875 | + | |
| 876 | + //誤差を 1 減らす | |
| 877 | + ReactionGunsightErrorRange -= 1; | |
| 878 | + | |
| 879 | + //誤差の範囲を補正 | |
| 880 | + if( ReactionGunsightErrorRange < 0 ){ ReactionGunsightErrorRange = 0; } | |
| 881 | + if( ReactionGunsightErrorRange > data.ErrorRangeMAX ){ ReactionGunsightErrorRange = data.ErrorRangeMAX; } | |
| 882 | + } | |
| 883 | + else{ | |
| 884 | + ReactionGunsightErrorRange = 0; | |
| 885 | + } | |
| 886 | +} | |
| 887 | + | |
| 888 | +//! 死亡判定と倒れる処理 | |
| 889 | +//! @return 倒れ終わった:3 倒れている最中:2 倒れ始める:1 何もしない:0 | |
| 890 | +int human::CheckAndProcessDead(class Collision *CollD) | |
| 891 | +{ | |
| 892 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 893 | + float add_ry = 0.0f; | |
| 894 | + float check_posx, check_posy, check_posz; | |
| 895 | + | |
| 896 | + if( deadstate == 0 ){ | |
| 897 | + if( hp <= 0 ){ //HPが 0 以下になった(死亡した)瞬間なら、倒し始める | |
| 898 | + //体の角度・腕の角度 | |
| 899 | + switch( GetRand(4) ){ | |
| 900 | + case 0: | |
| 901 | + add_ry = (float)M_PI/180*6; | |
| 902 | + armrotation_y = (float)M_PI/2; | |
| 903 | + break; | |
| 904 | + case 1: | |
| 905 | + add_ry = (float)M_PI/180*6 * -1; | |
| 906 | + armrotation_y = (float)M_PI/2; | |
| 907 | + break; | |
| 908 | + case 2: | |
| 909 | + add_ry = (float)M_PI/180*6; | |
| 910 | + armrotation_y = (float)M_PI/2 * -1; | |
| 911 | + break; | |
| 912 | + case 3: | |
| 913 | + add_ry = (float)M_PI/180*6 * -1; | |
| 914 | + armrotation_y = (float)M_PI/2 * -1; | |
| 915 | + break; | |
| 916 | + } | |
| 917 | + | |
| 918 | + //死体が埋まらぬよう、高さを +1.0 する | |
| 919 | + pos_y += 1.0f; | |
| 920 | + | |
| 921 | + //所持している武器を全て捨てる | |
| 922 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 923 | + if( weapon[i] != NULL ){ | |
| 924 | + weapon[i]->Dropoff(pos_x, pos_y, pos_z, (float)M_PI/18*GetRand(36), 1.5f); | |
| 925 | + weapon[i] = NULL; | |
| 926 | + } | |
| 927 | + } | |
| 928 | + | |
| 929 | + //スコープモードを解除 | |
| 930 | + SetDisableScope(); | |
| 931 | + | |
| 932 | + //次のフレームの頭の座標を取得 | |
| 933 | + check_posx = pos_x + cos(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH; | |
| 934 | + check_posy = pos_y + cos(add_ry) * HUMAN_HEIGTH; | |
| 935 | + check_posz = pos_z + sin(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH; | |
| 936 | + | |
| 937 | + if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){ | |
| 938 | + deadstate = 2; | |
| 939 | + } | |
| 940 | + else{ | |
| 941 | + rotation_y += add_ry; | |
| 942 | + deadstate = 1; | |
| 943 | + } | |
| 944 | + return 1; | |
| 945 | + } | |
| 946 | + return 0; | |
| 947 | + } | |
| 948 | + | |
| 949 | + if( deadstate == 1 ){ | |
| 950 | + //135度以上倒れていれば | |
| 951 | + if( abs(rotation_y) >= (float)M_PI/4*3 ){ | |
| 952 | + deadstate = 2; | |
| 953 | + return 2; | |
| 954 | + } | |
| 955 | + | |
| 956 | + if( pos_y <= (HUMAN_DEADLINE + 10.0f) ){ | |
| 957 | + //90度以上倒れていれば | |
| 958 | + if( abs(rotation_y) >= (float)M_PI/2 ){ | |
| 959 | + deadstate = 4; | |
| 960 | + return 2; | |
| 961 | + } | |
| 962 | + } | |
| 963 | + | |
| 964 | + //前後に倒す | |
| 965 | + if( rotation_y > 0.0f ){ //rotation_y < (float)M_PI/4*3 | |
| 966 | + add_ry = (float)M_PI/180*6; | |
| 967 | + } | |
| 968 | + else if( rotation_y < 0.0f ){ //rotation_y > (float)M_PI/4*3 * -1 | |
| 969 | + add_ry = (float)M_PI/180*6 * -1; | |
| 970 | + } | |
| 971 | + | |
| 972 | + if( pos_y <= HUMAN_DEADLINE ){ | |
| 973 | + rotation_y += add_ry; | |
| 974 | + } | |
| 975 | + else{ | |
| 976 | + //次のフレームの頭の座標を取得 | |
| 977 | + check_posx = pos_x + cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 978 | + check_posy = pos_y + cos(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 979 | + check_posz = pos_z + sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 980 | + | |
| 981 | + if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){ | |
| 982 | + deadstate = 3; | |
| 983 | + } | |
| 984 | + else{ | |
| 985 | + rotation_y += add_ry; | |
| 986 | + } | |
| 987 | + } | |
| 988 | + | |
| 989 | + return 2; | |
| 990 | + } | |
| 991 | + | |
| 992 | + if( deadstate == 2 ){ | |
| 993 | + if( pos_y <= HUMAN_DEADLINE ){ | |
| 994 | + deadstate = 4; | |
| 995 | + return 2; | |
| 996 | + } | |
| 997 | + | |
| 998 | + //次のフレームの足の座標 | |
| 999 | + check_posx = pos_x; | |
| 1000 | + check_posy = pos_y - 0.5f; | |
| 1001 | + check_posz = pos_z; | |
| 1002 | + | |
| 1003 | + if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){ | |
| 1004 | + deadstate = 4; | |
| 1005 | + } | |
| 1006 | + else{ | |
| 1007 | + pos_y -= 0.5f; | |
| 1008 | + } | |
| 1009 | + | |
| 1010 | + return 2; | |
| 1011 | + } | |
| 1012 | + | |
| 1013 | + if( deadstate == 3 ){ | |
| 1014 | + //deadstate = 4; | |
| 1015 | + | |
| 1016 | + //90度以上倒れていれば | |
| 1017 | + if( abs(rotation_y) >= (float)M_PI/2 ){ | |
| 1018 | + deadstate = 4; | |
| 1019 | + return 2; | |
| 1020 | + } | |
| 1021 | + | |
| 1022 | + //前後に倒す | |
| 1023 | + if( rotation_y > 0.0f ){ //rotation_y < (float)M_PI/2 | |
| 1024 | + add_ry = (float)M_PI/180*6; | |
| 1025 | + } | |
| 1026 | + else if( rotation_y < 0.0f ){ //rotation_y > (float)M_PI/2 * -1 | |
| 1027 | + add_ry = (float)M_PI/180*6 * -1; | |
| 1028 | + } | |
| 1029 | + | |
| 1030 | + //次のフレームの足の座標を取得 | |
| 1031 | + check_posx = pos_x - cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 1032 | + check_posy = pos_y + 0.1f; | |
| 1033 | + check_posz = pos_z - sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 1034 | + | |
| 1035 | + if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){ | |
| 1036 | + deadstate = 4; | |
| 1037 | + return 2; | |
| 1038 | + } | |
| 1039 | + | |
| 1040 | + //次のフレームの頭の座標を取得 | |
| 1041 | + check_posx = pos_x - cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 1042 | + check_posy = pos_y + cos(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 1043 | + check_posz = pos_z - sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH; | |
| 1044 | + | |
| 1045 | + if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){ | |
| 1046 | + deadstate = 4; | |
| 1047 | + return 2; | |
| 1048 | + } | |
| 1049 | + | |
| 1050 | + //足の座標を移動 | |
| 1051 | + pos_x -= cos(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH; | |
| 1052 | + pos_z -= sin(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH; | |
| 1053 | + | |
| 1054 | + rotation_y += add_ry; | |
| 1055 | + return 2; | |
| 1056 | + } | |
| 1057 | + | |
| 1058 | + if( deadstate == 4 ){ | |
| 1059 | + //何もしない(固定) | |
| 1060 | + return 3; | |
| 1061 | + } | |
| 1062 | + | |
| 1063 | + return 0; | |
| 1064 | +#else | |
| 1065 | + if( rotation_y > 0.0f ){ //倒れ始めていれば、そのまま倒れる。 | |
| 1066 | + if( rotation_y < (float)M_PI/2 ){ | |
| 1067 | + rotation_y += (float)M_PI/180*6; | |
| 1068 | + } | |
| 1069 | + return 2; | |
| 1070 | + } | |
| 1071 | + else if( rotation_y < 0.0f ){ //倒れ始めていれば、そのまま倒れる。 | |
| 1072 | + if( rotation_y > (float)M_PI/2 * -1 ){ | |
| 1073 | + rotation_y -= (float)M_PI/180*6; | |
| 1074 | + } | |
| 1075 | + return 2; | |
| 1076 | + } | |
| 1077 | + else if( hp <= 0 ){ //HPが 0 以下になった(死亡した)瞬間なら、倒し始める | |
| 1078 | + //体の角度・腕の角度 | |
| 1079 | + switch( GetRand(4) ){ | |
| 1080 | + case 0: | |
| 1081 | + rotation_y = (float)M_PI/180*6; | |
| 1082 | + armrotation_y = (float)M_PI/2; | |
| 1083 | + break; | |
| 1084 | + case 1: | |
| 1085 | + rotation_y = (float)M_PI/180*6 * -1; | |
| 1086 | + armrotation_y = (float)M_PI/2; | |
| 1087 | + break; | |
| 1088 | + case 2: | |
| 1089 | + rotation_y = (float)M_PI/180*6; | |
| 1090 | + armrotation_y = (float)M_PI/2 * -1; | |
| 1091 | + break; | |
| 1092 | + case 3: | |
| 1093 | + rotation_y = (float)M_PI/180*6 * -1; | |
| 1094 | + armrotation_y = (float)M_PI/2 * -1; | |
| 1095 | + break; | |
| 1096 | + } | |
| 1097 | + | |
| 1098 | + //死体が埋まらぬよう、高さを +1.0 する | |
| 1099 | + pos_y += 1.0f; | |
| 1100 | + | |
| 1101 | + //所持している武器を全て捨てる | |
| 1102 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1103 | + if( weapon[i] != NULL ){ | |
| 1104 | + weapon[i]->Dropoff(pos_x, pos_y, pos_z, (float)M_PI/18*GetRand(36), 1.5f); | |
| 1105 | + weapon[i] = NULL; | |
| 1106 | + } | |
| 1107 | + } | |
| 1108 | + | |
| 1109 | + //スコープモードを解除 | |
| 1110 | + SetDisableScope(); | |
| 1111 | + | |
| 1112 | + return 1; | |
| 1113 | + } | |
| 1114 | + | |
| 1115 | + return 0; | |
| 1116 | +#endif | |
| 1117 | +} | |
| 1118 | + | |
| 1119 | +//! 操作による移動計算 | |
| 1120 | +//! @attention 実行すると、各キーフラグは false に初期化されます。 | |
| 1121 | +void human::ControlProcess() | |
| 1122 | +{ | |
| 1123 | + //進行方向と速度を決定 | |
| 1124 | + if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){ | |
| 1125 | + move_rx = 0.0f; | |
| 1126 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_PROGRESSWALK_SPEED); | |
| 1127 | + legmode = LEG_WALK; | |
| 1128 | + walkcnt += 1; | |
| 1129 | + runcnt = 0; | |
| 1130 | + } | |
| 1131 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_FORWARD ){ | |
| 1132 | + move_rx = 0.0f; | |
| 1133 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_PROGRESSRUN_SPEED); | |
| 1134 | + legmode = LEG_RUN; | |
| 1135 | + walkcnt = 0; | |
| 1136 | + runcnt += 1; | |
| 1137 | + } | |
| 1138 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_BACK ){ | |
| 1139 | + move_rx = (float)M_PI; | |
| 1140 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_REGRESSRUN_SPEED); | |
| 1141 | + legmode = LEG_RUN; | |
| 1142 | + walkcnt = 0; | |
| 1143 | + runcnt += 1; | |
| 1144 | + } | |
| 1145 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_LEFT ){ | |
| 1146 | + move_rx = (float)M_PI/2; | |
| 1147 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_SIDEWAYSRUN_SPEED); | |
| 1148 | + legmode = LEG_RUN; | |
| 1149 | + walkcnt = 0; | |
| 1150 | + runcnt += 1; | |
| 1151 | + } | |
| 1152 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_RIGHT ){ | |
| 1153 | + move_rx = (float)M_PI/2 * -1; | |
| 1154 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_SIDEWAYSRUN_SPEED); | |
| 1155 | + legmode = LEG_RUN; | |
| 1156 | + walkcnt = 0; | |
| 1157 | + runcnt += 1; | |
| 1158 | + } | |
| 1159 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_FORWARD | MOVEFLAG_LEFT) ){ | |
| 1160 | + move_rx = (float)M_PI/4; | |
| 1161 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_PROGRESSRUN_SIDEWAYSRUN_SPEED); | |
| 1162 | + legmode = LEG_RUN; | |
| 1163 | + walkcnt = 0; | |
| 1164 | + runcnt += 1; | |
| 1165 | + } | |
| 1166 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_BACK | MOVEFLAG_LEFT) ){ | |
| 1167 | + move_rx = (float)M_PI/4*3; | |
| 1168 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_REGRESSRUN_SIDEWAYSRUN_SPEED); | |
| 1169 | + legmode = LEG_RUN; | |
| 1170 | + walkcnt = 0; | |
| 1171 | + runcnt += 1; | |
| 1172 | + } | |
| 1173 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_BACK | MOVEFLAG_RIGHT) ){ | |
| 1174 | + move_rx = (float)M_PI/4*3 * -1; | |
| 1175 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_REGRESSRUN_SIDEWAYSRUN_SPEED); | |
| 1176 | + legmode = LEG_RUN; | |
| 1177 | + walkcnt = 0; | |
| 1178 | + runcnt += 1; | |
| 1179 | + } | |
| 1180 | + else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_FORWARD | MOVEFLAG_RIGHT) ){ | |
| 1181 | + move_rx = (float)M_PI/4 * -1; | |
| 1182 | + AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, HUMAN_PROGRESSRUN_SIDEWAYSRUN_SPEED); | |
| 1183 | + legmode = LEG_RUN; | |
| 1184 | + walkcnt = 0; | |
| 1185 | + runcnt += 1; | |
| 1186 | + } | |
| 1187 | + else{ | |
| 1188 | + move_rx = 0.0f; | |
| 1189 | + legmode = LEG_STOP; | |
| 1190 | + walkcnt = 0; | |
| 1191 | + runcnt = 0; | |
| 1192 | + } | |
| 1193 | + | |
| 1194 | + //フラグをバックアップ | |
| 1195 | + MoveFlag_lt = MoveFlag; | |
| 1196 | + | |
| 1197 | + //キーフラグを元に戻す | |
| 1198 | + MoveFlag = 0x00; | |
| 1199 | +} | |
| 1200 | + | |
| 1201 | +//! 特定の方向(ベクトル)に対して、ブロックの面が表面か裏面か調べる | |
| 1202 | +//! @param inblockdata BlockDataInterfaceクラスのポインタ | |
| 1203 | +//! @param bid 判定するブロック番号 | |
| 1204 | +//! @param fid 判定する面番号 | |
| 1205 | +//! @param vx X軸ベクトルのポインタ | |
| 1206 | +//! @param vz Z軸ベクトルのポインタ | |
| 1207 | +//! @return 表向き:true 裏向き:false | |
| 1208 | +bool human::CheckBlockAngle(class BlockDataInterface *inblockdata, int bid, int fid, float vx, float vz) | |
| 1209 | +{ | |
| 1210 | + if( inblockdata == NULL ){ return false; } | |
| 1211 | + if( (bid < 0)||(inblockdata->GetTotaldatas() <= bid) ){ return false; } | |
| 1212 | + | |
| 1213 | + float costheta; | |
| 1214 | + struct blockdata bdata; | |
| 1215 | + | |
| 1216 | + inblockdata->Getdata(&bdata, bid); | |
| 1217 | + costheta = (vx * bdata.material[fid].vx + vz * bdata.material[fid].vz) / (sqrt(vx * vx + vz * vz) * sqrt(bdata.material[fid].vx * bdata.material[fid].vx + bdata.material[fid].vz * bdata.material[fid].vz)); | |
| 1218 | + if( acos(costheta) > (float)M_PI/2 ){ | |
| 1219 | + return true; | |
| 1220 | + } | |
| 1221 | + return false; | |
| 1222 | +} | |
| 1223 | + | |
| 1224 | +//! マップとの当たり判定 | |
| 1225 | +//! @param CollD Collisionクラスのポインタ | |
| 1226 | +//! @param inblockdata BlockDataInterfaceクラスのポインタ | |
| 1227 | +//! @param vx X軸ベクトルのポインタ | |
| 1228 | +//! @param vz Z軸ベクトルのポインタ | |
| 1229 | +//! @param speed 水平方向の移動速度 | |
| 1230 | +//! @param FallDist Y軸の移動量を取得するポインタ | |
| 1231 | +//! @return ブロックに埋まっている:true 埋まっていない:false | |
| 1232 | +//! @attention 与える vx vz のベクトルは正規化されている必要があります。 | |
| 1233 | +//! @attention 計算結果も vx vz に格納します。計算結果のベクトルは正規化されておらず、ベクトルの長さが新たな水平方向の移動速度を表します。 | |
| 1234 | +bool human::MapCollisionDetection(class Collision *CollD, class BlockDataInterface *inblockdata, float *vx, float *vz, float speed, float *FallDist) | |
| 1235 | +{ | |
| 1236 | + bool inside = false; | |
| 1237 | + int id; | |
| 1238 | + int face; | |
| 1239 | + float vy = 0.1f; | |
| 1240 | + float Dist; | |
| 1241 | + float FallDistance; | |
| 1242 | + float offset; | |
| 1243 | + | |
| 1244 | + //足元ギリギリは当たり判定から除外する | |
| 1245 | + offset = 0.1f; | |
| 1246 | + | |
| 1247 | + // 上下方向のあたり判定(ジャンプ・自然落下) | |
| 1248 | + //-------------------------------------------------- | |
| 1249 | + | |
| 1250 | + //足元がブロックに埋まっていなければ | |
| 1251 | + if( CollD->CheckALLBlockInside(pos_x, pos_y + offset, pos_z) == false ){ | |
| 1252 | + //落下速度を計算 | |
| 1253 | + move_y -= HUMAN_DAMAGE_SPEED; | |
| 1254 | + if( move_y < HUMAN_DAMAGE_MAXSPEED ){ move_y = HUMAN_DAMAGE_MAXSPEED; } | |
| 1255 | + | |
| 1256 | + if( move_y > 0.0f ){ | |
| 1257 | + //上方向へ当たり判定 | |
| 1258 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, 0, 1, 0, NULL, NULL, &Dist, move_y) == true ){ | |
| 1259 | + CollD->CheckALLBlockIntersectRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, 0, 1, 0, NULL, NULL, &Dist, move_y); | |
| 1260 | + | |
| 1261 | + FallDistance = Dist; | |
| 1262 | + move_y = 0.0f; | |
| 1263 | + } | |
| 1264 | + else{ | |
| 1265 | + FallDistance = move_y; | |
| 1266 | + } | |
| 1267 | + FallDistance = move_y; | |
| 1268 | + move_y_flag = true; | |
| 1269 | + } | |
| 1270 | + else{ | |
| 1271 | + int id, face; | |
| 1272 | + struct blockdata bdata; | |
| 1273 | + | |
| 1274 | + //下方向へ当たり判定 | |
| 1275 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + offset, pos_z, 0, -1, 0, NULL, NULL, &Dist, move_y*-1 + offset) == true ){ | |
| 1276 | + CollD->CheckALLBlockIntersectRay(pos_x, pos_y + offset, pos_z, 0, -1, 0, &id, &face, &Dist, move_y + offset); | |
| 1277 | + | |
| 1278 | + //ダメージ計算 | |
| 1279 | + if( move_y > HUMAN_DAMAGE_MINSPEED ){ hp -= 0; } | |
| 1280 | + else{ hp -= (int)((float)HUMAN_DAMAGE_MAXFALL / abs(HUMAN_DAMAGE_MAXSPEED - (HUMAN_DAMAGE_MINSPEED)) * abs(move_y - (HUMAN_DAMAGE_MINSPEED))); } | |
| 1281 | + | |
| 1282 | + FallDistance = (Dist - offset) * -1; | |
| 1283 | + move_y = 0.0f; | |
| 1284 | + | |
| 1285 | + inblockdata->Getdata(&bdata, id); | |
| 1286 | + | |
| 1287 | + //斜面に立っているなら | |
| 1288 | + if( acos(bdata.material[face].vy) > HUMAN_MAPCOLLISION_SLOPEANGLE ){ | |
| 1289 | + //地面と認めない (ジャンプ対策) | |
| 1290 | + move_y_flag = true; | |
| 1291 | + | |
| 1292 | + //押し出す | |
| 1293 | + AddPosOrder(atan2(bdata.material[face].vz, bdata.material[face].vx), HUMAN_MAPCOLLISION_SLOPEFORCE); | |
| 1294 | + } | |
| 1295 | + else{ | |
| 1296 | + move_y_flag = false; | |
| 1297 | + } | |
| 1298 | + } | |
| 1299 | + else{ | |
| 1300 | + FallDistance = move_y; | |
| 1301 | + move_y_flag = true; | |
| 1302 | + } | |
| 1303 | + } | |
| 1304 | + } | |
| 1305 | + else{ //埋まっている | |
| 1306 | + FallDistance = move_y; | |
| 1307 | + move_y = 0.0f; | |
| 1308 | + move_y_flag = false; | |
| 1309 | + } | |
| 1310 | + | |
| 1311 | + | |
| 1312 | + // 水平方向のあたり判定(移動) | |
| 1313 | + //-------------------------------------------------- | |
| 1314 | + | |
| 1315 | + if( speed > 0.0f ){ | |
| 1316 | + int surface; | |
| 1317 | + float ang = atan2(*vz, *vx); | |
| 1318 | + float newpos_x, newpos_y, newpos_z; | |
| 1319 | + | |
| 1320 | + //腰付近を当たり判定 | |
| 1321 | + for(int i=0; i<MAX_BLOCKS; i++){ | |
| 1322 | + surface = -1; | |
| 1323 | + CollD->CheckBlockInside(i, pos_x, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z, false, &surface); | |
| 1324 | + | |
| 1325 | + if( surface != -1 ){ | |
| 1326 | + //HUMAN_MAPCOLLISION_R 分の先を調べる | |
| 1327 | + if( CollD->CheckBlockInside(i, pos_x + cos(ang)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ | |
| 1328 | + CollD->ScratchVector(inblockdata, i, surface, *vx, vy, *vz, vx, &vy, vz); | |
| 1329 | + } | |
| 1330 | + | |
| 1331 | + //左右90度づつを調べる | |
| 1332 | + if( CollD->CheckBlockInside(i, pos_x + cos(ang + (float)M_PI/2)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang + (float)M_PI/2)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ | |
| 1333 | + if( CheckBlockAngle(inblockdata, i, surface, cos(ang), sin(ang)) == true ){ //進行方向に対して表向きなら〜 | |
| 1334 | + CollD->ScratchVector(inblockdata, i, surface, *vx, vy, *vz, vx, &vy, vz); | |
| 1335 | + } | |
| 1336 | + } | |
| 1337 | + if( CollD->CheckBlockInside(i, pos_x + cos(ang - (float)M_PI/2)*HUMAN_MAPCOLLISION_R, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z + sin(ang - (float)M_PI/2)*HUMAN_MAPCOLLISION_R, true, NULL) == true ){ | |
| 1338 | + if( CheckBlockAngle(inblockdata, i, surface, cos(ang), sin(ang)) == true ){ //進行方向に対して表向きなら〜 | |
| 1339 | + CollD->ScratchVector(inblockdata, i, surface, *vx, vy, *vz, vx, &vy, vz); | |
| 1340 | + } | |
| 1341 | + } | |
| 1342 | + } | |
| 1343 | + } | |
| 1344 | + | |
| 1345 | + //頭を当たり判定 | |
| 1346 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, *vx, 0, *vz, NULL, NULL, &Dist, speed) == true ){ | |
| 1347 | + CollD->CheckALLBlockIntersectRay(pos_x, pos_y + FallDistance + HUMAN_HEIGTH, pos_z, *vx, 0, *vz, &id, &face, &Dist, speed); | |
| 1348 | + CollD->ScratchVector(inblockdata, id, face, *vx, vy, *vz, vx, &vy, vz); | |
| 1349 | + } | |
| 1350 | + | |
| 1351 | + //足元がブロックに埋まっていなければ | |
| 1352 | + if( CollD->CheckALLBlockInside(pos_x, pos_y + offset, pos_z) == false ){ | |
| 1353 | + | |
| 1354 | + //足元を当たり判定 | |
| 1355 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + offset, pos_z, *vx, 0, *vz, NULL, NULL, &Dist, speed) == true ){ | |
| 1356 | + CollD->CheckALLBlockIntersectRay(pos_x, pos_y + offset, pos_z, *vx, 0, *vz, &id, &face, &Dist, speed); | |
| 1357 | + | |
| 1358 | + struct blockdata bdata; | |
| 1359 | + inblockdata->Getdata(&bdata, id); | |
| 1360 | + | |
| 1361 | + if( acos(bdata.material[face].vy) > HUMAN_MAPCOLLISION_SLOPEANGLE ){ //斜面〜壁なら | |
| 1362 | + //乗り越えられる高さか調べる | |
| 1363 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + 3.5f + offset, pos_z, *vx, 0, *vz, NULL, NULL, &Dist, speed) == false ){ | |
| 1364 | + //人を上に持ち上げる | |
| 1365 | + FallDistance = 0.3f; | |
| 1366 | + move_y = 0.0f; | |
| 1367 | + } | |
| 1368 | + | |
| 1369 | + //足元を当たり判定 | |
| 1370 | + CollD->ScratchVector(inblockdata, id, face, *vx, vy, *vz, vx, &vy, vz); | |
| 1371 | + } | |
| 1372 | + else{ //水平〜斜面なら | |
| 1373 | + //移動先の位置を計算 | |
| 1374 | + newpos_x = pos_x + *vx * speed; | |
| 1375 | + newpos_y = pos_y + FallDistance; | |
| 1376 | + newpos_z = pos_z + *vz * speed; | |
| 1377 | + | |
| 1378 | + //移動先の高さを調べる | |
| 1379 | + if( CollD->CheckALLBlockInside(newpos_x, newpos_y + HUMAN_HEIGTH, newpos_z) == false ){ | |
| 1380 | + if( CollD->CheckALLBlockIntersectRay(newpos_x, newpos_y + HUMAN_HEIGTH, newpos_z, 0, -1, 0, NULL, NULL, &Dist, HUMAN_HEIGTH) == true ){ | |
| 1381 | + float height = HUMAN_HEIGTH - Dist; | |
| 1382 | + | |
| 1383 | + if( height > 0.6f * speed ){ | |
| 1384 | + //人を上に持ち上げる | |
| 1385 | + FallDistance = 0.3f; | |
| 1386 | + move_y = 0.0f; | |
| 1387 | + } | |
| 1388 | + else{ | |
| 1389 | + FallDistance = height; | |
| 1390 | + move_y = 0.0f; | |
| 1391 | + } | |
| 1392 | + } | |
| 1393 | + } | |
| 1394 | + } | |
| 1395 | + } | |
| 1396 | + } | |
| 1397 | + | |
| 1398 | + //移動先の位置を計算 | |
| 1399 | + newpos_x = pos_x + *vx * speed; | |
| 1400 | + newpos_y = pos_y + FallDistance; | |
| 1401 | + newpos_z = pos_z + *vz * speed; | |
| 1402 | + | |
| 1403 | + //全身を改めて確認 | |
| 1404 | + if( | |
| 1405 | + (CollD->CheckALLBlockInside(newpos_x, newpos_y + offset, newpos_z) == true)|| | |
| 1406 | + (CollD->CheckALLBlockIntersectRay(newpos_x, newpos_y + offset, newpos_z, 0, 1, 0, NULL, NULL, &Dist, HUMAN_HEIGTH - offset - 1.0f) == true) | |
| 1407 | + ){ | |
| 1408 | + //めり込むなら移動しない | |
| 1409 | + *vx = 0.0f; | |
| 1410 | + *vz = 0.0f; | |
| 1411 | + inside = true; | |
| 1412 | + } | |
| 1413 | + } | |
| 1414 | + | |
| 1415 | + *FallDist = FallDistance; | |
| 1416 | + return inside; | |
| 1417 | +} | |
| 1418 | + | |
| 1419 | +//! 計算を実行(当たり判定) | |
| 1420 | +//! @param CollD Collisionのポインタ | |
| 1421 | +//! @param inblockdata BlockDataInterfaceのポインタ | |
| 1422 | +//! @param F5mode 上昇機能(F5裏技)のフラグ (有効:true 無効:false) | |
| 1423 | +int human::RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata, bool F5mode) | |
| 1424 | +{ | |
| 1425 | + if( CollD == NULL ){ return 0; } | |
| 1426 | + if( RenderFlag == false ){ return 0; } | |
| 1427 | + | |
| 1428 | +#ifdef HUMAN_DEADBODY_COLLISION | |
| 1429 | + if( deadstate == 4 ){ return 0; } | |
| 1430 | +#else | |
| 1431 | + if( hp <= 0 ){ return 0; } | |
| 1432 | +#endif | |
| 1433 | + | |
| 1434 | + float vx, vz; | |
| 1435 | + bool inside; | |
| 1436 | + | |
| 1437 | + float FallDistance; | |
| 1438 | + float move_speed; | |
| 1439 | + | |
| 1440 | + //武器切り替えカウント | |
| 1441 | + if( selectweaponcnt > 0 ){ | |
| 1442 | + selectweaponcnt -= 1; | |
| 1443 | + } | |
| 1444 | + | |
| 1445 | + //発砲による反動 | |
| 1446 | + if( reaction_y > 0.0f ){ | |
| 1447 | + if( reaction_y > (float)M_PI/180*2 ){ reaction_y -= (float)M_PI/180*2; } | |
| 1448 | + else{ reaction_y = 0.0f; } | |
| 1449 | + } | |
| 1450 | + if( reaction_y < 0.0f ){ | |
| 1451 | + if( reaction_y < (float)M_PI/180*2 ){ reaction_y += (float)M_PI/180*2; } | |
| 1452 | + else{ reaction_y = 0.0f; } | |
| 1453 | + } | |
| 1454 | + | |
| 1455 | + //照準の状態誤差の処理 | |
| 1456 | + GunsightErrorRange(); | |
| 1457 | + | |
| 1458 | + //死亡判定と倒れる処理 | |
| 1459 | + if( CheckAndProcessDead(CollD) != 0 ){ return 0; } | |
| 1460 | + | |
| 1461 | + //進行方向と速度を決定 | |
| 1462 | + ControlProcess(); | |
| 1463 | + | |
| 1464 | + //進行方向を示すベクトルを算出 | |
| 1465 | + vx = addposorder_x; | |
| 1466 | + vz = addposorder_z; | |
| 1467 | + move_speed = sqrt(vx*vx + vz*vz); | |
| 1468 | + vx = vx / move_speed; | |
| 1469 | + vz = vz / move_speed; | |
| 1470 | + | |
| 1471 | + //移動量をゼロに戻す | |
| 1472 | + move_x = 0.0f; | |
| 1473 | + move_z = 0.0f; | |
| 1474 | + | |
| 1475 | + //要求移動量をゼロに戻す | |
| 1476 | + addposorder_x = 0.0f; | |
| 1477 | + addposorder_z = 0.0f; | |
| 1478 | + | |
| 1479 | + inside = MapCollisionDetection(CollD, inblockdata, &vx, &vz, move_speed, &FallDistance); | |
| 1480 | + | |
| 1481 | + //ブロックに埋まっていなければ | |
| 1482 | + if( inside == false ){ | |
| 1483 | + if( move_speed > 0.0f ){ | |
| 1484 | + //移動量決定 | |
| 1485 | + move_x = vx * move_speed; | |
| 1486 | + move_z = vz * move_speed; | |
| 1487 | + | |
| 1488 | + //座標移動 | |
| 1489 | + pos_x += move_x; | |
| 1490 | + pos_z += move_z; | |
| 1491 | + | |
| 1492 | + totalmove += abs(vx * move_speed) + abs(vz * move_speed); | |
| 1493 | + } | |
| 1494 | + } | |
| 1495 | + | |
| 1496 | + //F5を使用していなければ、計算結果を反映 | |
| 1497 | + if( F5mode == false ){ | |
| 1498 | + pos_y += FallDistance; | |
| 1499 | + } | |
| 1500 | + else{ | |
| 1501 | + move_y = 0.0f; | |
| 1502 | + pos_y += 5.0f; //使用していれば、強制的に上昇 | |
| 1503 | + } | |
| 1504 | + | |
| 1505 | + | |
| 1506 | + //-100.0より下に落ちたら、死亡 | |
| 1507 | + if( pos_y < HUMAN_DEADLINE ){ | |
| 1508 | + pos_y = HUMAN_DEADLINE; | |
| 1509 | + hp = 0; | |
| 1510 | + } | |
| 1511 | + | |
| 1512 | + return 0; | |
| 1513 | +} | |
| 1514 | + | |
| 1515 | +//! 標準誤差を取得 | |
| 1516 | +int human::GetGunsightErrorRange() | |
| 1517 | +{ | |
| 1518 | + return StateGunsightErrorRange + ReactionGunsightErrorRange; | |
| 1519 | +} | |
| 1520 | + | |
| 1521 | +//! 描画 | |
| 1522 | +//! @param d3dg D3DGraphicsのポインタ | |
| 1523 | +//! @param Resource ResourceManagerのポインタ | |
| 1524 | +//! @param DrawArm 腕と武器のみ描画する | |
| 1525 | +//! @todo 腕の位置を行列で求める | |
| 1526 | +//! @todo 死体の部位の高さ(Y軸)がおかしい | |
| 1527 | +void human::Render(class D3DGraphics *d3dg, class ResourceManager *Resource, bool DrawArm) | |
| 1528 | +{ | |
| 1529 | + //正しく初期化されていなければ、処理しない | |
| 1530 | + if( d3dg == NULL ){ return; } | |
| 1531 | + if( RenderFlag == false ){ return; } | |
| 1532 | + | |
| 1533 | + //足の角度を、-90度〜90度の範囲に設定 | |
| 1534 | + float leg_rx; | |
| 1535 | + if( hp <= 0 ){ leg_rx = 0.0f; } | |
| 1536 | + else if( fabs(move_rx) > (float)M_PI/2 ){ leg_rx = move_rx + (float)M_PI; } | |
| 1537 | + else{ leg_rx = move_rx; } | |
| 1538 | + | |
| 1539 | + //現在装備する武器のクラスを取得 | |
| 1540 | + class weapon *nowweapon; | |
| 1541 | + nowweapon = weapon[selectweapon]; | |
| 1542 | + | |
| 1543 | + if( DrawArm == false ){ | |
| 1544 | + //上半身を描画 | |
| 1545 | + d3dg->SetWorldTransform(pos_x, pos_y - 1.0f, pos_z, rotation_x + (float)M_PI, rotation_y, upmodel_size); | |
| 1546 | + d3dg->RenderModel(id_upmodel, id_texture); | |
| 1547 | + | |
| 1548 | + //足を描画 | |
| 1549 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x + (float)M_PI + leg_rx*-1, rotation_y, legmodel_size); | |
| 1550 | + if( legmode == LEG_STOP ){ | |
| 1551 | + d3dg->RenderModel(id_legmodel, id_texture); | |
| 1552 | + } | |
| 1553 | + if( legmode == LEG_WALK ){ | |
| 1554 | + d3dg->RenderModel(id_walkmodel[ (walkcnt/3 % TOTAL_WALKMODE) ], id_texture); | |
| 1555 | + } | |
| 1556 | + if( legmode == LEG_RUN ){ | |
| 1557 | + d3dg->RenderModel(id_runmodel[ (runcnt/2 % TOTAL_RUNMODE) ], id_texture); | |
| 1558 | + } | |
| 1559 | + } | |
| 1560 | + | |
| 1561 | + //腕を描画 | |
| 1562 | + if( rotation_y != 0.0f ){ //死亡して倒れている or 倒れ始めた | |
| 1563 | + d3dg->SetWorldTransform(pos_x + cos(rotation_x*-1 - (float)M_PI/2)*sin(rotation_y)*16.0f, pos_y + cos(rotation_y)*16.0f, pos_z + sin(rotation_x*-1 - (float)M_PI/2)*sin(rotation_y)*16.0f, | |
| 1564 | + rotation_x + (float)M_PI, armrotation_y + rotation_y, armmodel_size); | |
| 1565 | + d3dg->RenderModel(id_armmodel[0], id_texture); | |
| 1566 | + } | |
| 1567 | + else if( nowweapon == NULL ){ //手ぶら | |
| 1568 | + d3dg->SetWorldTransform(pos_x, pos_y + 16.0f, pos_z, rotation_x + (float)M_PI, armrotation_y, armmodel_size); | |
| 1569 | + d3dg->RenderModel(id_armmodel[0], id_texture); | |
| 1570 | + } | |
| 1571 | + else{ //何か武器を持っている | |
| 1572 | + //武器のモデルとテクスチャを取得 | |
| 1573 | + int id_param; | |
| 1574 | + int armmodelid = 0; | |
| 1575 | + WeaponParameter paramdata; | |
| 1576 | + int model, texture; | |
| 1577 | + float ry; | |
| 1578 | + nowweapon->GetParamData(&id_param, NULL, NULL); | |
| 1579 | + Param->GetWeapon(id_param, ¶mdata); | |
| 1580 | + Resource->GetWeaponModelTexture(id_param, &model, &texture); | |
| 1581 | + | |
| 1582 | + //腕の形を決定 | |
| 1583 | + if( paramdata.WeaponP == 0 ){ | |
| 1584 | + armmodelid = 1; | |
| 1585 | + ry = armrotation_y + reaction_y; | |
| 1586 | + } | |
| 1587 | + if( paramdata.WeaponP == 1 ){ | |
| 1588 | + armmodelid = 2; | |
| 1589 | + ry = armrotation_y + reaction_y; | |
| 1590 | + } | |
| 1591 | + if( paramdata.WeaponP == 2 ){ | |
| 1592 | + armmodelid = 0; | |
| 1593 | + ry = ARMRAD_NOWEAPON; | |
| 1594 | + } | |
| 1595 | + | |
| 1596 | + //リロード時は角度を再設定 | |
| 1597 | + if( nowweapon->GetReloadCnt() > 0 ){ | |
| 1598 | + ry = ARMRAD_RELOADWEAPON; | |
| 1599 | + } | |
| 1600 | + | |
| 1601 | + //腕を描画 | |
| 1602 | + d3dg->SetWorldTransform(pos_x, pos_y + 16.0f, pos_z, rotation_x + (float)M_PI, ry, armmodel_size); | |
| 1603 | + d3dg->RenderModel(id_armmodel[armmodelid], id_texture); | |
| 1604 | + | |
| 1605 | + //武器を描画 | |
| 1606 | + d3dg->SetWorldTransformHumanWeapon(pos_x, pos_y + 16.0f, pos_z, paramdata.mx/10*-1, paramdata.my/10, paramdata.mz/10*-1, rotation_x + (float)M_PI, ry, paramdata.size); | |
| 1607 | + d3dg->RenderModel(model, texture); | |
| 1608 | + } | |
| 1609 | +} | |
| 1610 | + | |
| 1611 | +//! コンストラクタ | |
| 1612 | +weapon::weapon(class ParameterInfo *in_Param, float x, float y, float z, float rx, int id_param, int nbs, bool flag) | |
| 1613 | +{ | |
| 1614 | + Param = in_Param; | |
| 1615 | + pos_x = x; | |
| 1616 | + pos_y = y; | |
| 1617 | + pos_z = z; | |
| 1618 | + move_x = 0.0f; | |
| 1619 | + move_y = 0.0f; | |
| 1620 | + move_z = 0.0f; | |
| 1621 | + rotation_x = rx; | |
| 1622 | + RenderFlag = flag; | |
| 1623 | + | |
| 1624 | + id_parameter = id_param; | |
| 1625 | + usingflag = false; | |
| 1626 | + bullets = nbs; | |
| 1627 | + Loadbullets = 0; | |
| 1628 | + shotcnt = 0; | |
| 1629 | + motionflag = true; | |
| 1630 | + | |
| 1631 | + if( Param != NULL ){ | |
| 1632 | + WeaponParameter ParamData; | |
| 1633 | + if( Param->GetWeapon(id_param, &ParamData) == 0 ){ | |
| 1634 | + model_size = ParamData.size; | |
| 1635 | + //id_model = ParamData.id_model; | |
| 1636 | + //id_texture = ParamData.id_texture; | |
| 1637 | + } | |
| 1638 | + } | |
| 1639 | + id_model = -1; | |
| 1640 | + id_texture = -1; | |
| 1641 | +} | |
| 1642 | + | |
| 1643 | +//! ディストラクタ | |
| 1644 | +weapon::~weapon() | |
| 1645 | +{} | |
| 1646 | + | |
| 1647 | +//! 座標と角度を設定 | |
| 1648 | +//! @param x X座標 | |
| 1649 | +//! @param y Y座標 | |
| 1650 | +//! @param z Z座標 | |
| 1651 | +//! @param rx 横軸回転 | |
| 1652 | +void weapon::SetPosData(float x, float y, float z, float rx) | |
| 1653 | +{ | |
| 1654 | + pos_x = x; | |
| 1655 | + pos_y = y; | |
| 1656 | + pos_z = z; | |
| 1657 | + move_x = 0.0f; | |
| 1658 | + move_y = 0.0f; | |
| 1659 | + move_z = 0.0f; | |
| 1660 | + rotation_x = rx; | |
| 1661 | +} | |
| 1662 | + | |
| 1663 | +//! 設定値を設定 | |
| 1664 | +//! @param id_param 武器の種類番号 | |
| 1665 | +//! @param lnbs 装弾数 | |
| 1666 | +//! @param nbs 合計弾数 | |
| 1667 | +//! @param init オブジェクトを初期化 | |
| 1668 | +void weapon::SetParamData(int id_param, int lnbs, int nbs, bool init) | |
| 1669 | +{ | |
| 1670 | + id_parameter = id_param; | |
| 1671 | + usingflag = false; | |
| 1672 | + bullets = nbs; | |
| 1673 | + Loadbullets = lnbs; | |
| 1674 | + | |
| 1675 | + if( init == true ){ | |
| 1676 | + shotcnt = 0; | |
| 1677 | + reloadcnt = 0; | |
| 1678 | + motionflag = true; | |
| 1679 | + } | |
| 1680 | +} | |
| 1681 | + | |
| 1682 | +//! 設定値を取得 | |
| 1683 | +//! @param id_param 武器の種類番号を受け取るポインタ(NULL可) | |
| 1684 | +//! @param lnbs 装弾数を受け取るポインタ(NULL可) | |
| 1685 | +//! @param nbs 合計弾数を受け取るポインタ(NULL可) | |
| 1686 | +void weapon::GetParamData(int *id_param, int *lnbs, int *nbs) | |
| 1687 | +{ | |
| 1688 | + if( id_param != NULL ){ *id_param = id_parameter; } | |
| 1689 | + if( lnbs != NULL ){ *lnbs = Loadbullets; } | |
| 1690 | + if( nbs != NULL ){ *nbs = bullets; } | |
| 1691 | +} | |
| 1692 | + | |
| 1693 | +//! 武器の使用状況の取得 | |
| 1694 | +//! @return 使用中:true 未使用:false | |
| 1695 | +bool weapon::GetUsingFlag() | |
| 1696 | +{ | |
| 1697 | + return usingflag; | |
| 1698 | +} | |
| 1699 | + | |
| 1700 | +//! 武器を拾う | |
| 1701 | +//! @return 成功:0 失敗:1 | |
| 1702 | +int weapon::Pickup() | |
| 1703 | +{ | |
| 1704 | + if( usingflag == true ){ return 1; } | |
| 1705 | + usingflag = true; | |
| 1706 | + return 0; | |
| 1707 | +} | |
| 1708 | + | |
| 1709 | +//! 武器を捨てる | |
| 1710 | +//! @param x X座標 | |
| 1711 | +//! @param y Y座標 | |
| 1712 | +//! @param z Z座標 | |
| 1713 | +//! @param rx 横軸回転 | |
| 1714 | +//! @param speed 捨てる初速 | |
| 1715 | +void weapon::Dropoff(float x, float y, float z, float rx, float speed) | |
| 1716 | +{ | |
| 1717 | + //表示する座標と角度を設定 | |
| 1718 | + move_x = cos(rx*-1 + (float)M_PI/2) * speed; | |
| 1719 | + move_y = 0.0f; | |
| 1720 | + move_z = sin(rx*-1 + (float)M_PI/2) * speed; | |
| 1721 | + pos_x = x + cos(rx*-1 + (float)M_PI/2) * 5.0f; | |
| 1722 | + pos_y = y + 16.0f + move_y; | |
| 1723 | + pos_z = z + sin(rx*-1 + (float)M_PI/2) * 5.0f; | |
| 1724 | + rotation_x = rx + (float)M_PI; | |
| 1725 | + | |
| 1726 | + //未使用(未装備)に設定し、座標移動を有効に | |
| 1727 | + usingflag = false; | |
| 1728 | + motionflag = true; | |
| 1729 | +} | |
| 1730 | + | |
| 1731 | +//! 発砲 | |
| 1732 | +//! @return 成功:0 失敗:1 | |
| 1733 | +//! @attention 連射間隔も考慮されます。 | |
| 1734 | +//! @attention 関数が失敗するのは、いずれかの条件です。 「連射間隔に満たない」「リロード実行中」「弾がない」「無効な武器の種類が設定されている」 | |
| 1735 | +int weapon::Shot() | |
| 1736 | +{ | |
| 1737 | + //クラスが設定されていなければ失敗 | |
| 1738 | + if( Param == NULL ){ return 1; } | |
| 1739 | + | |
| 1740 | + //発射間隔に満たないか、リロード中か、弾が無ければ失敗 | |
| 1741 | + if( shotcnt > 0 ){ return 1; } | |
| 1742 | + if( reloadcnt > 0 ){ return 1; } | |
| 1743 | + if( Loadbullets == 0 ){ return 1; } | |
| 1744 | + | |
| 1745 | + //設定値を取得 | |
| 1746 | + WeaponParameter ParamData; | |
| 1747 | + if( Param->GetWeapon(id_parameter, &ParamData) == 1 ){ return 1; } | |
| 1748 | + | |
| 1749 | + //武器が手榴弾ならば〜 | |
| 1750 | + if( id_parameter == ID_WEAPON_GRENADE ){ | |
| 1751 | + //弾を減らし、連射カウントを設定 | |
| 1752 | + bullets -= 1; | |
| 1753 | + shotcnt = ParamData.blazings; | |
| 1754 | + | |
| 1755 | + //自動リロード | |
| 1756 | + if( bullets > 0 ){ | |
| 1757 | + Loadbullets = 1; | |
| 1758 | + } | |
| 1759 | + else{ | |
| 1760 | + Loadbullets = 0; | |
| 1761 | + } | |
| 1762 | + | |
| 1763 | + //弾が無くなれば、武器ごと消滅させる。 | |
| 1764 | + if( bullets <= 0 ){ | |
| 1765 | + RenderFlag = false; | |
| 1766 | + usingflag = false; | |
| 1767 | + } | |
| 1768 | + return 0; | |
| 1769 | + } | |
| 1770 | + | |
| 1771 | + //弾を減らし、連射カウントを設定 | |
| 1772 | + Loadbullets -= 1; | |
| 1773 | + bullets -= 1; | |
| 1774 | + shotcnt = ParamData.blazings; | |
| 1775 | + return 0; | |
| 1776 | +} | |
| 1777 | + | |
| 1778 | +//! リロードを開始 | |
| 1779 | +//! @return 成功:0 失敗:1 | |
| 1780 | +//! @attention リロード時間も考慮されます。 | |
| 1781 | +//! @attention 関数が失敗するのは、いずれかの条件です。 「リロード実行中」「弾がない」「無効な武器の種類が設定されている」 | |
| 1782 | +int weapon::StartReload() | |
| 1783 | +{ | |
| 1784 | + //クラスが設定されていなければ失敗 | |
| 1785 | + if( Param == NULL ){ return 1; } | |
| 1786 | + | |
| 1787 | + //リロード中か、弾が無ければ失敗 | |
| 1788 | + if( reloadcnt > 0 ){ return 1; } | |
| 1789 | + if( (bullets - Loadbullets) == 0 ){ return 1; } | |
| 1790 | + | |
| 1791 | + //武器の性能値を取得 | |
| 1792 | + WeaponParameter ParamData; | |
| 1793 | + if( Param->GetWeapon(id_parameter, &ParamData) != 0 ){ return 1; } | |
| 1794 | + | |
| 1795 | + //リロードカウントを設定 | |
| 1796 | + reloadcnt = ParamData.reloads + 1; | |
| 1797 | + return 0; | |
| 1798 | +} | |
| 1799 | + | |
| 1800 | +//! リロードを実行 | |
| 1801 | +//! @attention StartReload()関数と異なり、瞬時に弾を補充します。リロード時間は考慮されません。 | |
| 1802 | +//! @attention リロード時間を考慮する場合、StartReload()関数を呼び出してください。この関数は自動的に実行されます。 | |
| 1803 | +int weapon::RunReload() | |
| 1804 | +{ | |
| 1805 | + //クラスが設定されていなければ失敗 | |
| 1806 | + if( Param == NULL ){ return 1; } | |
| 1807 | + | |
| 1808 | + //弾が無ければ失敗 | |
| 1809 | + if( (bullets - Loadbullets) == 0 ){ return 1; } | |
| 1810 | + | |
| 1811 | + //武器の性能値から、装填する弾数を取得 | |
| 1812 | + WeaponParameter ParamData; | |
| 1813 | + int nbsmax = 0; | |
| 1814 | + if( Param->GetWeapon(id_parameter, &ParamData) == 0 ){ | |
| 1815 | + nbsmax = ParamData.nbsmax; | |
| 1816 | + } | |
| 1817 | + | |
| 1818 | + if( (bullets - Loadbullets) < nbsmax ){ //残りの弾数より装填する弾数が多ければ | |
| 1819 | + bullets = (bullets - Loadbullets); | |
| 1820 | + Loadbullets = bullets; | |
| 1821 | + } | |
| 1822 | + else{ //残りの弾数の方が多ければ | |
| 1823 | + bullets -= Loadbullets; | |
| 1824 | + Loadbullets = nbsmax; | |
| 1825 | + } | |
| 1826 | + | |
| 1827 | + return 0; | |
| 1828 | +} | |
| 1829 | + | |
| 1830 | +//! リロードカウントを取得 | |
| 1831 | +//! @return カウント数 (リロード中:1以上) | |
| 1832 | +int weapon::GetReloadCnt() | |
| 1833 | +{ | |
| 1834 | + return reloadcnt; | |
| 1835 | +} | |
| 1836 | + | |
| 1837 | +//! 武器の種類・装弾数の変更 | |
| 1838 | +//! @param Resource ResourceManagerのポインタ | |
| 1839 | +//! @param id_param 種類番号 | |
| 1840 | +//! @param lnbs 装弾数 | |
| 1841 | +//! @param nbs 合計弾数 | |
| 1842 | +//! @return 成功:1 失敗:0 | |
| 1843 | +//! @attention プレイヤーによる裏技(F6・F7)用に用意された関数です。手榴弾が選択された場合、自動的に弾を補充します。 | |
| 1844 | +//! @attention 使用されていない武器オブジェクトに対して実行すると、この関数は失敗します。 | |
| 1845 | +bool weapon::ResetWeaponParam(class ResourceManager *Resource, int id_param, int lnbs, int nbs) | |
| 1846 | +{ | |
| 1847 | + //初期化されていなければ、失敗 | |
| 1848 | + if( RenderFlag == false ){ return 0; } | |
| 1849 | + | |
| 1850 | + //指定された設定値へ上書き | |
| 1851 | + id_parameter = id_param; | |
| 1852 | + bullets = nbs; | |
| 1853 | + Loadbullets = lnbs; | |
| 1854 | + | |
| 1855 | + //もし手榴弾ならば、自動リロード | |
| 1856 | + if( id_param == ID_WEAPON_GRENADE ){ | |
| 1857 | + if( (bullets > 0)&&(Loadbullets == 0) ){ | |
| 1858 | + Loadbullets = 1; | |
| 1859 | + } | |
| 1860 | + } | |
| 1861 | + | |
| 1862 | + //モデルとテクスチャを設定 | |
| 1863 | + Resource->GetWeaponModelTexture(id_param, &id_model, &id_texture); | |
| 1864 | + WeaponParameter param; | |
| 1865 | + if( Param->GetWeapon(id_param, ¶m) == 0 ){ | |
| 1866 | + model_size = param.size; | |
| 1867 | + } | |
| 1868 | + | |
| 1869 | + return 1; | |
| 1870 | +} | |
| 1871 | + | |
| 1872 | +//! 計算を実行(自由落下) | |
| 1873 | +//! @param CollD Collisionのポインタ | |
| 1874 | +int weapon::RunFrame(class Collision *CollD) | |
| 1875 | +{ | |
| 1876 | + //クラスが設定されていなければ失敗 | |
| 1877 | + if( CollD == NULL ){ return 0; } | |
| 1878 | + | |
| 1879 | + //初期化されていなければ、失敗 | |
| 1880 | + if( RenderFlag == false ){ return 0; } | |
| 1881 | + | |
| 1882 | + //連射カウントが残っていれば、1 減らす | |
| 1883 | + if( shotcnt > 0 ){ | |
| 1884 | + shotcnt -= 1; | |
| 1885 | + } | |
| 1886 | + else if( reloadcnt > 0 ){ | |
| 1887 | + //リロードカウントが残っていれば 1 減らし、カウントが 0 ならばリロード処理を実行 | |
| 1888 | + reloadcnt -= 1; | |
| 1889 | + if( reloadcnt == 0 ){ | |
| 1890 | + RunReload(); | |
| 1891 | + } | |
| 1892 | + } | |
| 1893 | + | |
| 1894 | + //誰にも使われておらず、移動フラグが有効ならば〜 | |
| 1895 | + if( (usingflag == false)&&(motionflag == true) ){ | |
| 1896 | + float Dist; | |
| 1897 | + float maxDist; | |
| 1898 | + | |
| 1899 | + //移動速度を更新 | |
| 1900 | + move_x *= 0.96f; | |
| 1901 | + move_z *= 0.96f; | |
| 1902 | + if( move_y > -1.8f ){ | |
| 1903 | + move_y -= 0.3f; | |
| 1904 | + } | |
| 1905 | + | |
| 1906 | + //ブロックに埋まっていれば処理しない | |
| 1907 | + if( CollD->CheckALLBlockInside(pos_x, pos_y, pos_z) == true ){ | |
| 1908 | + motionflag = false; | |
| 1909 | + return 0; | |
| 1910 | + } | |
| 1911 | + | |
| 1912 | + //水平の移動速度を求める | |
| 1913 | + maxDist = sqrt(move_x*move_x + move_z*move_z); | |
| 1914 | + if( maxDist < 0.1f ){ | |
| 1915 | + maxDist = 0.0f; | |
| 1916 | + move_x = 0.0f; | |
| 1917 | + move_z = 0.0f; | |
| 1918 | + } | |
| 1919 | + | |
| 1920 | + //ブロックに接していれば、それ以上は水平移動しない。 | |
| 1921 | + if( maxDist > 0.0f ){ | |
| 1922 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y, pos_z, move_x/maxDist, 0, move_z/maxDist, NULL, NULL, &Dist, maxDist) == true ){ | |
| 1923 | + //ブロックに埋まらないように手前に | |
| 1924 | + Dist -= 0.1f; | |
| 1925 | + | |
| 1926 | + //接している座標まで移動 | |
| 1927 | + pos_x += move_x/maxDist * Dist; | |
| 1928 | + pos_z += move_z/maxDist * Dist; | |
| 1929 | + | |
| 1930 | + //移動量を 0 に | |
| 1931 | + move_x = 0.0f; | |
| 1932 | + move_z = 0.0f; | |
| 1933 | + } | |
| 1934 | + } | |
| 1935 | + | |
| 1936 | + //ブロックに接していれば、そこまで落下する | |
| 1937 | + if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, abs(move_y)) == true ){ | |
| 1938 | + CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, abs(move_y)); | |
| 1939 | + pos_y -= Dist - 0.2f; | |
| 1940 | + motionflag = false; | |
| 1941 | + return 0; | |
| 1942 | + } | |
| 1943 | + | |
| 1944 | + //座標を反映 | |
| 1945 | + pos_x += move_x; | |
| 1946 | + pos_y += move_y; | |
| 1947 | + pos_z += move_z; | |
| 1948 | + } | |
| 1949 | + | |
| 1950 | + return 0; | |
| 1951 | +} | |
| 1952 | + | |
| 1953 | +//! 描画 | |
| 1954 | +//! @param d3dg D3DGraphicsのポインタ | |
| 1955 | +void weapon::Render(class D3DGraphics *d3dg) | |
| 1956 | +{ | |
| 1957 | + //クラスが設定されていなければ失敗 | |
| 1958 | + if( d3dg == NULL ){ return; } | |
| 1959 | + | |
| 1960 | + //初期化されてないか、誰かに使われていれば処理しない | |
| 1961 | + if( RenderFlag == false ){ return; } | |
| 1962 | + if( usingflag == true ){ return; } | |
| 1963 | + | |
| 1964 | + //武器を描画 | |
| 1965 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, 0.0f, (float)M_PI/2, model_size); | |
| 1966 | + d3dg->RenderModel(id_model, id_texture); | |
| 1967 | +} | |
| 1968 | + | |
| 1969 | +//! コンストラクタ | |
| 1970 | +smallobject::smallobject(class ParameterInfo *in_Param, class MIFInterface *in_MIFdata, float x, float y, float z, float rx, int id_param, signed char p4, bool flag) | |
| 1971 | +{ | |
| 1972 | + Param = in_Param; | |
| 1973 | + pos_x = x; | |
| 1974 | + pos_y = y; | |
| 1975 | + pos_z = z; | |
| 1976 | + rotation_x = rx; | |
| 1977 | + rotation_y = 0.0f; | |
| 1978 | + RenderFlag = flag; | |
| 1979 | + model_size = 5.0f; | |
| 1980 | + | |
| 1981 | + id_parameter = id_param; | |
| 1982 | + point_p4 = p4; | |
| 1983 | + | |
| 1984 | + hp = 0; //暫定 | |
| 1985 | + jump_rx = 0.0f; | |
| 1986 | + move_rx = 0.0f; | |
| 1987 | + add_rx = 0.0f; | |
| 1988 | + add_ry = 0.0f; | |
| 1989 | + jump_cnt = 0; | |
| 1990 | + | |
| 1991 | + if( Param != NULL ){ | |
| 1992 | + SmallObjectParameter ParamData; | |
| 1993 | + if( Param->GetSmallObject(id_param, &ParamData) == 0 ){ | |
| 1994 | + hp = ParamData.hp; | |
| 1995 | + } | |
| 1996 | + } | |
| 1997 | + id_model = -1; | |
| 1998 | + id_texture = -1; | |
| 1999 | +} | |
| 2000 | + | |
| 2001 | +//! ディストラクタ | |
| 2002 | +smallobject::~smallobject() | |
| 2003 | +{} | |
| 2004 | + | |
| 2005 | +//! MIFデータを管理するクラスを設定 | |
| 2006 | +//! @param in_MIFdata MIFInterfaceクラスのポインタ | |
| 2007 | +void smallobject::SetMIFInterfaceClass(class MIFInterface *in_MIFdata) | |
| 2008 | +{ | |
| 2009 | + MIFdata = in_MIFdata; | |
| 2010 | +} | |
| 2011 | + | |
| 2012 | +//! 設定値を設定 | |
| 2013 | +//! @param id_param 小物の種類番号 | |
| 2014 | +//! @param p4 第4パラメータ | |
| 2015 | +//! @param init オブジェクトを初期化 | |
| 2016 | +void smallobject::SetParamData(int id_param, signed char p4, bool init) | |
| 2017 | +{ | |
| 2018 | + rotation_y = 0.0f; | |
| 2019 | + id_parameter = id_param; | |
| 2020 | + point_p4 = p4; | |
| 2021 | + | |
| 2022 | + if( init == true ){ | |
| 2023 | + hp = 0; //暫定 | |
| 2024 | + jump_rx = 0.0f; | |
| 2025 | + move_rx = 0.0f; | |
| 2026 | + add_rx = 0.0f; | |
| 2027 | + add_ry = 0.0f; | |
| 2028 | + jump_cnt = 0; | |
| 2029 | + | |
| 2030 | + if( id_param == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){ | |
| 2031 | + if( MIFdata != NULL ){ | |
| 2032 | + hp = MIFdata->GetAddSmallobjectHP(); | |
| 2033 | + } | |
| 2034 | + } | |
| 2035 | + else{ | |
| 2036 | + if( Param != NULL ){ | |
| 2037 | + SmallObjectParameter ParamData; | |
| 2038 | + if( Param->GetSmallObject(id_param, &ParamData) == 0 ){ | |
| 2039 | + hp = ParamData.hp; | |
| 2040 | + } | |
| 2041 | + } | |
| 2042 | + } | |
| 2043 | + } | |
| 2044 | +} | |
| 2045 | + | |
| 2046 | +//! 設定値を取得 | |
| 2047 | +//! @param id_param 小物の種類番号を受け取るポインタ(NULL可) | |
| 2048 | +//! @param p4 第4パラメータを受け取るポインタ(NULL可) | |
| 2049 | +void smallobject::GetParamData(int *id_param, signed char *p4) | |
| 2050 | +{ | |
| 2051 | + if( id_param != NULL ){ *id_param = id_parameter; } | |
| 2052 | + if( p4 != NULL ){ *p4 = point_p4; } | |
| 2053 | +} | |
| 2054 | + | |
| 2055 | +//! 体力を取得 | |
| 2056 | +// @return 体力値 | |
| 2057 | +int smallobject::GetHP() | |
| 2058 | +{ | |
| 2059 | + return hp; | |
| 2060 | +} | |
| 2061 | + | |
| 2062 | +//! ブロックの上に移動 | |
| 2063 | +//! @param CollD Collisionのポインタ | |
| 2064 | +//! @return 元の座標からの移動量(0で移動なし) | |
| 2065 | +float smallobject::CollisionMap(class Collision *CollD) | |
| 2066 | +{ | |
| 2067 | + //クラスが設定されていなければ失敗 | |
| 2068 | + if( CollD == NULL ){ return 0.0f; } | |
| 2069 | + | |
| 2070 | + float Dist; | |
| 2071 | + SmallObjectParameter ParamData; | |
| 2072 | + | |
| 2073 | + //ブロックに埋まっていれば、そのまま | |
| 2074 | + if( CollD->CheckALLBlockInside(pos_x, pos_y, pos_z) == true ){ return 0.0f; } | |
| 2075 | + | |
| 2076 | + //下方向に当たり判定 | |
| 2077 | + if( CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, 1000.0f) == true ){ | |
| 2078 | + //当たり判定の大きさを取得 | |
| 2079 | + if( id_parameter == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){ | |
| 2080 | + Dist -= (float)MIFdata->GetAddSmallobjectDecide()/10.0f; | |
| 2081 | + } | |
| 2082 | + else{ | |
| 2083 | + if( Param->GetSmallObject(id_parameter, &ParamData) == 0 ){ | |
| 2084 | + Dist -= (float)ParamData.decide/10.0f; | |
| 2085 | + } | |
| 2086 | + } | |
| 2087 | + | |
| 2088 | + //座標を移動する | |
| 2089 | + pos_y -= Dist; | |
| 2090 | + return Dist; | |
| 2091 | + } | |
| 2092 | + | |
| 2093 | + return 0.0f; | |
| 2094 | +} | |
| 2095 | + | |
| 2096 | +//! 弾がヒットした | |
| 2097 | +//! @param attacks 弾の攻撃力 | |
| 2098 | +void smallobject::HitBullet(int attacks) | |
| 2099 | +{ | |
| 2100 | + hp -= attacks; | |
| 2101 | + if( hp <= 0 ){ | |
| 2102 | + Destruction(); | |
| 2103 | + } | |
| 2104 | +} | |
| 2105 | + | |
| 2106 | +//! 手榴弾が爆発した | |
| 2107 | +//! @param CollD Collisionクラス | |
| 2108 | +//! @param tGrenade 爆発したgrenadeクラスのポインタ | |
| 2109 | +//! @return 破壊された:2 当たっただけ:1 当たっていない:0 | |
| 2110 | +int smallobject::GrenadeExplosion(class Collision *CollD, class grenade *tGrenade) | |
| 2111 | +{ | |
| 2112 | + //初期化されていないか、死亡していれば処理しない。 | |
| 2113 | + if( RenderFlag == false ){ return 0; } | |
| 2114 | + if( hp <= 0 ){ return 0; } | |
| 2115 | + | |
| 2116 | + //手榴弾の座標を取得し、距離を計算 | |
| 2117 | + float gre_x, gre_y, gre_z; | |
| 2118 | + float x, y, z, r; | |
| 2119 | + tGrenade->GetPosData(&gre_x, &gre_y, &gre_z, NULL, NULL); | |
| 2120 | + x = pos_x - gre_x; | |
| 2121 | + y = pos_y - gre_y; | |
| 2122 | + z = pos_z - gre_z; | |
| 2123 | + r = sqrt(x*x + y*y + z*z); | |
| 2124 | + | |
| 2125 | + //100.0より遠ければ計算しない | |
| 2126 | + if( r > MAX_DAMAGE_GRENADE_DISTANCE ){ return 0; } | |
| 2127 | + | |
| 2128 | + float dummy = 0.0f; | |
| 2129 | + | |
| 2130 | + //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ) | |
| 2131 | + if( CollD->CheckALLBlockIntersectRay(gre_x, gre_y, gre_z, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){ | |
| 2132 | + //ダメージ量を計算し、反映 | |
| 2133 | + hp -= SMALLOBJECT_DAMAGE_GRENADE - (int)((float)SMALLOBJECT_DAMAGE_GRENADE/MAX_DAMAGE_GRENADE_DISTANCE * r); | |
| 2134 | + if( hp <= 0 ){ | |
| 2135 | + Destruction(); | |
| 2136 | + return 2; | |
| 2137 | + } | |
| 2138 | + return 1; | |
| 2139 | + } | |
| 2140 | + | |
| 2141 | + return 0; | |
| 2142 | +} | |
| 2143 | + | |
| 2144 | +//! 小物を破壊する | |
| 2145 | +//! @attention 通常は HitBullet()関数 および GrenadeExplosion()関数 から自動的に実行されるため、直接呼び出す必要はありません。 | |
| 2146 | +void smallobject::Destruction() | |
| 2147 | +{ | |
| 2148 | + //RenderFlag = false; | |
| 2149 | + //return; | |
| 2150 | + | |
| 2151 | + //小物の設定値を取得 | |
| 2152 | + SmallObjectParameter paramdata; | |
| 2153 | + Param->GetSmallObject(id_parameter, ¶mdata); | |
| 2154 | + | |
| 2155 | + //飛ばす | |
| 2156 | + hp = 0; | |
| 2157 | + jump_cnt = paramdata.jump; | |
| 2158 | + | |
| 2159 | + //姿勢設定 | |
| 2160 | + jump_rx = (float)M_PI/18 * GetRand(36); | |
| 2161 | + move_rx = (float)paramdata.jump * 0.04243f; | |
| 2162 | + add_rx = (float)M_PI/180 * GetRand(20); | |
| 2163 | + add_ry = (float)M_PI/180 * GetRand(20); | |
| 2164 | +} | |
| 2165 | + | |
| 2166 | +//! 計算を実行(破壊時の移動など) | |
| 2167 | +int smallobject::RunFrame() | |
| 2168 | +{ | |
| 2169 | + //描画されていないか、体力が残っていなければ処理しない。 | |
| 2170 | + if( RenderFlag == false ){ return 0; } | |
| 2171 | + if( hp > 0 ){ return 0; } | |
| 2172 | + | |
| 2173 | + int cnt; | |
| 2174 | + SmallObjectParameter paramdata; | |
| 2175 | + | |
| 2176 | + //吹き飛んでいるカウント数を計算 | |
| 2177 | + cnt = Param->GetSmallObject(id_parameter, ¶mdata) - jump_cnt; | |
| 2178 | + | |
| 2179 | + //姿勢から座標・角度を計算 | |
| 2180 | + pos_x += cos(jump_rx) * move_rx; | |
| 2181 | + pos_y += jump_cnt * 0.1f; | |
| 2182 | + pos_z += sin(jump_rx) * move_rx; | |
| 2183 | + rotation_x += add_rx; | |
| 2184 | + rotation_y += add_ry; | |
| 2185 | + | |
| 2186 | + jump_cnt -= 1; | |
| 2187 | + | |
| 2188 | + //1秒飛んでいたら描画終了 | |
| 2189 | + if( cnt > (int)GAMEFPS ){ | |
| 2190 | + RenderFlag = false; | |
| 2191 | + return 2; | |
| 2192 | + } | |
| 2193 | + | |
| 2194 | + return 1; | |
| 2195 | +} | |
| 2196 | + | |
| 2197 | +//! 描画 | |
| 2198 | +//! @param d3dg D3DGraphicsのポインタ | |
| 2199 | +void smallobject::Render(D3DGraphics *d3dg) | |
| 2200 | +{ | |
| 2201 | + //クラスが設定されていなければ失敗 | |
| 2202 | + if( d3dg == NULL ){ return; } | |
| 2203 | + | |
| 2204 | + //初期化されていなければ処理しない。 | |
| 2205 | + if( RenderFlag == false ){ return; } | |
| 2206 | + | |
| 2207 | + //描画 | |
| 2208 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, rotation_y, model_size); | |
| 2209 | + d3dg->RenderModel(id_model, id_texture); | |
| 2210 | +} | |
| 2211 | + | |
| 2212 | +//! コンストラクタ | |
| 2213 | +bullet::bullet(int modelid, int textureid) | |
| 2214 | +{ | |
| 2215 | + model_size = 1.0f; | |
| 2216 | + id_model = modelid; | |
| 2217 | + id_texture = textureid; | |
| 2218 | + RenderFlag = false; | |
| 2219 | +} | |
| 2220 | + | |
| 2221 | +//! ディストラクタ | |
| 2222 | +bullet::~bullet() | |
| 2223 | +{} | |
| 2224 | + | |
| 2225 | +//! 座標と角度を設定 | |
| 2226 | +//! @param x X座標 | |
| 2227 | +//! @param y Y座標 | |
| 2228 | +//! @param z Z座標 | |
| 2229 | +//! @param rx 横軸回転 | |
| 2230 | +//! @param ry 縦軸回転 | |
| 2231 | +void bullet::SetPosData(float x, float y, float z, float rx, float ry) | |
| 2232 | +{ | |
| 2233 | + pos_x = x; | |
| 2234 | + pos_y = y; | |
| 2235 | + pos_z = z; | |
| 2236 | + rotation_x = rx; | |
| 2237 | + rotation_y = ry; | |
| 2238 | +} | |
| 2239 | + | |
| 2240 | +//! 設定値を設定 | |
| 2241 | +//! @param _attacks 攻撃力 | |
| 2242 | +//! @param _penetration 貫通力 | |
| 2243 | +//! @param _speed 弾速 | |
| 2244 | +//! @param _teamid チーム番号 | |
| 2245 | +//! @param _humanid 人のデータ番号 | |
| 2246 | +//! @param init オブジェクトを初期化 | |
| 2247 | +void bullet::SetParamData(int _attacks, int _penetration, int _speed, int _teamid, int _humanid, bool init) | |
| 2248 | +{ | |
| 2249 | + attacks = _attacks; | |
| 2250 | + penetration = _penetration; | |
| 2251 | + speed = _speed; | |
| 2252 | + teamid = _teamid; | |
| 2253 | + humanid = _humanid; | |
| 2254 | + | |
| 2255 | + if( init == true ){ | |
| 2256 | + cnt = 0; | |
| 2257 | + } | |
| 2258 | +} | |
| 2259 | + | |
| 2260 | +//! 座標と角度を取得 | |
| 2261 | +//! @param x X座標を受け取るポインタ(NULL可) | |
| 2262 | +//! @param y Y座標を受け取るポインタ(NULL可) | |
| 2263 | +//! @param z Z座標を受け取るポインタ(NULL可) | |
| 2264 | +//! @param rx 横軸回転を受け取るポインタ(NULL可) | |
| 2265 | +//! @param ry 縦軸回転を受け取るポインタ(NULL可) | |
| 2266 | +void bullet::GetPosData(float *x, float *y, float *z, float *rx, float *ry) | |
| 2267 | +{ | |
| 2268 | + if( x != NULL ){ *x = pos_x; } | |
| 2269 | + if( y != NULL ){ *y = pos_y; } | |
| 2270 | + if( z != NULL ){ *z = pos_z; } | |
| 2271 | + if( rx != NULL ){ *rx = rotation_x; } | |
| 2272 | + if( ry != NULL ){ *ry = rotation_y; } | |
| 2273 | +} | |
| 2274 | + | |
| 2275 | +//! 設定値を取得 | |
| 2276 | +//! @param _attacks 攻撃力を受け取るポインタ(NULL可) | |
| 2277 | +//! @param _penetration 貫通力を受け取るポインタ(NULL可) | |
| 2278 | +//! @param _speed 弾速を受け取るポインタ(NULL可) | |
| 2279 | +//! @param _teamid チーム番号を受け取るポインタ(NULL可) | |
| 2280 | +//! @param _humanid 人のデータ番号を受け取るポインタ(NULL可) | |
| 2281 | +void bullet::GetParamData(int *_attacks, int *_penetration, int *_speed, int *_teamid, int *_humanid) | |
| 2282 | +{ | |
| 2283 | + if( _attacks != NULL ){ *_attacks = attacks; } | |
| 2284 | + if( _penetration != NULL ){ *_penetration = penetration; } | |
| 2285 | + if( _speed != NULL ){ *_speed = speed; } | |
| 2286 | + if( _teamid != NULL ){ *_teamid = teamid; } | |
| 2287 | + if( _humanid != NULL ){ *_humanid = humanid; } | |
| 2288 | +} | |
| 2289 | + | |
| 2290 | +//! 計算を実行(弾の進行・時間消滅) | |
| 2291 | +int bullet::RunFrame() | |
| 2292 | +{ | |
| 2293 | + //初期化されていなければ処理しない | |
| 2294 | + if( RenderFlag == false ){ return 0; } | |
| 2295 | + | |
| 2296 | + //消滅時間を過ぎていれば、オブジェクトを無効化 | |
| 2297 | + if( cnt > BULLET_DESTROYFRAME ){ | |
| 2298 | + RenderFlag = false; | |
| 2299 | + return 0; | |
| 2300 | + } | |
| 2301 | + | |
| 2302 | + //移動処理 | |
| 2303 | + pos_x += cos(rotation_x)*cos(rotation_y)*speed; | |
| 2304 | + pos_y += sin(rotation_y)*speed; | |
| 2305 | + pos_z += sin(rotation_x)*cos(rotation_y)*speed; | |
| 2306 | + cnt += 1; | |
| 2307 | + | |
| 2308 | + return 0; | |
| 2309 | +} | |
| 2310 | + | |
| 2311 | +//! 描画 | |
| 2312 | +//! @param d3dg D3DGraphicsのポインタ | |
| 2313 | +void bullet::Render(class D3DGraphics *d3dg) | |
| 2314 | +{ | |
| 2315 | + //クラスが設定されていなければ失敗 | |
| 2316 | + if( d3dg == NULL ){ return; } | |
| 2317 | + | |
| 2318 | + //初期化されていなければ処理しない。 | |
| 2319 | + if( RenderFlag == false ){ return; } | |
| 2320 | + | |
| 2321 | + //弾を移動前だったら描画しない | |
| 2322 | + // 弾が頭から突き抜けて見える対策 | |
| 2323 | + if( cnt == 0 ){ return; } | |
| 2324 | + | |
| 2325 | + //描画 | |
| 2326 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), rotation_y, model_size); | |
| 2327 | + d3dg->RenderModel(id_model, id_texture); | |
| 2328 | +} | |
| 2329 | + | |
| 2330 | +//! コンストラクタ | |
| 2331 | +grenade::grenade(int modelid, int textureid) : bullet(modelid, textureid) | |
| 2332 | +{ | |
| 2333 | + if( Param != NULL ){ | |
| 2334 | + WeaponParameter ParamData; | |
| 2335 | + if( Param->GetWeapon(ID_WEAPON_GRENADE, &ParamData) == 0 ){ | |
| 2336 | + model_size = ParamData.size; | |
| 2337 | + } | |
| 2338 | + } | |
| 2339 | +} | |
| 2340 | + | |
| 2341 | +//! ディストラクタ | |
| 2342 | +grenade::~grenade() | |
| 2343 | +{} | |
| 2344 | + | |
| 2345 | +//! 座標と情報を設定 | |
| 2346 | +//! @param speed 初速 | |
| 2347 | +//! @param _humanid 人のデータ番号 | |
| 2348 | +//! @param init オブジェクトを初期化 | |
| 2349 | +//! @attention 先に SetPosData() を実行してください。 | |
| 2350 | +void grenade::SetParamData(float speed, int _humanid, bool init) | |
| 2351 | +{ | |
| 2352 | + move_x = cos(rotation_x) * cos(rotation_y) * speed; | |
| 2353 | + move_y = sin(rotation_y) * speed; | |
| 2354 | + move_z = sin(rotation_x) * cos(rotation_y) * speed; | |
| 2355 | + humanid = _humanid; | |
| 2356 | + | |
| 2357 | + if( init == true ){ | |
| 2358 | + cnt = 0; | |
| 2359 | + } | |
| 2360 | +} | |
| 2361 | + | |
| 2362 | +//! 計算を実行(手榴弾の進行・爆発) | |
| 2363 | +//! @return 爆発:2 バウンド・跳ね返り:1 それ以外:0 | |
| 2364 | +int grenade::RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata) | |
| 2365 | +{ | |
| 2366 | + //初期化されていなければ処理しない | |
| 2367 | + if( RenderFlag == false ){ return 0; } | |
| 2368 | + | |
| 2369 | + //時間を過ぎていれば、オブジェクトを無効化し、「爆発」として返す。 | |
| 2370 | + if( cnt > GRENADE_DESTROYFRAME ){ | |
| 2371 | + RenderFlag = false; | |
| 2372 | + return 2; | |
| 2373 | + } | |
| 2374 | + | |
| 2375 | + //静止していれば処理しない | |
| 2376 | + if( (move_x == 0.0f)&&(move_y == 0.0f)&&(move_z == 0.0f) ){ | |
| 2377 | + cnt += 1; | |
| 2378 | + return 0; | |
| 2379 | + } | |
| 2380 | + | |
| 2381 | + /* | |
| 2382 | + //静止に近い状態ならば、移動処理をしない。 | |
| 2383 | + if( (move_x*move_x + move_y*move_y + move_z*move_z) < 0.1f*0.1f ){ | |
| 2384 | + cnt += 1; | |
| 2385 | + return 0; | |
| 2386 | + } | |
| 2387 | + */ | |
| 2388 | + | |
| 2389 | + //移動速度を計算 | |
| 2390 | + move_x *= 0.98f; | |
| 2391 | + move_y = (move_y - 0.17f) * 0.98f; | |
| 2392 | + move_z *= 0.98f; | |
| 2393 | + | |
| 2394 | + int id, face; | |
| 2395 | + float Dist; | |
| 2396 | + float maxDist = sqrt(move_x*move_x + move_y*move_y + move_z*move_z); | |
| 2397 | + | |
| 2398 | + //マップに対して当たり判定を実行 | |
| 2399 | + if( CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, move_x/maxDist, move_y/maxDist, move_z/maxDist, &id, &face, &Dist, maxDist) == true ){ | |
| 2400 | + float vx, vy, vz; | |
| 2401 | + | |
| 2402 | + //マップと衝突する座標まで移動 | |
| 2403 | + pos_x += move_x/maxDist * (Dist - 0.1f); | |
| 2404 | + pos_y += move_y/maxDist * (Dist - 0.1f); | |
| 2405 | + pos_z += move_z/maxDist * (Dist - 0.1f); | |
| 2406 | + | |
| 2407 | + if( maxDist < 1.0f ){ | |
| 2408 | + move_x = 0.0f; | |
| 2409 | + move_y = 0.0f; | |
| 2410 | + move_z = 0.0f; | |
| 2411 | + } | |
| 2412 | + else{ | |
| 2413 | + //反射するベクトルを求める | |
| 2414 | + CollD->ReflectVector(inblockdata, id, face, move_x/maxDist, move_y/maxDist, move_z/maxDist, &vx, &vy, &vz); | |
| 2415 | + | |
| 2416 | + //減速 | |
| 2417 | + move_x = vx * maxDist * 0.63662f; | |
| 2418 | + move_y = vy * maxDist * 0.63662f; | |
| 2419 | + move_z = vz * maxDist * 0.63662f; | |
| 2420 | + } | |
| 2421 | + | |
| 2422 | + cnt += 1; | |
| 2423 | + return 1; | |
| 2424 | + } | |
| 2425 | + | |
| 2426 | + //座標を移動 | |
| 2427 | + pos_x += move_x; | |
| 2428 | + pos_y += move_y; | |
| 2429 | + pos_z += move_z; | |
| 2430 | + | |
| 2431 | + cnt += 1; | |
| 2432 | + return 0; | |
| 2433 | +} | |
| 2434 | + | |
| 2435 | +//! 描画 | |
| 2436 | +//! @param d3dg D3DGraphicsのポインタ | |
| 2437 | +void grenade::Render(class D3DGraphics *d3dg) | |
| 2438 | +{ | |
| 2439 | + //クラスが設定されていなければ失敗 | |
| 2440 | + if( d3dg == NULL ){ return; } | |
| 2441 | + | |
| 2442 | + //初期化されていなければ処理しない。 | |
| 2443 | + if( RenderFlag == false ){ return; } | |
| 2444 | + | |
| 2445 | + //描画 | |
| 2446 | + d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), 0.0f, (float)M_PI/2, model_size); | |
| 2447 | + d3dg->RenderModel(id_model, id_texture); | |
| 2448 | +} | |
| 2449 | + | |
| 2450 | +//! コンストラクタ | |
| 2451 | +effect::effect(float x, float y, float z, float size, float rotation, int count, int texture, int settype) | |
| 2452 | +{ | |
| 2453 | + pos_x = x; | |
| 2454 | + pos_y = y; | |
| 2455 | + pos_z = z; | |
| 2456 | + model_size = size; | |
| 2457 | + camera_rx = 0.0f; | |
| 2458 | + camera_ry = 0.0f; | |
| 2459 | + rotation_x = rotation; | |
| 2460 | + cnt = count; | |
| 2461 | + setcnt = count; | |
| 2462 | + id_texture = texture; | |
| 2463 | + type = settype; | |
| 2464 | + if( cnt > 0 ){ | |
| 2465 | + RenderFlag = true; | |
| 2466 | + } | |
| 2467 | + else{ | |
| 2468 | + RenderFlag = false; | |
| 2469 | + } | |
| 2470 | + alpha = 1.0f; | |
| 2471 | +} | |
| 2472 | + | |
| 2473 | +//! ディストラクタ | |
| 2474 | +effect::~effect() | |
| 2475 | +{} | |
| 2476 | + | |
| 2477 | +//! 設定値を設定 | |
| 2478 | +//! @param size 表示倍率 | |
| 2479 | +//! @param rotation 回転角度 | |
| 2480 | +//! @param count 表示フレーム数 | |
| 2481 | +//! @param texture テクスチャの認識番号 | |
| 2482 | +//! @param settype エフェクトの種類 (Effect_Type を組み合せる) | |
| 2483 | +//! @param init オブジェクトを初期化 | |
| 2484 | +void effect::SetParamData(float size, float rotation, int count, int texture, int settype, bool init) | |
| 2485 | +{ | |
| 2486 | + model_size = size; | |
| 2487 | + rotation_texture = rotation; | |
| 2488 | + cnt = count; | |
| 2489 | + setcnt = count; | |
| 2490 | + id_texture = texture; | |
| 2491 | + type = settype; | |
| 2492 | + alpha = 1.0f; | |
| 2493 | + | |
| 2494 | + if( init == true ){ | |
| 2495 | + camera_rx = 0.0f; | |
| 2496 | + camera_ry = 0.0f; | |
| 2497 | + } | |
| 2498 | +} | |
| 2499 | + | |
| 2500 | +//! 計算を実行(ビルボード化) | |
| 2501 | +//! @param in_camera_rx カメラの横軸角度 | |
| 2502 | +//! @param in_camera_ry カメラの縦軸角度 | |
| 2503 | +//! @return 処理実行:1 描画最終フレーム:2 処理なし:0 | |
| 2504 | +int effect::RunFrame(float in_camera_rx, float in_camera_ry) | |
| 2505 | +{ | |
| 2506 | + //初期化されていなければ処理しない | |
| 2507 | + if( RenderFlag == false ){ return 0; } | |
| 2508 | + | |
| 2509 | + //カウントが終了したら、処理しないように設定 | |
| 2510 | + if( cnt <= 0 ){ | |
| 2511 | + RenderFlag = false; | |
| 2512 | + return 2; | |
| 2513 | + } | |
| 2514 | + | |
| 2515 | + //カメラ座標を適用 | |
| 2516 | + camera_rx = in_camera_rx; | |
| 2517 | + camera_ry = in_camera_ry; | |
| 2518 | + | |
| 2519 | + //特殊処理を実行 | |
| 2520 | + if( type & EFFECT_DISAPPEAR ){ //消す | |
| 2521 | + alpha -= 1.0f/setcnt; | |
| 2522 | + } | |
| 2523 | + if( type & EFFECT_MAGNIFY ){ //拡大 | |
| 2524 | + model_size += model_size/50; | |
| 2525 | + } | |
| 2526 | + if( type & EFFECT_ROTATION ){ //回転 | |
| 2527 | + if( rotation_texture > 0.0f ){ | |
| 2528 | + rotation_texture += (float)M_PI/180*1; | |
| 2529 | + } | |
| 2530 | + else{ | |
| 2531 | + rotation_texture -= (float)M_PI/180*1; | |
| 2532 | + } | |
| 2533 | + } | |
| 2534 | + if( type & EFFECT_FALL ){ //落下 | |
| 2535 | + pos_y -= 1.0f; | |
| 2536 | + } | |
| 2537 | + else{ | |
| 2538 | + pos_y += 0.05f; | |
| 2539 | + } | |
| 2540 | + | |
| 2541 | + //カウントを 1 引く | |
| 2542 | + cnt -= 1; | |
| 2543 | + return 1; | |
| 2544 | +} | |
| 2545 | + | |
| 2546 | +//! 描画 | |
| 2547 | +//! @param d3dg D3DGraphicsのポインタ | |
| 2548 | +void effect::Render(class D3DGraphics *d3dg) | |
| 2549 | +{ | |
| 2550 | + //クラスが設定されていなければ失敗 | |
| 2551 | + if( d3dg == NULL ){ return; } | |
| 2552 | + | |
| 2553 | + //初期化されていなければ処理しない。 | |
| 2554 | + if( RenderFlag == false ){ return; } | |
| 2555 | + | |
| 2556 | + //描画 | |
| 2557 | + d3dg->SetWorldTransformEffect(pos_x, pos_y, pos_z, camera_rx*-1, camera_ry, rotation_texture, model_size); | |
| 2558 | + d3dg->RenderBoard(id_texture, alpha); | |
| 2559 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,1031 @@ | ||
| 1 | +//! @file datafile.cpp | |
| 2 | +//! @brief データ管理クラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "datafile.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +DataInterface::DataInterface() | |
| 36 | +{ | |
| 37 | + datas = 0; | |
| 38 | +} | |
| 39 | + | |
| 40 | +//! ディストラクタ | |
| 41 | +DataInterface::~DataInterface() | |
| 42 | +{} | |
| 43 | + | |
| 44 | +//! データファイルを読みこむ | |
| 45 | +//! @param fname ファイル名 | |
| 46 | +//! @return 成功:0 失敗:1 | |
| 47 | +int DataInterface::LoadFiledata(char *fname) | |
| 48 | +{ | |
| 49 | + return 0; | |
| 50 | +} | |
| 51 | + | |
| 52 | +//! 合計データ数の取得 | |
| 53 | +//! @return 合計データ数 | |
| 54 | +int DataInterface::GetTotaldatas() | |
| 55 | +{ | |
| 56 | + return datas; | |
| 57 | +} | |
| 58 | + | |
| 59 | +//! データを取得 | |
| 60 | +//! @param out_data 受け取るポインタ | |
| 61 | +//! @param id 認識番号 | |
| 62 | +//! @return 成功:0 失敗:0以外 | |
| 63 | +int DataInterface::Getdata(void *out_data, int id) | |
| 64 | +{ | |
| 65 | + return 0; | |
| 66 | +} | |
| 67 | + | |
| 68 | +//! コンストラクタ | |
| 69 | +BlockDataInterface::BlockDataInterface() | |
| 70 | +{ | |
| 71 | + //blockdata構造体初期化 | |
| 72 | + data = new blockdata[MAX_BLOCKS]; | |
| 73 | + | |
| 74 | + //テクスチャ設定初期化 | |
| 75 | + for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){ | |
| 76 | + strcpy(texture[i], ""); | |
| 77 | + } | |
| 78 | +} | |
| 79 | + | |
| 80 | +//! ディストラクタ | |
| 81 | +BlockDataInterface::~BlockDataInterface() | |
| 82 | +{ | |
| 83 | + //blockdata構造体解放 | |
| 84 | + if( data != NULL ) delete [] data; | |
| 85 | +} | |
| 86 | + | |
| 87 | +//! ブロックデータファイルを読みこむ | |
| 88 | +//! @param fname ファイル名 | |
| 89 | +//! @return 成功:0 失敗:1 | |
| 90 | +int BlockDataInterface::LoadFiledata(char *fname) | |
| 91 | +{ | |
| 92 | + FILE *fp; | |
| 93 | + unsigned char bdata_header[2]; | |
| 94 | + float bdata_main[80]; | |
| 95 | + char bdata_mainb[30]; | |
| 96 | + | |
| 97 | + //ファイルを読み込む | |
| 98 | + fp = fopen(fname, "rb"); | |
| 99 | + if( fp == NULL ){ | |
| 100 | + return 1; | |
| 101 | + } | |
| 102 | + | |
| 103 | + //テクスチャを取得 | |
| 104 | + for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){ | |
| 105 | + fread(texture[i], 1, 31, fp ); | |
| 106 | + } | |
| 107 | + | |
| 108 | + //データ数を取得 | |
| 109 | + fread( bdata_header, 1, 2, fp ); | |
| 110 | + datas = (int)bdata_header[1]*256 + bdata_header[0]; | |
| 111 | + if( datas > MAX_BLOCKS ){ | |
| 112 | + datas = MAX_BLOCKS; | |
| 113 | + } | |
| 114 | + | |
| 115 | + //ブロックデータ数分取得 | |
| 116 | + for(int i=0; i<datas; i++){ | |
| 117 | + //ブロックのを頂点情報と面情報を取得 | |
| 118 | + fread( bdata_main, 4, 24+48, fp ); | |
| 119 | + fread( bdata_mainb, 1, 28, fp ); | |
| 120 | + | |
| 121 | + //データ番号を設定 | |
| 122 | + data[i].id = i; | |
| 123 | + | |
| 124 | + //ブロックの頂点情報に設定 | |
| 125 | + for(int j=0; j<8; j++){ | |
| 126 | + data[i].x[j] = bdata_main[j]; | |
| 127 | + data[i].y[j] = bdata_main[j+8]; | |
| 128 | + data[i].z[j] = bdata_main[j+16]; | |
| 129 | + } | |
| 130 | + | |
| 131 | + //ブロックの面情報を設定 | |
| 132 | + for(int j=0; j<6; j++){ | |
| 133 | + data[i].material[j].textureID = (int)bdata_mainb[j*4]; | |
| 134 | + data[i].material[j].u[0] = bdata_main[j*4+24]; | |
| 135 | + data[i].material[j].v[0] = bdata_main[j*4+48]; | |
| 136 | + data[i].material[j].u[1] = bdata_main[j*4+25]; | |
| 137 | + data[i].material[j].v[1] = bdata_main[j*4+49]; | |
| 138 | + data[i].material[j].u[2] = bdata_main[j*4+26]; | |
| 139 | + data[i].material[j].v[2] = bdata_main[j*4+50]; | |
| 140 | + data[i].material[j].u[3] = bdata_main[j*4+27]; | |
| 141 | + data[i].material[j].v[3] = bdata_main[j*4+51]; | |
| 142 | + } | |
| 143 | + } | |
| 144 | + | |
| 145 | + //ファイルハンドルを解放 | |
| 146 | + fclose( fp ); | |
| 147 | + | |
| 148 | + return 0; | |
| 149 | +} | |
| 150 | + | |
| 151 | +//! ブロックデータの法線・影を算出する | |
| 152 | +//! @param screen ブロックを暗くする | |
| 153 | +//! @attention LoadBlockdata()関数で読みこんだ後、一度だけ実行。 | |
| 154 | +void BlockDataInterface::CalculationBlockdata(bool screen) | |
| 155 | +{ | |
| 156 | + int vID[4]; | |
| 157 | + int uvID[4]; | |
| 158 | + float g; | |
| 159 | + float xs, ys, zs; | |
| 160 | + float lx, ly, lz; | |
| 161 | + float rx, ry, rz, a; | |
| 162 | + | |
| 163 | + //光源の角度を設定 | |
| 164 | + lx = cos(LIGHT_RX); | |
| 165 | + ly = sin(LIGHT_RY); | |
| 166 | + lz = sin(LIGHT_RX); | |
| 167 | + | |
| 168 | + //各ブロックの面情報分処理する | |
| 169 | + for(int i=0; i<datas; i++){ | |
| 170 | + for(int j=0; j<6; j++){ | |
| 171 | + | |
| 172 | + //ブロック頂点データの関連付けを取得 | |
| 173 | + blockdataface(j, vID, uvID); | |
| 174 | + | |
| 175 | + //面の法線(ベクトル)と、その長さを求める | |
| 176 | + xs = ((data[i].y[ vID[3] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[0] ] - data[i].z[ vID[2] ])) - ((data[i].y[ vID[0] ] - data[i].y[ vID[2] ]) * (data[i].z[ vID[3] ] - data[i].z[ vID[2] ])); | |
| 177 | + ys = ((data[i].z[ vID[3] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[0] ] - data[i].x[ vID[2] ])) - ((data[i].z[ vID[0] ] - data[i].z[ vID[2] ]) * (data[i].x[ vID[3] ] - data[i].x[ vID[2] ])); | |
| 178 | + zs = ((data[i].x[ vID[3] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[0] ] - data[i].y[ vID[2] ])) - ((data[i].x[ vID[0] ] - data[i].x[ vID[2] ]) * (data[i].y[ vID[3] ] - data[i].y[ vID[2] ])); | |
| 179 | + g = (float)sqrt(xs * xs + ys * ys + zs * zs); | |
| 180 | + | |
| 181 | + //もし法線がおかしければ、もう一方の三角形で計算をやり直す | |
| 182 | + if( g == 0.0f ){ | |
| 183 | + xs = ((data[i].y[ vID[1] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[2] ] - data[i].z[ vID[0] ])) - ((data[i].y[ vID[2] ] - data[i].y[ vID[0] ]) * (data[i].z[ vID[1] ] - data[i].z[ vID[0] ])); | |
| 184 | + ys = ((data[i].z[ vID[1] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[2] ] - data[i].x[ vID[0] ])) - ((data[i].z[ vID[2] ] - data[i].z[ vID[0] ]) * (data[i].x[ vID[1] ] - data[i].x[ vID[0] ])); | |
| 185 | + zs = ((data[i].x[ vID[1] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[2] ] - data[i].y[ vID[0] ])) - ((data[i].x[ vID[2] ] - data[i].x[ vID[0] ]) * (data[i].y[ vID[1] ] - data[i].y[ vID[0] ])); | |
| 186 | + g = (float)sqrt(xs * xs + ys * ys + zs * zs); | |
| 187 | + } | |
| 188 | + | |
| 189 | + //法線(ベクトル)を正規化 | |
| 190 | + data[i].material[j].vx = xs / g; | |
| 191 | + data[i].material[j].vy = ys / g; | |
| 192 | + data[i].material[j].vz = zs / g; | |
| 193 | + | |
| 194 | + //面の明るさを求める | |
| 195 | + rx = data[i].material[j].vx + lx; | |
| 196 | + ry = data[i].material[j].vy + ly; | |
| 197 | + rz = data[i].material[j].vz + lz; | |
| 198 | + //a = sqrt(fabs(rx*rx + ry*ry + rz*rz)) / 2.0f; | |
| 199 | + //data[i].material[j].shadow = a/2 + 0.5f; | |
| 200 | + a = sqrt(rx*rx + ry*ry + rz*rz) / 3.0f; | |
| 201 | + data[i].material[j].shadow = a/2; | |
| 202 | + if( screen == false ){ | |
| 203 | + data[i].material[j].shadow += 0.5f; | |
| 204 | + } | |
| 205 | + else{ | |
| 206 | + data[i].material[j].shadow += 0.2f; | |
| 207 | + } | |
| 208 | + } | |
| 209 | + } | |
| 210 | +} | |
| 211 | + | |
| 212 | +//! ブロックデータに設定されたテクスチャのファイル名を取得 | |
| 213 | +//! @param fname ファイル名を受け取る文字列型ポインタ | |
| 214 | +//! @param id テクスチャ番号 | |
| 215 | +//! @return 成功:0 失敗:0以外 | |
| 216 | +int BlockDataInterface::GetTexture(char *fname, int id) | |
| 217 | +{ | |
| 218 | + if( data == NULL ){ return 1; } | |
| 219 | + if( (id < 0)||((TOTAL_BLOCKTEXTURE -1) < id) ){ return 2; } | |
| 220 | + | |
| 221 | + //ポインタにテクスチャ名をコピー | |
| 222 | + strcpy(fname, texture[id]); | |
| 223 | + | |
| 224 | + return 0; | |
| 225 | +} | |
| 226 | + | |
| 227 | +//! ブロックデータを取得 | |
| 228 | +//! @param out_data 受け取るblockdata型ポインタ | |
| 229 | +//! @param id 認識番号 | |
| 230 | +//! @return 成功:0 失敗:0以外 | |
| 231 | +int BlockDataInterface::Getdata(blockdata *out_data, int id) | |
| 232 | +{ | |
| 233 | + if( data == NULL ){ return 1; } | |
| 234 | + if( (id < 0)||((datas -1) < id) ){ return 2; } | |
| 235 | + | |
| 236 | + //ブロックデータを取得 | |
| 237 | + memcpy(out_data, &(data[id]), sizeof(blockdata)); | |
| 238 | + | |
| 239 | + return 0; | |
| 240 | +} | |
| 241 | + | |
| 242 | +//! ブロック頂点データの関連付けを取得 | |
| 243 | +// | |
| 244 | +// 3 ・----・2 | |
| 245 | +// /| /| | |
| 246 | +// / | / | | |
| 247 | +// 0 ・----・1 | | |
| 248 | +// |7 ・-| --・6 | |
| 249 | +// | / | / | |
| 250 | +// | / | / | |
| 251 | +// 4 ・----・5 | |
| 252 | +// | |
| 253 | +// C-----D | |
| 254 | +// | | | |
| 255 | +// | | | |
| 256 | +// B-----A | |
| 257 | +// | |
| 258 | +// 上[0](ABCD) = (1032) | |
| 259 | +// 下[1] = (6745) | |
| 260 | +// 前[2] = (5401) | |
| 261 | +// 右[3] = (6512) | |
| 262 | +// 奥[4] = (7623) | |
| 263 | +// 左[5] = (4730) | |
| 264 | +bool blockdataface(int faceID, int* vID, int* uvID) | |
| 265 | +{ | |
| 266 | + if( faceID == 0 ){ | |
| 267 | + if( vID != NULL ){ | |
| 268 | + vID[0] = 1; vID[1] = 0; vID[2] = 3; vID[3] = 2; | |
| 269 | + } | |
| 270 | + if( uvID != NULL ){ | |
| 271 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 272 | + } | |
| 273 | + return TRUE; | |
| 274 | + } | |
| 275 | + if( faceID == 1 ){ | |
| 276 | + if( vID != NULL ){ | |
| 277 | + vID[0] = 6; vID[1] = 7; vID[2] = 4; vID[3] = 5; | |
| 278 | + } | |
| 279 | + if( uvID != NULL ){ | |
| 280 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 281 | + } | |
| 282 | + return TRUE; | |
| 283 | + } | |
| 284 | + if( faceID == 2 ){ | |
| 285 | + if( vID != NULL ){ | |
| 286 | + vID[0] = 5; vID[1] = 4; vID[2] = 0; vID[3] = 1; | |
| 287 | + } | |
| 288 | + if( uvID != NULL ){ | |
| 289 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 290 | + } | |
| 291 | + return TRUE; | |
| 292 | + } | |
| 293 | + if( faceID == 3 ){ | |
| 294 | + if( vID != NULL ){ | |
| 295 | + vID[0] = 6; vID[1] = 5; vID[2] = 1; vID[3] = 2; | |
| 296 | + } | |
| 297 | + if( uvID != NULL ){ | |
| 298 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 299 | + } | |
| 300 | + return TRUE; | |
| 301 | + } | |
| 302 | + if( faceID == 4 ){ | |
| 303 | + if( vID != NULL ){ | |
| 304 | + vID[0] = 7; vID[1] = 6; vID[2] = 2; vID[3] = 3; | |
| 305 | + } | |
| 306 | + if( uvID != NULL ){ | |
| 307 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 308 | + } | |
| 309 | + return TRUE; | |
| 310 | + } | |
| 311 | + if( faceID == 5 ){ | |
| 312 | + if( vID != NULL ){ | |
| 313 | + vID[0] = 4; vID[1] = 7; vID[2] = 3; vID[3] = 0; | |
| 314 | + } | |
| 315 | + if( uvID != NULL ){ | |
| 316 | + uvID[0] = 2; uvID[1] = 3; uvID[2] = 0; uvID[3] = 1; | |
| 317 | + } | |
| 318 | + return TRUE; | |
| 319 | + } | |
| 320 | + return FALSE; | |
| 321 | +} | |
| 322 | + | |
| 323 | +//! コンストラクタ | |
| 324 | +PointDataInterface::PointDataInterface() | |
| 325 | +{ | |
| 326 | + //pointdata構造体初期化 | |
| 327 | + data = new pointdata[MAX_POINTS]; | |
| 328 | + | |
| 329 | + //イベントメッセージ初期化 | |
| 330 | + for(int i=0; i<MAX_POINTMESSAGES; i++){ | |
| 331 | + text[i] = new char[MAX_POINTMESSAGEBYTE]; | |
| 332 | + } | |
| 333 | +} | |
| 334 | + | |
| 335 | +//! ディストラクタ | |
| 336 | +PointDataInterface::~PointDataInterface() | |
| 337 | +{ | |
| 338 | + //pointdata構造体解放 | |
| 339 | + if( data != NULL ) delete [] data; | |
| 340 | + | |
| 341 | + //イベントメッセージ解放 | |
| 342 | + for(int i=0; i<MAX_POINTMESSAGES; i++){ | |
| 343 | + if( text[i] != NULL ) delete [] text[i]; | |
| 344 | + } | |
| 345 | +} | |
| 346 | + | |
| 347 | +//! ポイントデータファイルを読みこむ | |
| 348 | +//! @param fname ファイル名 | |
| 349 | +//! @return 成功:0 失敗:1 | |
| 350 | +int PointDataInterface::LoadFiledata(char *fname) | |
| 351 | +{ | |
| 352 | + FILE *fp; | |
| 353 | + unsigned char pdata_header[2]; | |
| 354 | + float pdata_mainf[200][4]; | |
| 355 | + char pdata_mainc[200][4]; | |
| 356 | + char fname2[MAX_PATH]; | |
| 357 | + | |
| 358 | + //ファイルを読み込む | |
| 359 | + fp = fopen( fname, "rb" ); | |
| 360 | + if( fp == NULL ){ | |
| 361 | + return 1; | |
| 362 | + } | |
| 363 | + | |
| 364 | + //データ数を取得 | |
| 365 | + fread( pdata_header, 1, 2, fp ); | |
| 366 | + datas = (int)pdata_header[1]*256 + pdata_header[0]; | |
| 367 | + if( datas > MAX_POINTS ){ | |
| 368 | + datas = MAX_POINTS; | |
| 369 | + } | |
| 370 | + | |
| 371 | + //ポイントデータ数分処理する | |
| 372 | + for(int i=0; i<datas; i++){ | |
| 373 | + //データ番号設定 | |
| 374 | + data[i].id = i; | |
| 375 | + | |
| 376 | + //座標データ取得 | |
| 377 | + fread( pdata_mainf[i], 4, 4, fp ); | |
| 378 | + data[i].x = pdata_mainf[i][0]; | |
| 379 | + data[i].y = pdata_mainf[i][1]; | |
| 380 | + data[i].z = pdata_mainf[i][2]; | |
| 381 | + data[i].r = pdata_mainf[i][3]; | |
| 382 | + | |
| 383 | + //パラメータ取得 | |
| 384 | + fread( pdata_mainc[i], 1, 4, fp ); | |
| 385 | + data[i].p1 = pdata_mainc[i][0]; | |
| 386 | + data[i].p2 = pdata_mainc[i][1]; | |
| 387 | + data[i].p3 = pdata_mainc[i][2]; | |
| 388 | + data[i].p4 = pdata_mainc[i][3]; | |
| 389 | + } | |
| 390 | + | |
| 391 | + //ファイルポインタを閉じる | |
| 392 | + fclose( fp ); | |
| 393 | + | |
| 394 | + //「同ファイル名.msg」を生成 | |
| 395 | + strcpy(fname2, fname); | |
| 396 | + //PathRemoveExtension(fname2); | |
| 397 | + for(int i=strlen(fname2)-1; i>0; i--){ | |
| 398 | + if( fname2[i] == '.' ){ | |
| 399 | + fname2[i] = 0x00; | |
| 400 | + break; | |
| 401 | + } | |
| 402 | + } | |
| 403 | + strcat(fname2, ".msg"); | |
| 404 | + | |
| 405 | + //ファイルを読み込み | |
| 406 | + fp = fopen( fname2, "r" ); | |
| 407 | + if( fp != NULL ){ | |
| 408 | + //メッセージデータを取得 | |
| 409 | + for(int i=0; i<MAX_POINTMESSAGES; i++){ | |
| 410 | + if( fgets(text[i], MAX_POINTMESSAGEBYTE, fp) == NULL ){ break; } | |
| 411 | + | |
| 412 | + //'\r'があれば'\n'に置き換える | |
| 413 | + for(int j=0; j<MAX_POINTMESSAGEBYTE; j++){ | |
| 414 | + if( text[i][j] == '\r' ){ text[i][j] = '\n'; } | |
| 415 | + } | |
| 416 | + } | |
| 417 | + | |
| 418 | + //ファイルポインタを開放 | |
| 419 | + fclose( fp ); | |
| 420 | + } | |
| 421 | + | |
| 422 | + return 0; | |
| 423 | +} | |
| 424 | + | |
| 425 | +//! ポイントデータを取得 | |
| 426 | +//! @param out_data 受け取るpointdata型ポインタ | |
| 427 | +//! @param id 認識番号 | |
| 428 | +//! @return 成功:0 失敗:0以外 | |
| 429 | +int PointDataInterface::Getdata(pointdata *out_data, int id) | |
| 430 | +{ | |
| 431 | + if( data == NULL ){ return 1; } | |
| 432 | + if( (id < 0)||((datas -1) < id) ){ return 2; } | |
| 433 | + | |
| 434 | + //データをポインタにコピー | |
| 435 | + memcpy(out_data, &(data[id]), sizeof(pointdata)); | |
| 436 | + | |
| 437 | + return 0; | |
| 438 | +} | |
| 439 | + | |
| 440 | +//! ポイントのパラメーターを書き換え | |
| 441 | +//! @param id 認識番号 | |
| 442 | +//! @param p1 第1パラメータ | |
| 443 | +//! @param p2 第2パラメータ | |
| 444 | +//! @param p3 第3パラメータ | |
| 445 | +//! @param p4 第4パラメータ | |
| 446 | +//! @return 成功:0 失敗:0以外 | |
| 447 | +//! @warning AIが使用するパス(p1:3 or p1:8)以外への使用は、保証されておらず推奨しません。 | |
| 448 | +int PointDataInterface::SetParam(int id, signed char p1, signed char p2, signed char p3, signed char p4) | |
| 449 | +{ | |
| 450 | + if( data == NULL ){ return 1; } | |
| 451 | + if( (id < 0)||((datas -1) < id) ){ return 2; } | |
| 452 | + | |
| 453 | + //パラメータを上書き | |
| 454 | + data[id].p1 = p1; | |
| 455 | + data[id].p2 = p2; | |
| 456 | + data[id].p3 = p3; | |
| 457 | + data[id].p4 = p4; | |
| 458 | + | |
| 459 | + return 0; | |
| 460 | +} | |
| 461 | + | |
| 462 | +//! メッセージ(1行)を取得 | |
| 463 | +//! @param str 文字列を受け取るポインタ | |
| 464 | +//! @param id 認識番号 | |
| 465 | +//! @return 成功:0 失敗:1 | |
| 466 | +int PointDataInterface::GetMessageText(char *str, int id) | |
| 467 | +{ | |
| 468 | + if( (id < 0)||((MAX_POINTMESSAGES -1) < id) ){ return 1; } | |
| 469 | + | |
| 470 | + //ポインタにメッセージをコピー | |
| 471 | + strcpy(str, text[id]); | |
| 472 | + return 0; | |
| 473 | +} | |
| 474 | + | |
| 475 | +//! ポイントデータを検索 | |
| 476 | +//! @param id 最初に該当したデータ番号を受け取るポインタ (NULL 可) | |
| 477 | +//! @param pmask パラメータのマスク | |
| 478 | +//! @param p1 第1パラメータ | |
| 479 | +//! @param p2 第2パラメータ | |
| 480 | +//! @param p3 第3パラメータ | |
| 481 | +//! @param p4 第4パラメータ | |
| 482 | +//! @param offset 検索を開始するデータ | |
| 483 | +//! @return 該当ポイント数 | |
| 484 | +//! @note パラメータのマスクは、p1〜p4の検索対象を指定します。 | |
| 485 | +//! @note 1〜4ビット目までを使用し、p1:1ビット目、p2:2ビット目、p3:3ビット目、p4:4ビット目 をそれぞれ意味します。 | |
| 486 | +//! @note 検索の対象ビット:1 対象外のビット:0 に設定してください。 なお、7〜5ビット目は無視されます。 | |
| 487 | +//! @code | |
| 488 | +//! //16進数で記述の場合― | |
| 489 | +//! 0x02 // p2のみを検索対象にする | |
| 490 | +//! 0x05 // p1とp3を検索対象にする | |
| 491 | +//! 0xF1 // p1のみを検索対象にする (7〜5ビット目は無視) | |
| 492 | +//! @endcode | |
| 493 | +int PointDataInterface::SearchPointdata(int* id, unsigned char pmask, signed char p1, signed char p2, signed char p3, signed char p4, int offset) | |
| 494 | +{ | |
| 495 | + int cnt = 0; | |
| 496 | + | |
| 497 | + if( offset < 0 ){ offset = 0; } | |
| 498 | + if( offset >= datas ){ offset = datas; } | |
| 499 | + | |
| 500 | + //オフセット値からデータ数分処理 | |
| 501 | + for(int i=offset; i<datas; i++){ | |
| 502 | + | |
| 503 | + if( ((pmask&0x01) == 0)||(p1 == data[i].p1) ){ //マスクで指定されていないか、p1が一致 | |
| 504 | + if( ((pmask&0x02) == 0)||(p2 == data[i].p2) ){ //マスクで指定されていないか、p2が一致 | |
| 505 | + if( ((pmask&0x04) == 0)||(p3 == data[i].p3) ){ //マスクで指定されていないか、p3が一致 | |
| 506 | + if( ((pmask&0x08) == 0)||(p4 == data[i].p4) ){ //マスクで指定されていないか、p4が一致 | |
| 507 | + | |
| 508 | + if( (cnt == 0)&&(id != NULL) ){ //最初に該当し、idがNULLでない。 | |
| 509 | + *id = i; | |
| 510 | + } | |
| 511 | + | |
| 512 | + //検索該当数を+1 | |
| 513 | + cnt += 1; | |
| 514 | + | |
| 515 | + } | |
| 516 | + } | |
| 517 | + } | |
| 518 | + } | |
| 519 | + | |
| 520 | + } | |
| 521 | + | |
| 522 | + //検索該当数を返す | |
| 523 | + return cnt; | |
| 524 | +} | |
| 525 | + | |
| 526 | +//! ポイントデータを検索 | |
| 527 | +//! @param out_data 最初に該当したデータを受け取るpointdata型ポインタ (NULL 可) | |
| 528 | +//! @param pmask パラメータのマスク | |
| 529 | +//! @param p1 第1パラメータ | |
| 530 | +//! @param p2 第2パラメータ | |
| 531 | +//! @param p3 第3パラメータ | |
| 532 | +//! @param p4 第4パラメータ | |
| 533 | +//! @param offset 検索を開始するデータ | |
| 534 | +//! @return 該当ポイント数 | |
| 535 | +//! @attention この関数の詳しい説明は、同オーバーロード関数をご覧ください。 | |
| 536 | +int PointDataInterface::SearchPointdata(pointdata *out_data, unsigned char pmask, signed char p1, signed char p2, signed char p3, signed char p4, int offset) | |
| 537 | +{ | |
| 538 | + int id, total; | |
| 539 | + | |
| 540 | + //同条件でポイントを検索 | |
| 541 | + total = SearchPointdata(&id, pmask, p1, p2, p3, p4, offset); | |
| 542 | + | |
| 543 | + //該当すればデータを取得 | |
| 544 | + if( total > 0 ){ | |
| 545 | + Getdata(out_data, id); | |
| 546 | + } | |
| 547 | + | |
| 548 | + //検索該当数を返す | |
| 549 | + return total; | |
| 550 | +} | |
| 551 | + | |
| 552 | +//! コンストラクタ | |
| 553 | +MIFInterface::MIFInterface() | |
| 554 | +{ | |
| 555 | + datas = 0; | |
| 556 | + | |
| 557 | + mif = false; | |
| 558 | + strcpy(mission_name, ""); | |
| 559 | + strcpy(mission_fullname, ""); | |
| 560 | + strcpy(blockfile_path, ""); | |
| 561 | + strcpy(pointfile_path, ""); | |
| 562 | + skynumber = 0; | |
| 563 | + strcpy(picturefileA_path, "!"); | |
| 564 | + strcpy(picturefileB_path, "!"); | |
| 565 | + strcpy(addsmallobject_path, ""); | |
| 566 | + strcpy(briefingtext, ""); | |
| 567 | + collision = false; | |
| 568 | + screen = false; | |
| 569 | + strcpy(addsmallobject_modelpath, ""); | |
| 570 | + strcpy(addsmallobject_texturepath, ""); | |
| 571 | + addsmallobject_decide = 0; | |
| 572 | + addsmallobject_hp = 0; | |
| 573 | + strcpy(addsmallobject_soundpath, ""); | |
| 574 | + addsmallobject_jump = 0; | |
| 575 | +} | |
| 576 | + | |
| 577 | +//! ディストラクタ | |
| 578 | +MIFInterface::~MIFInterface() | |
| 579 | +{} | |
| 580 | + | |
| 581 | +//! データファイルを読みこむ | |
| 582 | +//! @param fname ファイル名 | |
| 583 | +//! @return 成功:0 失敗:1 | |
| 584 | +int MIFInterface::LoadFiledata(char *fname) | |
| 585 | +{ | |
| 586 | + char str[64]; | |
| 587 | + | |
| 588 | + mif = false; | |
| 589 | + | |
| 590 | + //拡張子が.mifならば | |
| 591 | + //if( strcmp(PathFindExtension(fname), ".mif") == 0 ){ | |
| 592 | + // //MIFフラグを有効に | |
| 593 | + // mif = true; | |
| 594 | + //} | |
| 595 | + for(int i=strlen(fname)-1; i>0; i--){ | |
| 596 | + if( fname[i] == '.' ){ | |
| 597 | + if( strcmp(&(fname[i]), ".mif") == 0 ){ | |
| 598 | + //MIFフラグを有効に | |
| 599 | + mif = true; | |
| 600 | + } | |
| 601 | + break; | |
| 602 | + } | |
| 603 | + } | |
| 604 | + | |
| 605 | + FILE *fp; | |
| 606 | + | |
| 607 | + //ファイルを開く | |
| 608 | + fp = fopen( fname, "r" ); | |
| 609 | + if( fp == NULL ){ | |
| 610 | + //briefing data open failed | |
| 611 | + return 1; | |
| 612 | + } | |
| 613 | + | |
| 614 | + if( mif == true ){ | |
| 615 | + //ミッション識別名 | |
| 616 | + fgets(mission_name, 24, fp); | |
| 617 | + DeleteLinefeed(mission_name); | |
| 618 | + | |
| 619 | + //ミッション正式名称 | |
| 620 | + fgets(mission_fullname, 64, fp); | |
| 621 | + DeleteLinefeed(mission_fullname); | |
| 622 | + | |
| 623 | + //ブロックデータファイル | |
| 624 | + fgets(blockfile_path, _MAX_PATH, fp); | |
| 625 | + DeleteLinefeed(blockfile_path); | |
| 626 | + | |
| 627 | + //ポイントデータファイル | |
| 628 | + fgets(pointfile_path, _MAX_PATH, fp); | |
| 629 | + DeleteLinefeed(pointfile_path); | |
| 630 | + | |
| 631 | + //背景空の番号 | |
| 632 | + fgets(str, 16, fp); | |
| 633 | + DeleteLinefeed(str); | |
| 634 | + skynumber = atoi(str); | |
| 635 | + | |
| 636 | + //あたり判定・画面設定の取得 | |
| 637 | + fgets(str, 16, fp); | |
| 638 | + DeleteLinefeed(str); | |
| 639 | + if( strcmp(str, "1") == 0 ){ | |
| 640 | + collision = true; | |
| 641 | + screen = false; | |
| 642 | + } | |
| 643 | + else if( strcmp(str, "2") == 0 ){ | |
| 644 | + collision = false; | |
| 645 | + screen = true; | |
| 646 | + } | |
| 647 | + else if( strcmp(str, "3") == 0 ){ | |
| 648 | + collision = true; | |
| 649 | + screen = true; | |
| 650 | + } | |
| 651 | + else{ // == "0" | |
| 652 | + collision = false; | |
| 653 | + screen = false; | |
| 654 | + } | |
| 655 | + | |
| 656 | + //追加小物情報ファイル取得 | |
| 657 | + fgets(addsmallobject_path, _MAX_PATH, fp); | |
| 658 | + DeleteLinefeed(addsmallobject_path); | |
| 659 | + | |
| 660 | + //画像Aを取得 | |
| 661 | + fgets(picturefileA_path, _MAX_PATH, fp); | |
| 662 | + DeleteLinefeed(picturefileA_path); | |
| 663 | + | |
| 664 | + //画像Bを取得 | |
| 665 | + fgets(picturefileB_path, _MAX_PATH, fp); | |
| 666 | + DeleteLinefeed(picturefileB_path); | |
| 667 | + } | |
| 668 | + else{ | |
| 669 | + //画像Aを取得 | |
| 670 | + fgets(str, 64, fp); | |
| 671 | + DeleteLinefeed(str); | |
| 672 | + if( strcmp(str, "!") == 0 ){ | |
| 673 | + strcpy(picturefileA_path, "!"); | |
| 674 | + } | |
| 675 | + else{ | |
| 676 | + //「data\\briefing\\ 〜 .bmp」を生成 | |
| 677 | + strcpy(picturefileA_path, "data\\briefing\\"); | |
| 678 | + strcat(picturefileA_path, str); | |
| 679 | + strcat(picturefileA_path, ".bmp"); | |
| 680 | + } | |
| 681 | + | |
| 682 | + //画像Bを取得 | |
| 683 | + fgets(str, 64, fp); | |
| 684 | + DeleteLinefeed(str); | |
| 685 | + if( strcmp(str, "!") == 0 ){ | |
| 686 | + strcpy(picturefileB_path, "!"); | |
| 687 | + } | |
| 688 | + else{ | |
| 689 | + //「data\\briefing\\ 〜 .bmp」を生成 | |
| 690 | + strcpy(picturefileB_path, "data\\briefing\\"); | |
| 691 | + strcat(picturefileB_path, str); | |
| 692 | + strcat(picturefileB_path, ".bmp"); | |
| 693 | + } | |
| 694 | + | |
| 695 | + //背景空の番号 | |
| 696 | + fgets(str, 16, fp); | |
| 697 | + DeleteLinefeed(str); | |
| 698 | + skynumber = atoi(str); | |
| 699 | + | |
| 700 | + //取得できない値の初期化 | |
| 701 | + strcpy(mission_name, ""); | |
| 702 | + strcpy(mission_fullname, ""); | |
| 703 | + strcpy(blockfile_path, ""); | |
| 704 | + strcpy(pointfile_path, ""); | |
| 705 | + strcpy(addsmallobject_path, ""); | |
| 706 | + collision = false; | |
| 707 | + screen = false; | |
| 708 | + } | |
| 709 | + | |
| 710 | + //ブリーフィングテキストを取得 | |
| 711 | + strcpy(briefingtext, ""); | |
| 712 | + for(int i=0; i<17; i++ ){ | |
| 713 | + if( fgets(str, 50, fp) == NULL ){ break; } | |
| 714 | + strcat(briefingtext, str); | |
| 715 | + datas += 1; | |
| 716 | + } | |
| 717 | + | |
| 718 | + //ファイルハンドルを開放 | |
| 719 | + fclose( fp ); | |
| 720 | + | |
| 721 | + | |
| 722 | + //追加小物情報を初期値へ | |
| 723 | + strcpy(addsmallobject_modelpath, ""); | |
| 724 | + strcpy(addsmallobject_texturepath, ""); | |
| 725 | + addsmallobject_decide = 0; | |
| 726 | + addsmallobject_hp = 0; | |
| 727 | + strcpy(addsmallobject_soundpath, ""); | |
| 728 | + addsmallobject_jump = 0; | |
| 729 | + | |
| 730 | + //何かしらの追加小物情報ファイルが指定されていれば | |
| 731 | + if( (strcmp(addsmallobject_path, "") != 0)&&(strcmp(addsmallobject_path, "!") != 0) ){ | |
| 732 | + //ファイルを開く | |
| 733 | + fp = fopen( addsmallobject_path, "r" ); | |
| 734 | + if( fp != NULL ){ | |
| 735 | + //モデルデータパス | |
| 736 | + fgets(addsmallobject_modelpath, _MAX_PATH, fp); | |
| 737 | + DeleteLinefeed(addsmallobject_modelpath); | |
| 738 | + | |
| 739 | + //テクスチャパス | |
| 740 | + fgets(addsmallobject_texturepath, _MAX_PATH, fp); | |
| 741 | + DeleteLinefeed(addsmallobject_texturepath); | |
| 742 | + | |
| 743 | + //当たり判定の大きさ | |
| 744 | + fgets(str, 16, fp); | |
| 745 | + DeleteLinefeed(str); | |
| 746 | + addsmallobject_decide = atoi(str); | |
| 747 | + | |
| 748 | + //耐久力 | |
| 749 | + fgets(str, 16, fp); | |
| 750 | + DeleteLinefeed(str); | |
| 751 | + addsmallobject_hp = atoi(str); | |
| 752 | + | |
| 753 | + //サウンドデータパス | |
| 754 | + fgets(addsmallobject_soundpath, _MAX_PATH, fp); | |
| 755 | + DeleteLinefeed(addsmallobject_soundpath); | |
| 756 | + | |
| 757 | + //飛び具合 | |
| 758 | + fgets(str, 16, fp); | |
| 759 | + DeleteLinefeed(str); | |
| 760 | + addsmallobject_jump = atoi(str); | |
| 761 | + | |
| 762 | + //ファイルハンドルを開放 | |
| 763 | + fclose( fp ); | |
| 764 | + } | |
| 765 | + } | |
| 766 | + | |
| 767 | + return 0; | |
| 768 | +} | |
| 769 | + | |
| 770 | +//! 読み込んだデータファイルの形式を取得 | |
| 771 | +//! @return 標準形式:false MIF形式:true | |
| 772 | +//! @attention ファイルを正常に読み込んだ後に実行してください。 | |
| 773 | +bool MIFInterface::GetFiletype() | |
| 774 | +{ | |
| 775 | + return mif; | |
| 776 | +} | |
| 777 | + | |
| 778 | +//! ミッション識別名を取得 | |
| 779 | +//! @return 識別名のポインタ(最大:24) | |
| 780 | +char* MIFInterface::GetMissionName() | |
| 781 | +{ | |
| 782 | + return mission_name; | |
| 783 | +} | |
| 784 | + | |
| 785 | +//! ミッション正式名称を取得 | |
| 786 | +//! @return 正式名称のポインタ(最大:64) | |
| 787 | +char* MIFInterface::GetMissionFullname() | |
| 788 | +{ | |
| 789 | + return mission_fullname; | |
| 790 | +} | |
| 791 | + | |
| 792 | +//! ブロックデータとポイントデータのパスを取得 | |
| 793 | +//! @param *blockfile ブロックデータを受け取るポインタ | |
| 794 | +//! @param *pointfile ポイントデータを受け取るポインタ | |
| 795 | +void MIFInterface::GetDatafilePath(char *blockfile, char *pointfile) | |
| 796 | +{ | |
| 797 | + strcpy(blockfile, blockfile_path); | |
| 798 | + strcpy(pointfile, pointfile_path); | |
| 799 | +} | |
| 800 | + | |
| 801 | +//! 背景空を取得 | |
| 802 | +//! @return 空の番号(0〜5) | |
| 803 | +//! @attention 番号 0 は「背景なし」を意味します。 | |
| 804 | +int MIFInterface::GetSkynumber() | |
| 805 | +{ | |
| 806 | + return skynumber; | |
| 807 | +} | |
| 808 | + | |
| 809 | +//! ブリーフィング画像ファイルのパスを取得 | |
| 810 | +//! @param *picturefileA 画像ファイルAのパスを受け取るポインタ | |
| 811 | +//! @param *picturefileB 画像ファイルBのパスを受け取るポインタ | |
| 812 | +//! @attention 設定されていない場合は「!」が返されます。 | |
| 813 | +//! @attention 画像を1枚しか使用しない場合、画像ファイルBは「!」を返します。 | |
| 814 | +void MIFInterface::GetPicturefilePath(char *picturefileA, char *picturefileB) | |
| 815 | +{ | |
| 816 | + strcpy(picturefileA, picturefileA_path); | |
| 817 | + strcpy(picturefileB, picturefileB_path); | |
| 818 | +} | |
| 819 | + | |
| 820 | +//! ブリーフィング文章(本文)を取得 | |
| 821 | +//! @return 文章のポインタ(最大:816) | |
| 822 | +//! @attention 改行コードも含めて、最大17行分が一度に返されます。 | |
| 823 | +//! @attention 行数は GetTotaldatas() で取得できます。 | |
| 824 | +char* MIFInterface::GetBriefingText() | |
| 825 | +{ | |
| 826 | + return briefingtext; | |
| 827 | +} | |
| 828 | + | |
| 829 | +//! 追加のあたり判定を示すフラグを取得 | |
| 830 | +//! @return 有効:true 無効:false | |
| 831 | +bool MIFInterface::GetCollisionFlag() | |
| 832 | +{ | |
| 833 | + return collision; | |
| 834 | +} | |
| 835 | + | |
| 836 | +//! 画面を暗くを示すフラグを取得 | |
| 837 | +//! @return 有効:true 無効:false | |
| 838 | +bool MIFInterface::GetScreenFlag() | |
| 839 | +{ | |
| 840 | + return screen; | |
| 841 | +} | |
| 842 | + | |
| 843 | +//! 追加小物のモデルデータパスを取得 | |
| 844 | +//! @return モデルデータパスのポインタ(最大:_MAX_PATH) | |
| 845 | +char* MIFInterface::GetAddSmallobjectModelPath() | |
| 846 | +{ | |
| 847 | + return addsmallobject_modelpath; | |
| 848 | +} | |
| 849 | + | |
| 850 | +//! 追加小物のテクスチャパスを取得 | |
| 851 | +//! @return テクスチャパスのポインタ(最大:_MAX_PATH) | |
| 852 | +char* MIFInterface::GetAddSmallobjectTexturePath() | |
| 853 | +{ | |
| 854 | + return addsmallobject_texturepath; | |
| 855 | +} | |
| 856 | + | |
| 857 | +//! 追加小物の当たり判定の大きさを取得 | |
| 858 | +//! @return 当たり判定の大きさ | |
| 859 | +int MIFInterface::GetAddSmallobjectDecide() | |
| 860 | +{ | |
| 861 | + return addsmallobject_decide; | |
| 862 | +} | |
| 863 | + | |
| 864 | +//! 追加小物の耐久力を取得 | |
| 865 | +//! @return 耐久力 | |
| 866 | +int MIFInterface::GetAddSmallobjectHP() | |
| 867 | +{ | |
| 868 | + return addsmallobject_hp; | |
| 869 | +} | |
| 870 | + | |
| 871 | +//! 追加小物のサウンドデータパスを取得 | |
| 872 | +//! @return サウンドデータパスのポインタ(最大:_MAX_PATH) | |
| 873 | +char* MIFInterface::GetAddSmallobjectSoundPath() | |
| 874 | +{ | |
| 875 | + return addsmallobject_soundpath; | |
| 876 | +} | |
| 877 | + | |
| 878 | +//! 追加小物の飛び具合を取得 | |
| 879 | +//! @return 飛び具合 | |
| 880 | +int MIFInterface::GetAddSmallobjectJump() | |
| 881 | +{ | |
| 882 | + return addsmallobject_jump; | |
| 883 | +} | |
| 884 | + | |
| 885 | +//! コンストラクタ | |
| 886 | +AddonList::AddonList() | |
| 887 | +{ | |
| 888 | + datas = 0; | |
| 889 | + | |
| 890 | + for(int i=0; i<MAX_ADDONLIST; i++){ | |
| 891 | + strcpy(filename[i], ""); | |
| 892 | + strcpy(mission_name[i], ""); | |
| 893 | + } | |
| 894 | +} | |
| 895 | + | |
| 896 | +//! ディストラクタ | |
| 897 | +AddonList::~AddonList() | |
| 898 | +{} | |
| 899 | + | |
| 900 | +//! .mifファイルを取得 | |
| 901 | +void AddonList::GetMIFlist(char *dir) | |
| 902 | +{ | |
| 903 | + char SearchDIR[_MAX_PATH]; | |
| 904 | + HANDLE hFind; | |
| 905 | + WIN32_FIND_DATA FindFileData; | |
| 906 | + | |
| 907 | + //.mifの検索条件を生成 | |
| 908 | + strcpy(SearchDIR, dir); | |
| 909 | + strcat(SearchDIR, "\\*.mif"); | |
| 910 | + | |
| 911 | + //検索 | |
| 912 | + hFind = FindFirstFile(SearchDIR, &FindFileData); | |
| 913 | + if( hFind != INVALID_HANDLE_VALUE ){ | |
| 914 | + strcpy(filename[0], FindFileData.cFileName); | |
| 915 | + datas += 1; | |
| 916 | + | |
| 917 | + while( FindNextFile(hFind, &FindFileData) == TRUE ){ | |
| 918 | + strcpy(filename[datas], FindFileData.cFileName); | |
| 919 | + datas += 1; | |
| 920 | + } | |
| 921 | + } | |
| 922 | + FindClose(hFind); | |
| 923 | +} | |
| 924 | + | |
| 925 | +//! ミッション名を取得 | |
| 926 | +void AddonList::GetMissionName(char *dir) | |
| 927 | +{ | |
| 928 | + char str[_MAX_PATH]; | |
| 929 | + MIFInterface mifdata; | |
| 930 | + | |
| 931 | + for(int i=0; i<datas; i++){ | |
| 932 | + //ファイル名を生成 | |
| 933 | + strcpy(str, dir); | |
| 934 | + strcat(str, "\\"); | |
| 935 | + strcat(str, filename[i]); | |
| 936 | + | |
| 937 | + //MIFInterfaceで読み込む | |
| 938 | + mifdata.LoadFiledata(str); | |
| 939 | + | |
| 940 | + //ミッション名を取得 | |
| 941 | + strcpy(mission_name[i], mifdata.GetMissionName()); | |
| 942 | + } | |
| 943 | +} | |
| 944 | + | |
| 945 | +//! ミッション名をソートする | |
| 946 | +void AddonList::Sort() | |
| 947 | +{ | |
| 948 | + char mission_name_c[MAX_ADDONLIST][24]; | |
| 949 | + char temp[_MAX_PATH]; | |
| 950 | + int cmp; | |
| 951 | + | |
| 952 | + //ミッション名を一度小文字に変換する | |
| 953 | + for(int i=0; i<datas; i++){ | |
| 954 | + for(int j=0; j<(signed)strlen(mission_name[i]); j++){ | |
| 955 | + mission_name_c[i][j] = tolower(mission_name[i][j]); | |
| 956 | + } | |
| 957 | + mission_name_c[i][strlen(mission_name[i])] = 0x00; | |
| 958 | + } | |
| 959 | + | |
| 960 | + //低速なバブルソート (^^; | |
| 961 | + for(int i=0; i<datas-1; i++){ | |
| 962 | + for(int j=i+1; j<datas; j++){ | |
| 963 | + cmp = strcmp(mission_name_c[i], mission_name_c[j]); | |
| 964 | + if(cmp > 0){ | |
| 965 | + strcpy(temp, mission_name_c[i]); | |
| 966 | + strcpy(mission_name_c[i], mission_name_c[j]); | |
| 967 | + strcpy(mission_name_c[j], temp); | |
| 968 | + | |
| 969 | + strcpy(temp, mission_name[i]); | |
| 970 | + strcpy(mission_name[i], mission_name[j]); | |
| 971 | + strcpy(mission_name[j], temp); | |
| 972 | + | |
| 973 | + strcpy(temp, filename[i]); | |
| 974 | + strcpy(filename[i], filename[j]); | |
| 975 | + strcpy(filename[j], temp); | |
| 976 | + } | |
| 977 | + } | |
| 978 | + } | |
| 979 | + | |
| 980 | +} | |
| 981 | + | |
| 982 | +//! ADDONリストを取得する | |
| 983 | +//! @param dir ADDON(.mif)が入ったディレクトリ (標準:"addon\\") | |
| 984 | +//! @return addonの総数 | |
| 985 | +int AddonList::LoadFiledata(char *dir) | |
| 986 | +{ | |
| 987 | + datas = 0; | |
| 988 | + | |
| 989 | + //.mifファイルを取得 | |
| 990 | + GetMIFlist(dir); | |
| 991 | + | |
| 992 | + //ミッション名を取得 | |
| 993 | + GetMissionName(dir); | |
| 994 | + | |
| 995 | + //ミッション名をソートする | |
| 996 | + Sort(); | |
| 997 | + | |
| 998 | + return datas; | |
| 999 | +} | |
| 1000 | + | |
| 1001 | +//! ミッション名を取得 | |
| 1002 | +//! @param id 認識番号 | |
| 1003 | +//! @return ミッション名 | |
| 1004 | +char* AddonList::GetMissionName(int id) | |
| 1005 | +{ | |
| 1006 | + return mission_name[id]; | |
| 1007 | +} | |
| 1008 | + | |
| 1009 | +//! ファイル名を取得 | |
| 1010 | +//! @param id 認識番号 | |
| 1011 | +//! @return ファイル名 | |
| 1012 | +char* AddonList::GetFileName(int id) | |
| 1013 | +{ | |
| 1014 | + return filename[id]; | |
| 1015 | +} | |
| 1016 | + | |
| 1017 | + | |
| 1018 | +//! fgets()用 改行コードを取り除く | |
| 1019 | +//! @param str 文字列 | |
| 1020 | +//! @return 成功:0 失敗:1 | |
| 1021 | +int DeleteLinefeed(char str[]) | |
| 1022 | +{ | |
| 1023 | + char *pstr; | |
| 1024 | + | |
| 1025 | + pstr = strchr(str, '\n'); | |
| 1026 | + if( pstr ){ | |
| 1027 | + *pstr = '\0'; | |
| 1028 | + return 0; | |
| 1029 | + } | |
| 1030 | + return 1; | |
| 1031 | +} |
| @@ -0,0 +1,52 @@ | ||
| 1 | +//! @file window.h | |
| 2 | +//! @brief window.cpp関係のヘッダーファイル | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#ifndef WINDOW_H | |
| 33 | +#define WINDOW_H | |
| 34 | + | |
| 35 | +#ifndef H_LAYERLEVEL | |
| 36 | + #define H_LAYERLEVEL 1 //!< Select include file. | |
| 37 | +#endif | |
| 38 | +#include "main.h" | |
| 39 | + | |
| 40 | +#include <windows.h> | |
| 41 | +#include <mmsystem.h> | |
| 42 | + | |
| 43 | +#pragma comment(lib, "winmm.lib") | |
| 44 | + | |
| 45 | +HWND InitWindow(HINSTANCE hInstance, char* title, int width, int height, int nCmdShow, bool fullscreen); | |
| 46 | +float GetFps(int getcnt); | |
| 47 | +bool ControlFps(); | |
| 48 | +unsigned int GetTimeMS(); | |
| 49 | +void InitRand(); | |
| 50 | +int GetRand(int num); | |
| 51 | + | |
| 52 | +#endif | |
| \ No newline at end of file |
| @@ -0,0 +1,2341 @@ | ||
| 1 | +//! @file gamemain.cpp | |
| 2 | +//! @brief ゲームメイン処理のサンプルコード | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "gamemain.h" | |
| 33 | + | |
| 34 | +D3DGraphics d3dg; //!< 描画クラス | |
| 35 | +InputControl inputCtrl; //!< 入力取得クラス | |
| 36 | +SoundControl SoundCtrl; //!< サウンド再生クラス | |
| 37 | + | |
| 38 | +//! ゲームの設定値 | |
| 39 | +ParameterInfo GameParamInfo; | |
| 40 | + | |
| 41 | +//! リソース管理 | |
| 42 | +ResourceManager Resource; | |
| 43 | + | |
| 44 | +SoundManager GameSound; //!< ゲーム効果音再生クラス | |
| 45 | + | |
| 46 | +BlockDataInterface BlockData; //!< ブロックデータ管理クラス | |
| 47 | +PointDataInterface PointData; //!< ポイントデータ管理クラス | |
| 48 | +MIFInterface MIFdata; //!< MIFコントロール | |
| 49 | +AddonList GameAddon; //!< addonのリスト | |
| 50 | +Collision CollD; //!< 当たり判定管理クラス | |
| 51 | +ObjectManager ObjMgr; //!< オブジェクト管理クラス | |
| 52 | +AIcontrol HumanAI[MAX_HUMAN]; //!< AI管理クラス | |
| 53 | + | |
| 54 | +GameInfo GameInfoData; //!< ゲームの状態 | |
| 55 | + | |
| 56 | +EventControl Event[TOTAL_EVENTLINE]; //!< イベント制御クラス | |
| 57 | + | |
| 58 | + | |
| 59 | +//! 基本的な初期化処理 | |
| 60 | +int InitGame(HWND hWnd) | |
| 61 | +{ | |
| 62 | + //DirectX初期化 | |
| 63 | + if( d3dg.InitD3D(hWnd, "data\\char.dds", GameConfig.GetFullscreenFlag()) ){ | |
| 64 | + MessageBox(hWnd, "Direct3Dの作成に失敗しました", "error", MB_OK); | |
| 65 | + return 1; | |
| 66 | + } | |
| 67 | + | |
| 68 | + //Directinputの初期化 | |
| 69 | + if( inputCtrl.InitD3Dinput(hWnd) ){ | |
| 70 | + MessageBox(hWnd, "Input initialization error", "error", MB_OK); | |
| 71 | + return 1; | |
| 72 | + } | |
| 73 | + | |
| 74 | + //EASY DIRECT SOUND 初期化 | |
| 75 | + if( SoundCtrl.InitSound(hWnd) ){ | |
| 76 | + MessageBox(hWnd, "DLL open failed", "error", MB_OK); | |
| 77 | + return 1; | |
| 78 | + } | |
| 79 | + | |
| 80 | + //設定値を初期化 | |
| 81 | + GameParamInfo.InitInfo(); | |
| 82 | + | |
| 83 | + //リソースの初期設定 | |
| 84 | + Resource.SetParameterInfo(&GameParamInfo); | |
| 85 | + Resource.SetD3DGraphics(&d3dg); | |
| 86 | + Resource.SetSoundControl(&SoundCtrl); | |
| 87 | + | |
| 88 | + //リソースを初期化 | |
| 89 | + Resource.LoadHumanModel(); | |
| 90 | + Resource.LoadWeaponModelTexture(); | |
| 91 | + Resource.LoadWeaponSound(); | |
| 92 | + Resource.LoadSmallObjectModelTexture(); | |
| 93 | + Resource.LoadSmallObjectSound(); | |
| 94 | + Resource.LoadScopeTexture(); | |
| 95 | + Resource.LoadBulletModelTexture(); | |
| 96 | + Resource.LoadBulletSound(); | |
| 97 | + Resource.LoadEffectTexture(); | |
| 98 | + | |
| 99 | + int bulletmodel, bullettexture; | |
| 100 | + Resource.GetBulletModelTexture(&bulletmodel, &bullettexture); | |
| 101 | + | |
| 102 | + //効果音初期化 | |
| 103 | + float volume; | |
| 104 | + if( GameConfig.GetSoundFlag() == false ){ | |
| 105 | + volume = 0.0f; | |
| 106 | + } | |
| 107 | + else{ | |
| 108 | + volume = 1.0f; | |
| 109 | + } | |
| 110 | + GameSound.SetClass(&SoundCtrl, &Resource, &GameParamInfo); | |
| 111 | + SoundCtrl.SetVolume(volume); | |
| 112 | + | |
| 113 | + //オブジェクトマネージャー初期化 | |
| 114 | + ObjMgr.SetClass(&GameParamInfo, &d3dg, &Resource, &BlockData, &PointData, &CollD, &GameSound, &MIFdata); | |
| 115 | + | |
| 116 | + //addonリスト作成 | |
| 117 | + GameAddon.LoadFiledata("addon\\"); | |
| 118 | + | |
| 119 | + GameInfoData.selectaddon = false; | |
| 120 | + | |
| 121 | + return 0; | |
| 122 | +} | |
| 123 | + | |
| 124 | +//! コンストラクタ | |
| 125 | +opening::opening() | |
| 126 | +{} | |
| 127 | + | |
| 128 | +//! ディストラクタ | |
| 129 | +opening::~opening() | |
| 130 | +{} | |
| 131 | + | |
| 132 | +int opening::Create() | |
| 133 | +{ | |
| 134 | + //ブロックデータ読み込み | |
| 135 | + if( BlockData.LoadFiledata("data\\map10\\temp.bd1") ){ | |
| 136 | + //block data open failed | |
| 137 | + return 1; | |
| 138 | + } | |
| 139 | + BlockData.CalculationBlockdata(false); | |
| 140 | + d3dg->LoadMapdata(&BlockData, "data\\map10\\"); | |
| 141 | + CollD.InitCollision(&BlockData); | |
| 142 | + | |
| 143 | + //ポイントデータ読み込み | |
| 144 | + if( PointData.LoadFiledata("data\\map10\\op.pd1") ){ | |
| 145 | + //point data open failed | |
| 146 | + return 1; | |
| 147 | + } | |
| 148 | + ObjMgr.LoadPointData(); | |
| 149 | + ObjMgr.SetPlayerID(MAX_HUMAN-1); //実在しない人をプレイヤーに(銃声のサウンド再生対策) | |
| 150 | + | |
| 151 | + //AI設定 | |
| 152 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 153 | + HumanAI[i].SetClass(&ObjMgr, ObjMgr.GeHumanObject(i), &BlockData, &PointData, &GameParamInfo, &CollD, GameSound); | |
| 154 | + HumanAI[i].Init(); | |
| 155 | + } | |
| 156 | + | |
| 157 | + //背景空読み込み | |
| 158 | + Resource.LoadSkyModelTexture(1); | |
| 159 | + | |
| 160 | + //opening_banner = d3dg->LoadTexture("banner.png", true, false); | |
| 161 | + | |
| 162 | + //サウンド初期化 | |
| 163 | + GameSound->InitWorldSound(); | |
| 164 | + | |
| 165 | + //マウスカーソルを中央へ移動 | |
| 166 | + inputCtrl->MoveMouseCenter(); | |
| 167 | + framecnt = 0; | |
| 168 | + | |
| 169 | + GameState->NextState(); | |
| 170 | + return 0; | |
| 171 | +} | |
| 172 | + | |
| 173 | +void opening::Process() | |
| 174 | +{ | |
| 175 | + //オブジェクトマネージャーを実行 | |
| 176 | + ObjMgr.Process(-1, camera_x, camera_y, camera_z, camera_rx, camera_ry); | |
| 177 | + | |
| 178 | + //AIを実行 | |
| 179 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 180 | + HumanAI[i].Process(); | |
| 181 | + } | |
| 182 | + | |
| 183 | + //カメラワークを求める | |
| 184 | + if( framecnt < 3*((int)GAMEFPS) ){ | |
| 185 | + camera_x = -4.0f; | |
| 186 | + camera_y = 58.0f; | |
| 187 | + camera_z = 28.0f; | |
| 188 | + camera_rx = (float)M_PI/180*205; | |
| 189 | + camera_ry = (float)M_PI/180*13; | |
| 190 | + } | |
| 191 | + else if( framecnt < 5*((int)GAMEFPS) ){ | |
| 192 | + camera_rx += (float)M_PI/180*1.1f; | |
| 193 | + camera_ry -= (float)M_PI/180*0.7f; | |
| 194 | + } | |
| 195 | + else if( framecnt < 17*((int)GAMEFPS) ){ | |
| 196 | + camera_z += 0.1f; | |
| 197 | + camera_y -= 0.05f; | |
| 198 | + } | |
| 199 | + else { | |
| 200 | + GameState->NextState(); | |
| 201 | + } | |
| 202 | + | |
| 203 | + framecnt += 1; | |
| 204 | +} | |
| 205 | + | |
| 206 | +void opening::Render3D() | |
| 207 | +{ | |
| 208 | + int skymodel, skytexture; | |
| 209 | + | |
| 210 | + //フォグとカメラを設定 | |
| 211 | + d3dg->SetFog(1); | |
| 212 | + d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL); | |
| 213 | + | |
| 214 | + //カメラ座標に背景空を描画 | |
| 215 | + d3dg->SetWorldTransform(camera_x, camera_y, camera_z, 0.0f, 0.0f, 1.0f); | |
| 216 | + Resource.GetSkyModelTexture(&skymodel, &skytexture); | |
| 217 | + d3dg->RenderModel(skymodel, skytexture); | |
| 218 | + | |
| 219 | + //Zバッファを初期化 | |
| 220 | + d3dg->ResetZbuffer(); | |
| 221 | + | |
| 222 | + //マップを描画 | |
| 223 | + d3dg->ResetWorldTransform(); | |
| 224 | + d3dg->DrawMapdata(); | |
| 225 | + | |
| 226 | + //オブジェクトを描画 | |
| 227 | + ObjMgr.Render(camera_x, camera_y, camera_z, 0); | |
| 228 | +} | |
| 229 | + | |
| 230 | +void opening::Render2D() | |
| 231 | +{ | |
| 232 | + float effect; | |
| 233 | + | |
| 234 | + //ブラックアウト設定 | |
| 235 | + if( framecnt < 1*((int)GAMEFPS) ){ | |
| 236 | + effect = 1.0f/(1*((int)GAMEFPS)) * ((1*((int)GAMEFPS)) - framecnt); | |
| 237 | + } | |
| 238 | + if( (1*((int)GAMEFPS) <= framecnt)&&(framecnt < 13*((int)GAMEFPS)) ){ | |
| 239 | + effect = 0.0f; | |
| 240 | + } | |
| 241 | + if( (11*((int)GAMEFPS) <= framecnt)&&(framecnt < 15*((int)GAMEFPS)) ){ | |
| 242 | + effect = 1.0f/(4*((int)GAMEFPS)) * (framecnt - (11*((int)GAMEFPS))); | |
| 243 | + } | |
| 244 | + if( 15*((int)GAMEFPS) <= framecnt ){ | |
| 245 | + effect = 1.0f; | |
| 246 | + } | |
| 247 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,effect)); | |
| 248 | + | |
| 249 | + //上下の黒縁描画 | |
| 250 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, 40, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 251 | + d3dg->Draw2DBox(0, SCREEN_HEIGTH - 40, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 252 | + | |
| 253 | + //プロジェクト名 | |
| 254 | + if( ((int)(0.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(4.0f*GAMEFPS)) ){ | |
| 255 | + char str[32]; | |
| 256 | + float effectA = 1.0f; | |
| 257 | + sprintf(str, GAMENAME" project", 0, 0); | |
| 258 | + if( framecnt < (int)(1.5f*GAMEFPS) ){ effectA = 1.0f/GAMEFPS * (framecnt - (int)(0.5f*GAMEFPS)); } | |
| 259 | + if( framecnt > (int)(3.0f*GAMEFPS) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - (int)(3.0f*GAMEFPS)); } | |
| 260 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*22/2, SCREEN_HEIGTH - 140, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 22, 22); | |
| 261 | + } | |
| 262 | + | |
| 263 | + //スタッフ名・その1 | |
| 264 | + if( ((int)(4.0f*GAMEFPS) < framecnt)&&(framecnt < (int)(8.0f*GAMEFPS)) ){ | |
| 265 | + float effectA = 1.0f; | |
| 266 | + if( framecnt < (int)(5.0f*GAMEFPS) ){ effectA = 1.0f/GAMEFPS * (framecnt - (int)(4.0f*GAMEFPS)); } | |
| 267 | + if( framecnt > (int)(7.0f*GAMEFPS) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - (int)(7.0f*GAMEFPS)); } | |
| 268 | + d3dg->Draw2DTextureFontText(60, 150, "ORIGINAL", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 20, 20); | |
| 269 | + } | |
| 270 | + if( ((int)(4.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(8.5f*GAMEFPS)) ){ | |
| 271 | + float effectA = 1.0f; | |
| 272 | + if( framecnt < (int)(5.5f*GAMEFPS) ){ effectA = 1.0f/GAMEFPS * (framecnt - (int)(4.5f*GAMEFPS)); } | |
| 273 | + if( framecnt > (int)(7.5f*GAMEFPS) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - (int)(7.5f*GAMEFPS)); } | |
| 274 | + d3dg->Draw2DTextureFontText(100, 180, "nine-two", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 20, 20); | |
| 275 | + d3dg->Draw2DTextureFontText(100, 210, "TENNKUU", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 20, 20); | |
| 276 | + } | |
| 277 | + | |
| 278 | + //スタッフ名・その2 | |
| 279 | + if( ((int)(7.0f*GAMEFPS) < framecnt)&&(framecnt < (int)(11.0f*GAMEFPS)) ){ | |
| 280 | + float effectA = 1.0f; | |
| 281 | + if( framecnt < (int)(8.0f*GAMEFPS) ){ effectA = 1.0f/GAMEFPS * (framecnt - (int)(7.0f*GAMEFPS)); } | |
| 282 | + if( framecnt > (int)(10.0f*GAMEFPS) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - (int)(10.0f*GAMEFPS)); } | |
| 283 | + d3dg->Draw2DTextureFontText(330, 300, "REMAKE", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 20, 20); | |
| 284 | + } | |
| 285 | + if( ((int)(7.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(11.5f*GAMEFPS)) ){ | |
| 286 | + float effectA = 1.0f; | |
| 287 | + if( framecnt < (int)(8.5f*GAMEFPS) ){ effectA = 1.0f/GAMEFPS * (framecnt - (int)(7.5f*GAMEFPS)); } | |
| 288 | + if( framecnt > (int)(10.5f*GAMEFPS) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - (int)(10.5f*GAMEFPS)); } | |
| 289 | + d3dg->Draw2DTextureFontText(370, 330, "[-_-;](mikan)", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA), 20, 20); | |
| 290 | + //d3dg->Draw2DTexture(410, 360, opening_banner, 200, 40, effectA); | |
| 291 | + } | |
| 292 | + | |
| 293 | + //ゲーム名 | |
| 294 | + if( 12*((int)GAMEFPS) <= framecnt ){ //framecnt < 17*((int)GAMEFPS) | |
| 295 | + char str[32]; | |
| 296 | + float effectA = 1.0f; | |
| 297 | + sprintf(str, GAMENAME, 0, 0); | |
| 298 | + if( framecnt < (13*((int)GAMEFPS)) ){ effectA = 1.0f/GAMEFPS * (framecnt - 12*((int)GAMEFPS)); } | |
| 299 | + if( (16*((int)GAMEFPS) < framecnt)&&(framecnt < (17*((int)GAMEFPS))) ){ effectA = 1.0f - 1.0f/GAMEFPS * (framecnt - 16*((int)GAMEFPS)); } | |
| 300 | + if( framecnt >= (17*((int)GAMEFPS)) ){ effectA = 0.0f; } | |
| 301 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*22/2, (SCREEN_HEIGTH-11)/2, str, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,effectA), 22, 22); | |
| 302 | + } | |
| 303 | +} | |
| 304 | + | |
| 305 | +void opening::Destroy() | |
| 306 | +{ | |
| 307 | + //ブロックデータ解放 | |
| 308 | + d3dg->CleanupMapdata(); | |
| 309 | + | |
| 310 | + //オブジェクトマネージャー解放 | |
| 311 | + ObjMgr.Cleanup(); | |
| 312 | + | |
| 313 | + //背景空解放 | |
| 314 | + Resource.CleanupSkyModelTexture(); | |
| 315 | + | |
| 316 | + //d3dg->CleanupTexture(opening_banner); | |
| 317 | + | |
| 318 | + GameState->NextState(); | |
| 319 | +} | |
| 320 | + | |
| 321 | +//! コンストラクタ | |
| 322 | +mainmenu::mainmenu() | |
| 323 | +{ | |
| 324 | + mainmenu_scrollitems_official = 0; | |
| 325 | + mainmenu_scrollitems_addon = 0; | |
| 326 | +} | |
| 327 | + | |
| 328 | +//! ディストラクタ | |
| 329 | +mainmenu::~mainmenu() | |
| 330 | +{} | |
| 331 | + | |
| 332 | +int mainmenu::Create() | |
| 333 | +{ | |
| 334 | + char path[MAX_PATH]; | |
| 335 | + char bdata[MAX_PATH]; | |
| 336 | + char pdata[MAX_PATH]; | |
| 337 | + | |
| 338 | + //デモを決定し読み込む | |
| 339 | + switch( GetRand(6) ){ | |
| 340 | + case 0: | |
| 341 | + strcpy(path, "data\\map2\\"); | |
| 342 | + break; | |
| 343 | + case 1: | |
| 344 | + strcpy(path, "data\\map4\\"); | |
| 345 | + break; | |
| 346 | + case 2: | |
| 347 | + strcpy(path, "data\\map5\\"); | |
| 348 | + break; | |
| 349 | + case 3: | |
| 350 | + strcpy(path, "data\\map7\\"); | |
| 351 | + break; | |
| 352 | + case 4: | |
| 353 | + strcpy(path, "data\\map8\\"); | |
| 354 | + break; | |
| 355 | + case 5: | |
| 356 | + strcpy(path, "data\\map16\\"); | |
| 357 | + break; | |
| 358 | + } | |
| 359 | + strcpy(bdata, path); | |
| 360 | + strcat(bdata, "temp.bd1"); | |
| 361 | + strcpy(pdata, path); | |
| 362 | + strcat(pdata, "demo.pd1"); | |
| 363 | + | |
| 364 | + //ブロックデータ読み込み | |
| 365 | + if( BlockData.LoadFiledata(bdata) ){ | |
| 366 | + //block data open failed | |
| 367 | + return 1; | |
| 368 | + } | |
| 369 | + BlockData.CalculationBlockdata(false); | |
| 370 | + d3dg->LoadMapdata(&BlockData, path); | |
| 371 | + CollD.InitCollision(&BlockData); | |
| 372 | + | |
| 373 | + //ポイントデータ読み込み | |
| 374 | + if( PointData.LoadFiledata(pdata) ){ | |
| 375 | + //point data open failed | |
| 376 | + return 1; | |
| 377 | + } | |
| 378 | + ObjMgr.LoadPointData(); | |
| 379 | + | |
| 380 | + //AI設定 | |
| 381 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 382 | + HumanAI[i].SetClass(&ObjMgr, ObjMgr.GeHumanObject(i), &BlockData, &PointData, &GameParamInfo, &CollD, GameSound); | |
| 383 | + HumanAI[i].Init(); | |
| 384 | + } | |
| 385 | + | |
| 386 | + gametitle = d3dg->LoadTexture("data\\title.dds", false, false); | |
| 387 | + | |
| 388 | + //サウンド初期化 | |
| 389 | + GameSound->InitWorldSound(); | |
| 390 | + | |
| 391 | + mainmenu_mouseX = SCREEN_WIDTH/2; | |
| 392 | + mainmenu_mouseY = SCREEN_HEIGTH/2; | |
| 393 | + | |
| 394 | + //標準ミッションのスクロールバーの設定 | |
| 395 | + if( TOTAL_OFFICIALMISSION > TOTAL_MENUITEMS ){ | |
| 396 | + mainmenu_scrollbar_official_height = (float)(MAINMENU_H-25) / TOTAL_OFFICIALMISSION * TOTAL_MENUITEMS; | |
| 397 | + mainmenu_scrollbar_official_scale = ((float)(MAINMENU_H-25) - mainmenu_scrollbar_official_height) / (TOTAL_OFFICIALMISSION - TOTAL_MENUITEMS); | |
| 398 | + } | |
| 399 | + else{ | |
| 400 | + mainmenu_scrollbar_official_height = 0.0f; | |
| 401 | + mainmenu_scrollbar_official_scale = 0.0f; | |
| 402 | + } | |
| 403 | + | |
| 404 | + //addonのスクロールバーの設定 | |
| 405 | + if( TOTAL_OFFICIALMISSION > TOTAL_MENUITEMS ){ | |
| 406 | + mainmenu_scrollbar_addon_height = (float)(MAINMENU_H-25) / GameAddon.GetTotaldatas() * TOTAL_MENUITEMS; | |
| 407 | + mainmenu_scrollbar_addon_scale = ((float)(MAINMENU_H-25) - mainmenu_scrollbar_addon_height) / (GameAddon.GetTotaldatas() - TOTAL_MENUITEMS); | |
| 408 | + } | |
| 409 | + else{ | |
| 410 | + mainmenu_scrollbar_addon_height = 0.0f; | |
| 411 | + mainmenu_scrollbar_addon_scale = 0.0f; | |
| 412 | + } | |
| 413 | + | |
| 414 | + mainmenu_scrollbar_official_y = 141; | |
| 415 | + mainmenu_scrollbar_addon_y = 141; | |
| 416 | + mainmenu_scrollbar_flag = false; | |
| 417 | + inputCtrl->MoveMouseCenter(); | |
| 418 | + framecnt = 0; | |
| 419 | + | |
| 420 | + GameState->NextState(); | |
| 421 | + return 0; | |
| 422 | +} | |
| 423 | + | |
| 424 | +void mainmenu::Input() | |
| 425 | +{ | |
| 426 | + inputCtrl->GetInputState(false); | |
| 427 | + | |
| 428 | + //スクロールバーの情報などを取得 | |
| 429 | + int scrollitems; | |
| 430 | + float scrollbar_height; | |
| 431 | + float scrollbar_scale; | |
| 432 | + int scrollbar_y; | |
| 433 | + int totalmission; | |
| 434 | + if( GameInfoData.selectaddon == false ){ | |
| 435 | + scrollitems = mainmenu_scrollitems_official; | |
| 436 | + scrollbar_height = mainmenu_scrollbar_official_height; | |
| 437 | + scrollbar_scale = mainmenu_scrollbar_official_scale; | |
| 438 | + scrollbar_y = mainmenu_scrollbar_official_y; | |
| 439 | + totalmission = TOTAL_OFFICIALMISSION; | |
| 440 | + } | |
| 441 | + else{ | |
| 442 | + scrollitems = mainmenu_scrollitems_addon; | |
| 443 | + scrollbar_height = mainmenu_scrollbar_addon_height; | |
| 444 | + scrollbar_scale = mainmenu_scrollbar_addon_scale; | |
| 445 | + scrollbar_y = mainmenu_scrollbar_addon_y; | |
| 446 | + totalmission = GameAddon.GetTotaldatas(); | |
| 447 | + } | |
| 448 | + | |
| 449 | + //マウス座標を取得 | |
| 450 | + int y = mainmenu_mouseY; | |
| 451 | + inputCtrl->GetMouseMovement(&mainmenu_mouseX, &mainmenu_mouseY); | |
| 452 | + if( mainmenu_mouseX < 0 ){ mainmenu_mouseX = 0; } | |
| 453 | + if( mainmenu_mouseX > SCREEN_WIDTH-1 ){ mainmenu_mouseX = SCREEN_WIDTH-1; } | |
| 454 | + if( mainmenu_mouseY < 0 ){ mainmenu_mouseY = 0; } | |
| 455 | + if( mainmenu_mouseY > SCREEN_HEIGTH-1 ){ mainmenu_mouseY = SCREEN_HEIGTH-1; } | |
| 456 | + | |
| 457 | + //ESCキーを処理 | |
| 458 | + if( inputCtrl->CheckKeyDown(GetEscKeycode()) ){ | |
| 459 | + GameState->PushBackSpaceKey(); | |
| 460 | + } | |
| 461 | + | |
| 462 | + //スクロールバーを押したか判定 | |
| 463 | + if( inputCtrl->CheckMouseButtonDownL() ){ | |
| 464 | + if( ((MAINMENU_X+341) < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+360))&&(MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems) < mainmenu_mouseY) | |
| 465 | + &&(mainmenu_mouseY < MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems + scrollbar_height)) | |
| 466 | + ){ | |
| 467 | + mainmenu_scrollbar_flag = true; | |
| 468 | + } | |
| 469 | + } | |
| 470 | + | |
| 471 | + if( inputCtrl->CheckMouseButtonUpL() ){ | |
| 472 | + mainmenu_scrollbar_flag = false; | |
| 473 | + | |
| 474 | + // UP | |
| 475 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&(MAINMENU_Y < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30) ){ | |
| 476 | + if( scrollitems > 0 ){ scrollitems -= 1; } | |
| 477 | + } | |
| 478 | + | |
| 479 | + // DOWN | |
| 480 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-55) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-55+30)) ){ | |
| 481 | + if( scrollitems < (totalmission - TOTAL_MENUITEMS) ){ scrollitems += 1; } | |
| 482 | + } | |
| 483 | + | |
| 484 | + //ミッション選択 | |
| 485 | + for(int i=0; i<TOTAL_MENUITEMS; i++){ | |
| 486 | + char name[32]; | |
| 487 | + if( GameInfoData.selectaddon == false ){ | |
| 488 | + GameParamInfo.GetOfficialMission(scrollitems + i, name, NULL, NULL, NULL); | |
| 489 | + } | |
| 490 | + else{ | |
| 491 | + strcpy(name, GameAddon.GetMissionName(scrollitems + i)); | |
| 492 | + } | |
| 493 | + | |
| 494 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+(signed)strlen(name)*20))&&(MAINMENU_Y+30 + i*30 < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30 + i*30 + 26) ){ | |
| 495 | + GameInfoData.selectmission_id = scrollitems + i; | |
| 496 | + GameState->PushMouseButton(); | |
| 497 | + } | |
| 498 | + } | |
| 499 | + } | |
| 500 | + | |
| 501 | + //スクロールバーの移動 | |
| 502 | + if( mainmenu_scrollbar_flag == true ){ | |
| 503 | + scrollbar_y += mainmenu_mouseY - y; | |
| 504 | + if( scrollbar_y < MAINMENU_Y+1 ){ scrollbar_y = MAINMENU_Y+1; } | |
| 505 | + if( scrollbar_y > MAINMENU_Y+MAINMENU_H-24 - (int)(scrollbar_height) ){ scrollbar_y = MAINMENU_Y+MAINMENU_H-24 - (int)(scrollbar_height); } | |
| 506 | + | |
| 507 | + scrollitems = (scrollbar_y - (MAINMENU_Y+1)) / (int)(scrollbar_scale); | |
| 508 | + if( scrollitems < 0 ){ | |
| 509 | + scrollitems = 0; | |
| 510 | + } | |
| 511 | + if( scrollitems > (totalmission - TOTAL_MENUITEMS) ){ | |
| 512 | + scrollitems = (totalmission - TOTAL_MENUITEMS); | |
| 513 | + } | |
| 514 | + } | |
| 515 | + else{ | |
| 516 | + scrollbar_y = MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems); | |
| 517 | + } | |
| 518 | + | |
| 519 | + //スクロールバーの情報などを反映 | |
| 520 | + if( GameInfoData.selectaddon == false ){ | |
| 521 | + mainmenu_scrollitems_official = scrollitems; | |
| 522 | + mainmenu_scrollbar_official_y = scrollbar_y; | |
| 523 | + } | |
| 524 | + else{ | |
| 525 | + mainmenu_scrollitems_addon = scrollitems; | |
| 526 | + mainmenu_scrollbar_addon_y = scrollbar_y; | |
| 527 | + } | |
| 528 | + | |
| 529 | + //標準ミッションとアドオンリストの切り替え | |
| 530 | + if( inputCtrl->CheckMouseButtonUpL() ){ | |
| 531 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){ | |
| 532 | + if( GameInfoData.selectaddon == false ){ | |
| 533 | + if( GameAddon.GetTotaldatas() > 0 ){ | |
| 534 | + GameInfoData.selectaddon = true; | |
| 535 | + } | |
| 536 | + } | |
| 537 | + else{ | |
| 538 | + GameInfoData.selectaddon = false; | |
| 539 | + } | |
| 540 | + } | |
| 541 | + } | |
| 542 | +} | |
| 543 | + | |
| 544 | +void mainmenu::Process() | |
| 545 | +{ | |
| 546 | + //オブジェクトマネージャーを実行 | |
| 547 | + ObjMgr.Process(-1, camera_x, camera_y, camera_z, camera_rx, camera_ry); | |
| 548 | + | |
| 549 | + //AIを実行 | |
| 550 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 551 | + HumanAI[i].Process(); | |
| 552 | + } | |
| 553 | + | |
| 554 | + //カメラ位置を計算 | |
| 555 | + human *myHuman = ObjMgr.GetPlayerHumanObject(); | |
| 556 | + myHuman->GetPosData(&camera_x, &camera_y, &camera_z, NULL); | |
| 557 | + camera_x -= 4.0f; | |
| 558 | + camera_y += 22.0f; | |
| 559 | + camera_z -= 12.0f; | |
| 560 | + camera_rx = (float)M_PI/180 * (45); | |
| 561 | + camera_ry = (float)M_PI/180 * (-25); | |
| 562 | + | |
| 563 | + framecnt += 1; | |
| 564 | +} | |
| 565 | + | |
| 566 | +void mainmenu::Render3D() | |
| 567 | +{ | |
| 568 | + //フォグとカメラを設定 | |
| 569 | + d3dg->SetFog(0); | |
| 570 | + d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL); | |
| 571 | + | |
| 572 | + //Zバッファを初期化 | |
| 573 | + d3dg->ResetZbuffer(); | |
| 574 | + | |
| 575 | + //マップを描画 | |
| 576 | + d3dg->ResetWorldTransform(); | |
| 577 | + d3dg->DrawMapdata(); | |
| 578 | + | |
| 579 | + //オブジェクトを描画 | |
| 580 | + ObjMgr.Render(camera_x, camera_y, camera_z, 0); | |
| 581 | +} | |
| 582 | + | |
| 583 | +void mainmenu::Render2D() | |
| 584 | +{ | |
| 585 | + int color, color2; | |
| 586 | + float effect; | |
| 587 | + | |
| 588 | + //スクロールバーの情報などを取得 | |
| 589 | + int scrollitems; | |
| 590 | + float scrollbar_height; | |
| 591 | + int scrollbar_y; | |
| 592 | + int totalmission; | |
| 593 | + if( GameInfoData.selectaddon == false ){ | |
| 594 | + scrollitems = mainmenu_scrollitems_official; | |
| 595 | + scrollbar_height = mainmenu_scrollbar_official_height; | |
| 596 | + scrollbar_y = mainmenu_scrollbar_official_y; | |
| 597 | + totalmission = TOTAL_OFFICIALMISSION; | |
| 598 | + } | |
| 599 | + else{ | |
| 600 | + scrollitems = mainmenu_scrollitems_addon; | |
| 601 | + scrollbar_height = mainmenu_scrollbar_addon_height; | |
| 602 | + scrollbar_y = mainmenu_scrollbar_addon_y; | |
| 603 | + totalmission = GameAddon.GetTotaldatas(); | |
| 604 | + } | |
| 605 | + | |
| 606 | + //ゲームのバージョン情報描画 | |
| 607 | + d3dg->Draw2DTextureFontText(522+1, 75+1, GAMEVERSION, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 18, 22); | |
| 608 | + d3dg->Draw2DTextureFontText(522, 75, GAMEVERSION, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 18, 22); | |
| 609 | + | |
| 610 | + //メニューエリア描画 | |
| 611 | + d3dg->Draw2DBox(MAINMENU_X-1, MAINMENU_Y, MAINMENU_X+360, MAINMENU_Y+MAINMENU_H, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.5f)); | |
| 612 | + d3dg->Draw2DBox(MAINMENU_X+341, MAINMENU_Y+1, MAINMENU_X+360, MAINMENU_Y+MAINMENU_H-24, D3DCOLOR_COLORVALUE(0.5f,0.5f,0.5f,0.5f)); | |
| 613 | + | |
| 614 | + //スクロールバー描画 | |
| 615 | + if( totalmission > TOTAL_MENUITEMS ){ | |
| 616 | + //色を設定 | |
| 617 | + if( mainmenu_scrollbar_flag == true ){ | |
| 618 | + color = D3DCOLOR_COLORVALUE(0.6f,0.3f,0.25f,1.0f); | |
| 619 | + color2 = D3DCOLOR_COLORVALUE(0.8f,0.3f,0.25f,1.0f); | |
| 620 | + } | |
| 621 | + else if( ((MAINMENU_X+341) < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+360))&&(scrollbar_y < mainmenu_mouseY)&&(mainmenu_mouseY < scrollbar_y + (int)scrollbar_height) ){ | |
| 622 | + color = D3DCOLOR_COLORVALUE(0.4f,0.67f,0.57f,1.0f); | |
| 623 | + color2 = D3DCOLOR_COLORVALUE(0.38f,0.77f,0.64f,1.0f); | |
| 624 | + } | |
| 625 | + else{ | |
| 626 | + color = D3DCOLOR_COLORVALUE(0.6f,0.6f,0.25f,1.0f); | |
| 627 | + color2 = D3DCOLOR_COLORVALUE(0.8f,0.8f,0.25f,1.0f); | |
| 628 | + } | |
| 629 | + | |
| 630 | + //描画 | |
| 631 | + d3dg->Draw2DBox(MAINMENU_X+341, scrollbar_y, MAINMENU_X+360, scrollbar_y + (int)scrollbar_height, color); | |
| 632 | + d3dg->Draw2DBox(MAINMENU_X+341+3, scrollbar_y +3, MAINMENU_X+360-3, scrollbar_y + (int)scrollbar_height -3, color2); | |
| 633 | + } | |
| 634 | + | |
| 635 | + //'< UP >'描画 | |
| 636 | + d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+1, "< UP >", D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 20, 26); | |
| 637 | + if( scrollitems > 0 ){ | |
| 638 | + //文字の色を設定 | |
| 639 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&(MAINMENU_Y < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30) ){ | |
| 640 | + color = D3DCOLOR_COLORVALUE(0.0f,1.0f,1.0f,1.0f); | |
| 641 | + } | |
| 642 | + else{ | |
| 643 | + color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f); | |
| 644 | + } | |
| 645 | + | |
| 646 | + //文字を描画 | |
| 647 | + d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y, "< UP >", color, 20, 26); | |
| 648 | + } | |
| 649 | + | |
| 650 | + //'< DOWN >'描画 | |
| 651 | + d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-55+1, "< DOWN >", D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 20, 26); | |
| 652 | + if( scrollitems < (totalmission - TOTAL_MENUITEMS) ){ | |
| 653 | + //文字の色を設定 | |
| 654 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-55) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-55+30)) ){ | |
| 655 | + color = D3DCOLOR_COLORVALUE(0.0f,1.0f,1.0f,1.0f); | |
| 656 | + } | |
| 657 | + else{ | |
| 658 | + color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f); | |
| 659 | + } | |
| 660 | + | |
| 661 | + //文字を描画 | |
| 662 | + d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-55, "< DOWN >", color, 20, 26); | |
| 663 | + } | |
| 664 | + | |
| 665 | + //標準ミッションとaddon切り替え | |
| 666 | + if( GameInfoData.selectaddon == false ){ | |
| 667 | + //下地の文字を描画 | |
| 668 | + d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-25+1, "ADD-ON MISSIONS >>", D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 16, 23); | |
| 669 | + | |
| 670 | + //addonがあれば | |
| 671 | + if( GameAddon.GetTotaldatas() > 0 ){ | |
| 672 | + //文字の色を設定 | |
| 673 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){ | |
| 674 | + color = D3DCOLOR_COLORVALUE(0.0f,1.0f,1.0f,1.0f); | |
| 675 | + } | |
| 676 | + else{ | |
| 677 | + color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f); | |
| 678 | + } | |
| 679 | + | |
| 680 | + //文字を描画 | |
| 681 | + d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-25, "ADD-ON MISSIONS >>", color, 16, 23); | |
| 682 | + } | |
| 683 | + } | |
| 684 | + else{ | |
| 685 | + //文字の色を設定 | |
| 686 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){ | |
| 687 | + color = D3DCOLOR_COLORVALUE(0.0f,1.0f,1.0f,1.0f); | |
| 688 | + } | |
| 689 | + else{ | |
| 690 | + color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f); | |
| 691 | + } | |
| 692 | + | |
| 693 | + //文字を描画 | |
| 694 | + d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-25+1, "<< STANDARD MISSIONS", D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 16, 23); | |
| 695 | + d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-25, "<< STANDARD MISSIONS", color, 16, 23); | |
| 696 | + } | |
| 697 | + | |
| 698 | + //ミッション名を描画 | |
| 699 | + for(int i=0; i<TOTAL_MENUITEMS; i++){ | |
| 700 | + char name[32]; | |
| 701 | + strcpy(name, ""); | |
| 702 | + | |
| 703 | + //ミッション名を取得 | |
| 704 | + if( GameInfoData.selectaddon == false ){ | |
| 705 | + GameParamInfo.GetOfficialMission(scrollitems + i, name, NULL, NULL, NULL); | |
| 706 | + } | |
| 707 | + else{ | |
| 708 | + strcpy(name, GameAddon.GetMissionName(scrollitems + i)); | |
| 709 | + } | |
| 710 | + | |
| 711 | + //文字の色を設定 | |
| 712 | + if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+(signed)strlen(name)*20))&&(MAINMENU_Y+30 + i*30 < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30 + i*30 + 26) ){ | |
| 713 | + color = D3DCOLOR_COLORVALUE(1.0f,0.6f,0.6f,1.0f); | |
| 714 | + } | |
| 715 | + else{ | |
| 716 | + color = D3DCOLOR_COLORVALUE(0.6f,0.6f,1.0f,1.0f); | |
| 717 | + } | |
| 718 | + | |
| 719 | + //文字を描画 | |
| 720 | + d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+30+1 + i*30, name, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 20, 26); | |
| 721 | + d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+30 + i*30, name, color, 20, 26); | |
| 722 | + } | |
| 723 | + | |
| 724 | + //マウスカーソル描画(赤線) | |
| 725 | + d3dg->Draw2DBox(0, mainmenu_mouseY-1, SCREEN_WIDTH, mainmenu_mouseY+1, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 726 | + d3dg->Draw2DBox(mainmenu_mouseX-1, 0, mainmenu_mouseX+1, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 727 | + d3dg->Draw2DLine(0, mainmenu_mouseY, SCREEN_WIDTH, mainmenu_mouseY, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 728 | + d3dg->Draw2DLine(mainmenu_mouseX, 0, mainmenu_mouseX, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 729 | + | |
| 730 | + //ゲームのロゴマーク描画 | |
| 731 | + d3dg->Draw2DTexture(20, 25, gametitle, 480, 80, 1.0f); | |
| 732 | + | |
| 733 | + //ブラックアウト設定 | |
| 734 | + if( framecnt < 2*((int)GAMEFPS) ){ | |
| 735 | + effect = 1.0f/(2*((int)GAMEFPS)) * (2*((int)GAMEFPS) - framecnt); | |
| 736 | + } | |
| 737 | + else{ | |
| 738 | + effect = 0.0f; | |
| 739 | + } | |
| 740 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,effect)); | |
| 741 | +} | |
| 742 | + | |
| 743 | +void mainmenu::Destroy() | |
| 744 | +{ | |
| 745 | + //ブロックデータ解放 | |
| 746 | + d3dg->CleanupMapdata(); | |
| 747 | + | |
| 748 | + //オブジェクトマネージャー解放 | |
| 749 | + ObjMgr.Cleanup(); | |
| 750 | + | |
| 751 | + //背景空解放 | |
| 752 | + Resource.CleanupSkyModelTexture(); | |
| 753 | + | |
| 754 | + d3dg->CleanupTexture(gametitle); | |
| 755 | + | |
| 756 | + GameState->NextState(); | |
| 757 | +} | |
| 758 | + | |
| 759 | +//! コンストラクタ | |
| 760 | +briefing::briefing() | |
| 761 | +{} | |
| 762 | + | |
| 763 | +//! ディストラクタ | |
| 764 | +briefing::~briefing() | |
| 765 | +{} | |
| 766 | + | |
| 767 | +int briefing::Create() | |
| 768 | +{ | |
| 769 | + char path[MAX_PATH]; | |
| 770 | + char pdata[MAX_PATH]; | |
| 771 | + char PictureA[MAX_PATH]; | |
| 772 | + char PictureB[MAX_PATH]; | |
| 773 | + | |
| 774 | + //背景画像を取得 | |
| 775 | + gametitle = d3dg->LoadTexture("data\\title.dds", false, false); | |
| 776 | + | |
| 777 | + //mifファイルのファイルパス取得 | |
| 778 | + if( GameInfoData.selectaddon == false ){ | |
| 779 | + GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, NULL, path, pdata); | |
| 780 | + strcat(path, pdata); | |
| 781 | + strcat(path, ".txt"); | |
| 782 | + } | |
| 783 | + else{ | |
| 784 | + strcpy(path, "addon\\"); | |
| 785 | + strcat(path, GameAddon.GetFileName(GameInfoData.selectmission_id)); | |
| 786 | + } | |
| 787 | + | |
| 788 | + //mifファイルを読み込み | |
| 789 | + if( MIFdata.LoadFiledata(path) != 0 ){ | |
| 790 | + //briefing data open failed | |
| 791 | + return 1; | |
| 792 | + } | |
| 793 | + | |
| 794 | + //ブリーフィング画像のファイルパス取得 | |
| 795 | + MIFdata.GetPicturefilePath(PictureA, PictureB); | |
| 796 | + | |
| 797 | + //ブリーフィング画像読み込み | |
| 798 | + if( strcmp(PictureB, "!") == 0 ){ | |
| 799 | + TwoTexture = false; | |
| 800 | + TextureA = d3dg->LoadTexture(PictureA, true, false); | |
| 801 | + TextureB = -1; | |
| 802 | + } | |
| 803 | + else{ | |
| 804 | + TwoTexture = true; | |
| 805 | + TextureA = d3dg->LoadTexture(PictureA, true, false); | |
| 806 | + TextureB = d3dg->LoadTexture(PictureB, true, false); | |
| 807 | + } | |
| 808 | + | |
| 809 | + //マウスカーソルを中央へ移動 | |
| 810 | + inputCtrl->MoveMouseCenter(); | |
| 811 | + framecnt = 0; | |
| 812 | + | |
| 813 | + GameState->NextState(); | |
| 814 | + return 0; | |
| 815 | +} | |
| 816 | + | |
| 817 | +void briefing::Render2D() | |
| 818 | +{ | |
| 819 | + float effectA = 1.0f - 0.8f/((int)(GAMEFPS*0.7f))*(framecnt%((int)(GAMEFPS*0.7f))); | |
| 820 | + float effectB = 1.0f - 0.8f/((int)(GAMEFPS*0.8f))*(framecnt%((int)(GAMEFPS*1.0f))); | |
| 821 | + int effectB_sizeW = (int)( (float)(framecnt%((int)(GAMEFPS*1.0f))) * 0.2f + 18 ); | |
| 822 | + int effectB_sizeH = (int)( (float)(framecnt%((int)(GAMEFPS*1.0f))) * 1.0f + 25 ); | |
| 823 | + | |
| 824 | + //メモ:背景画像の描画は、自動的に行われる。 | |
| 825 | + | |
| 826 | + //固定文字描画 | |
| 827 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 60*4, 30, "BRIEFING", D3DCOLOR_COLORVALUE(1.0f,1.0f,0.0f,effectA), 60, 42); | |
| 828 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH - 220 - effectB_sizeW*9 - effectB_sizeW/2, SCREEN_HEIGTH - 37 - effectB_sizeH/2, | |
| 829 | + "LEFT CLICK TO BEGIN", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectB), effectB_sizeW, effectB_sizeH); | |
| 830 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH - 390, SCREEN_HEIGTH - 50, "LEFT CLICK TO BEGIN", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 18, 25); | |
| 831 | + | |
| 832 | + //ブリーフィング画像描画 | |
| 833 | + if( TwoTexture == false ){ | |
| 834 | + d3dg->Draw2DBox(40, 180, 40+160, 180+150, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f)); | |
| 835 | + d3dg->Draw2DTexture(40, 180, TextureA, 160, 150, 1.0f); | |
| 836 | + } | |
| 837 | + else{ | |
| 838 | + d3dg->Draw2DBox(40, 130, 40+160, 130+150, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f)); | |
| 839 | + d3dg->Draw2DTexture(40, 130, TextureA, 160, 150, 1.0f); | |
| 840 | + | |
| 841 | + d3dg->Draw2DBox(40, 300, 40+160, 300+150, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f)); | |
| 842 | + d3dg->Draw2DTexture(40, 300, TextureB, 160, 150, 1.0f); | |
| 843 | + } | |
| 844 | + | |
| 845 | + //ミッション名を取得・描画 | |
| 846 | + char mname[64]; | |
| 847 | + if( MIFdata.GetFiletype() == false ){ | |
| 848 | + GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, mname, NULL, NULL); | |
| 849 | + } | |
| 850 | + else{ | |
| 851 | + strcpy(mname, MIFdata.GetMissionFullname()); | |
| 852 | + } | |
| 853 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(mname)*18/2, 90, mname, D3DCOLOR_COLORVALUE(1.0f,0.5f,0.0f,1.0f), 18, 25); | |
| 854 | + | |
| 855 | + //ミッション説明を描画 | |
| 856 | + d3dg->Draw2DMSFontText(230, 180, MIFdata.GetBriefingText(), D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f)); | |
| 857 | +} | |
| 858 | + | |
| 859 | +void briefing::Destroy(){ | |
| 860 | + //ブリーフィング画像を開放 | |
| 861 | + d3dg->CleanupTexture(TextureA); | |
| 862 | + d3dg->CleanupTexture(TextureB); | |
| 863 | + | |
| 864 | + //背景画像を開放 | |
| 865 | + d3dg->CleanupTexture(gametitle); | |
| 866 | + | |
| 867 | + GameState->NextState(); | |
| 868 | +} | |
| 869 | + | |
| 870 | +//! コンストラクタ | |
| 871 | +maingame::maingame() | |
| 872 | +{ | |
| 873 | + ShowInfo_Debugmode = false; | |
| 874 | + Camera_F2mode = 0; | |
| 875 | + Camera_HOMEmode = false; | |
| 876 | + time_input = 0; | |
| 877 | + time_process_object = 0; | |
| 878 | + time_process_ai = 0; | |
| 879 | + time_process_event = 0; | |
| 880 | + time_sound = 0; | |
| 881 | + time_render = 0; | |
| 882 | +} | |
| 883 | + | |
| 884 | +//! ディストラクタ | |
| 885 | +maingame::~maingame() | |
| 886 | +{} | |
| 887 | + | |
| 888 | +int maingame::Create() | |
| 889 | +{ | |
| 890 | + MainGameInfo = GameInfoData; | |
| 891 | + char path[MAX_PATH]; | |
| 892 | + char bdata[MAX_PATH]; | |
| 893 | + char pdata[MAX_PATH]; | |
| 894 | + char pdata2[MAX_PATH]; | |
| 895 | + | |
| 896 | + //.bd1と.pd1のファイルパスを求める | |
| 897 | + if( MIFdata.GetFiletype() == false ){ | |
| 898 | + GameParamInfo.GetOfficialMission(MainGameInfo.selectmission_id, NULL, NULL, path, pdata2); | |
| 899 | + | |
| 900 | + strcpy(bdata, path); | |
| 901 | + strcat(bdata, "temp.bd1"); | |
| 902 | + strcpy(pdata, path); | |
| 903 | + strcat(pdata, pdata2); | |
| 904 | + strcat(pdata, ".pd1"); | |
| 905 | + } | |
| 906 | + else{ | |
| 907 | + MIFdata.GetDatafilePath(bdata, pdata); | |
| 908 | + | |
| 909 | + strcpy(path, bdata); | |
| 910 | + for(int i=strlen(path)-1; i>0; i--){ | |
| 911 | + if( path[i] == '\\' ){ | |
| 912 | + path[i+1] = 0x00; | |
| 913 | + break; | |
| 914 | + } | |
| 915 | + } | |
| 916 | + } | |
| 917 | + | |
| 918 | + //追加小物を読み込む | |
| 919 | + Resource.LoadAddSmallObject(MIFdata.GetAddSmallobjectModelPath(), MIFdata.GetAddSmallobjectTexturePath(), MIFdata.GetAddSmallobjectSoundPath()); | |
| 920 | + | |
| 921 | + //ブロックデータ読み込み | |
| 922 | + if( BlockData.LoadFiledata(bdata) ){ | |
| 923 | + //block data open failed | |
| 924 | + return 1; | |
| 925 | + } | |
| 926 | + BlockData.CalculationBlockdata(MIFdata.GetScreenFlag()); | |
| 927 | + d3dg->LoadMapdata(&BlockData, path); | |
| 928 | + CollD.InitCollision(&BlockData); | |
| 929 | + | |
| 930 | + //ポイントデータ読み込み | |
| 931 | + if( PointData.LoadFiledata(pdata) ){ | |
| 932 | + //point data open failed | |
| 933 | + return 1; | |
| 934 | + } | |
| 935 | + ObjMgr.LoadPointData(); | |
| 936 | + | |
| 937 | + //AI設定 | |
| 938 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 939 | + HumanAI[i].SetClass(&ObjMgr, ObjMgr.GeHumanObject(i), &BlockData, &PointData, &GameParamInfo, &CollD, GameSound); | |
| 940 | + HumanAI[i].Init(); | |
| 941 | + } | |
| 942 | + | |
| 943 | + | |
| 944 | + //背景空読み込み | |
| 945 | + Resource.LoadSkyModelTexture(MIFdata.GetSkynumber()); | |
| 946 | + | |
| 947 | + //サウンド初期化 | |
| 948 | + GameSound->InitWorldSound(); | |
| 949 | + | |
| 950 | + //イベント初期化 | |
| 951 | + for(int i=0; i<TOTAL_EVENTLINE; i++){ | |
| 952 | + Event[i].SetClass(&PointData, &ObjMgr); | |
| 953 | + } | |
| 954 | + Event[0].Reset(TOTAL_EVENTENTRYPOINT_0); | |
| 955 | + Event[1].Reset(TOTAL_EVENTENTRYPOINT_1); | |
| 956 | + Event[2].Reset(TOTAL_EVENTENTRYPOINT_2); | |
| 957 | + | |
| 958 | + //プレイヤーの向きを取得 | |
| 959 | + ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry); | |
| 960 | + | |
| 961 | + view_rx = 0.0f; | |
| 962 | + view_ry = 0.0f; | |
| 963 | + Camera_Debugmode = false; | |
| 964 | + Camera_F1mode = false; | |
| 965 | + framecnt = 0; | |
| 966 | + start_framecnt = 0; | |
| 967 | + end_framecnt = 0; | |
| 968 | + message_id = -1; | |
| 969 | + message_cnt = 0; | |
| 970 | + redflash_flag = false; | |
| 971 | + MainGameInfo.missioncomplete = false; | |
| 972 | + MainGameInfo.fire = 0; | |
| 973 | + MainGameInfo.ontarget = 0; | |
| 974 | + MainGameInfo.kill = 0; | |
| 975 | + MainGameInfo.headshot = 0; | |
| 976 | + | |
| 977 | + GameState->NextState(); | |
| 978 | + return 0; | |
| 979 | +} | |
| 980 | + | |
| 981 | +//! 特定操作の入力をチェック | |
| 982 | +bool maingame::CheckInputControl(int CheckKey, int mode) | |
| 983 | +{ | |
| 984 | + int KeyCode = OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)); | |
| 985 | + if( KeyCode == -1 ){ | |
| 986 | + if( mode == 0 ){ | |
| 987 | + return inputCtrl->CheckMouseButtonNowL(); | |
| 988 | + } | |
| 989 | + if( mode == 1 ){ | |
| 990 | + return inputCtrl->CheckMouseButtonDownL(); | |
| 991 | + } | |
| 992 | + //if( mode == 2 ){ | |
| 993 | + return inputCtrl->CheckMouseButtonUpL(); | |
| 994 | + //} | |
| 995 | + } | |
| 996 | + if( KeyCode == -2 ){ | |
| 997 | + if( mode == 0 ){ | |
| 998 | + return inputCtrl->CheckMouseButtonNowR(); | |
| 999 | + } | |
| 1000 | + if( mode == 1 ){ | |
| 1001 | + return inputCtrl->CheckMouseButtonDownR(); | |
| 1002 | + } | |
| 1003 | + //if( mode == 2 ){ | |
| 1004 | + return inputCtrl->CheckMouseButtonUpR(); | |
| 1005 | + //} | |
| 1006 | + } | |
| 1007 | + if( KeyCode == -3 ){ | |
| 1008 | + int CodeL, CodeR; | |
| 1009 | + GetDoubleKeyCode(0, &CodeL, &CodeR); | |
| 1010 | + if( mode == 0 ){ | |
| 1011 | + if( inputCtrl->CheckKeyNow(CodeL) ){ | |
| 1012 | + return true; | |
| 1013 | + } | |
| 1014 | + return inputCtrl->CheckKeyNow(CodeR); | |
| 1015 | + } | |
| 1016 | + if( mode == 1 ){ | |
| 1017 | + if( inputCtrl->CheckKeyDown(CodeL) ){ | |
| 1018 | + return true; | |
| 1019 | + } | |
| 1020 | + return inputCtrl->CheckKeyDown(CodeR); | |
| 1021 | + } | |
| 1022 | + //if( mode == 2 ){ | |
| 1023 | + if( inputCtrl->CheckKeyUp(CodeL) ){ | |
| 1024 | + return true; | |
| 1025 | + } | |
| 1026 | + return inputCtrl->CheckKeyUp(CodeR); | |
| 1027 | + //} | |
| 1028 | + } | |
| 1029 | + if( KeyCode == -4 ){ | |
| 1030 | + int CodeL, CodeR; | |
| 1031 | + GetDoubleKeyCode(1, &CodeL, &CodeR); | |
| 1032 | + if( mode == 0 ){ | |
| 1033 | + if( inputCtrl->CheckKeyNow(CodeL) ){ | |
| 1034 | + return true; | |
| 1035 | + } | |
| 1036 | + return inputCtrl->CheckKeyNow(CodeR); | |
| 1037 | + } | |
| 1038 | + if( mode == 1 ){ | |
| 1039 | + if( inputCtrl->CheckKeyDown(CodeL) ){ | |
| 1040 | + return true; | |
| 1041 | + } | |
| 1042 | + return inputCtrl->CheckKeyDown(CodeR); | |
| 1043 | + } | |
| 1044 | + //if( mode == 2 ){ | |
| 1045 | + if( inputCtrl->CheckKeyUp(CodeL) ){ | |
| 1046 | + return true; | |
| 1047 | + } | |
| 1048 | + return inputCtrl->CheckKeyUp(CodeR); | |
| 1049 | + //} | |
| 1050 | + } | |
| 1051 | + | |
| 1052 | + if( mode == 0 ){ | |
| 1053 | + return inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) ); | |
| 1054 | + } | |
| 1055 | + if( mode == 1 ){ | |
| 1056 | + return inputCtrl->CheckKeyDown( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) ); | |
| 1057 | + } | |
| 1058 | + //if( mode == 2 ){ | |
| 1059 | + return inputCtrl->CheckKeyUp( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) ); | |
| 1060 | + //} | |
| 1061 | +} | |
| 1062 | + | |
| 1063 | +void maingame::Input() | |
| 1064 | +{ | |
| 1065 | + time = GetTimeMS(); | |
| 1066 | + static unsigned int bullettime = 0; | |
| 1067 | + | |
| 1068 | + //プレイヤーのクラスを取得 | |
| 1069 | + human *myHuman = ObjMgr.GetPlayerHumanObject(); | |
| 1070 | + | |
| 1071 | + //キー入力を取得 | |
| 1072 | + inputCtrl->GetInputState(true); | |
| 1073 | + inputCtrl->MoveMouseCenter(); | |
| 1074 | + | |
| 1075 | + //前後左右の移動(走り)操作かチェック | |
| 1076 | + if( CheckInputControl(KEY_MOVEFORWARD, 0) ){ | |
| 1077 | + myHuman->SetMoveForward(); | |
| 1078 | + } | |
| 1079 | + if( CheckInputControl(KEY_MOVEBACKWARD, 0) ){ | |
| 1080 | + myHuman->SetMoveBack(); | |
| 1081 | + } | |
| 1082 | + if( CheckInputControl(KEY_MOVELEFT, 0) ){ | |
| 1083 | + myHuman->SetMoveLeft(); | |
| 1084 | + } | |
| 1085 | + if( CheckInputControl(KEY_MOVERIGHT, 0) ){ | |
| 1086 | + myHuman->SetMoveRight(); | |
| 1087 | + } | |
| 1088 | + | |
| 1089 | + //歩き操作かチェック | |
| 1090 | + if( CheckInputControl(KEY_WALK, 0) ){ | |
| 1091 | + myHuman->SetMoveWalk(); | |
| 1092 | + } | |
| 1093 | + | |
| 1094 | + //ジャンプ操作かチェック | |
| 1095 | + if( CheckInputControl(KEY_JUMP, 1) ){ | |
| 1096 | + myHuman->Jump(); | |
| 1097 | + } | |
| 1098 | + | |
| 1099 | + if( Camera_Debugmode == true ){ //デバックモードならば | |
| 1100 | + //発砲操作かチェック | |
| 1101 | + if( CheckInputControl(KEY_Shot, 0) ){ | |
| 1102 | + //前回の発射より、4フレーム分よりも時間が経っていれば | |
| 1103 | + if( bullettime + 4*((int)GAMEFPS) < GetTimeMS() ){ | |
| 1104 | + float x, y, z, rx, ry; | |
| 1105 | + x = camera_x; | |
| 1106 | + y = camera_y; | |
| 1107 | + z = camera_z; | |
| 1108 | + rx = camera_rx; | |
| 1109 | + ry = camera_ry; | |
| 1110 | + | |
| 1111 | + //未使用の弾オブジェクトを取得 | |
| 1112 | + bullet* newbullet = ObjMgr.GetNewBulletObject(); | |
| 1113 | + if( newbullet != NULL ){ | |
| 1114 | + //弾オブジェクトを設定 | |
| 1115 | + newbullet->SetPosData(x, y, z, rx, ry); | |
| 1116 | + newbullet->SetParamData(40, 5, 10, 1024, ObjMgr.GetPlayerID(), true); | |
| 1117 | + newbullet->SetDrawFlag(true); | |
| 1118 | + GameSound->ShotWeapon(x, y, z, 0, 1024, true); | |
| 1119 | + | |
| 1120 | + //スコアに加算 | |
| 1121 | + MainGameInfo.fire += 1; | |
| 1122 | + | |
| 1123 | + //発射時間を記憶(連射間隔判定用) | |
| 1124 | + bullettime = GetTimeMS(); | |
| 1125 | + } | |
| 1126 | + } | |
| 1127 | + } | |
| 1128 | + } | |
| 1129 | + else{ //デバックモードでなければ | |
| 1130 | + HumanParameter humandata; | |
| 1131 | + int id_param; | |
| 1132 | + bool zombie; | |
| 1133 | + int keymode; | |
| 1134 | + | |
| 1135 | + //ゾンビかどうか判定 | |
| 1136 | + myHuman->GetParamData(&id_param, NULL, NULL, NULL); | |
| 1137 | + GameParamInfo.GetHuman(id_param, &humandata); | |
| 1138 | + if( humandata.type == 2 ){ | |
| 1139 | + zombie = true; | |
| 1140 | + } | |
| 1141 | + else{ | |
| 1142 | + zombie = false; | |
| 1143 | + } | |
| 1144 | + | |
| 1145 | + //連射モードを取得 | |
| 1146 | + if( zombie == true ){ | |
| 1147 | + keymode = 1; | |
| 1148 | + } | |
| 1149 | + else if( myHuman->GetWeaponBlazingmode() == false ){ | |
| 1150 | + keymode = 1; | |
| 1151 | + } | |
| 1152 | + else{ | |
| 1153 | + keymode = 0; | |
| 1154 | + } | |
| 1155 | + | |
| 1156 | + //発砲操作かチェック | |
| 1157 | + if( CheckInputControl(KEY_Shot, keymode) ){ | |
| 1158 | + | |
| 1159 | + if( zombie == false ){ | |
| 1160 | + //弾の発射に成功すれば | |
| 1161 | + if( ObjMgr.ShotWeapon(myHuman) == 1 ){ | |
| 1162 | + //スコアに加算 | |
| 1163 | + MainGameInfo.fire += 1; | |
| 1164 | + | |
| 1165 | + //プレイヤーの向きを取得 | |
| 1166 | + ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry); | |
| 1167 | + } | |
| 1168 | + } | |
| 1169 | + else{ | |
| 1170 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1171 | + human *EnemyHuman = ObjMgr.GeHumanObject(i); | |
| 1172 | + if( ObjMgr.CheckZombieAttack(myHuman, EnemyHuman) == true ){ | |
| 1173 | + ObjMgr.HitZombieAttack(EnemyHuman); | |
| 1174 | + } | |
| 1175 | + } | |
| 1176 | + } | |
| 1177 | + | |
| 1178 | + } | |
| 1179 | + } | |
| 1180 | + | |
| 1181 | + //リロード操作かチェック | |
| 1182 | + if( CheckInputControl(KEY_RELOAD, 1) ){ | |
| 1183 | + ObjMgr.ReloadWeapon(myHuman); | |
| 1184 | + } | |
| 1185 | + | |
| 1186 | + //武器の切り替え操作かチェック | |
| 1187 | + if( CheckInputControl(KEY_SWITCHWEAPON, 1) ){ | |
| 1188 | + myHuman->ChangeWeapon(-1); | |
| 1189 | + } | |
| 1190 | + if( CheckInputControl(KEY_WEAPON1, 1) ){ | |
| 1191 | + myHuman->ChangeWeapon(0); | |
| 1192 | + } | |
| 1193 | + if( CheckInputControl(KEY_WEAPON2, 1) ){ | |
| 1194 | + myHuman->ChangeWeapon(1); | |
| 1195 | + } | |
| 1196 | + | |
| 1197 | + //武器の廃棄操作かチェック | |
| 1198 | + if( CheckInputControl(KEY_DROPWEAPON, 1) ){ | |
| 1199 | + myHuman->DumpWeapon(); | |
| 1200 | + } | |
| 1201 | + | |
| 1202 | + //スコープ操作かチェック | |
| 1203 | + if( CheckInputControl(KEY_ZOOM, 1) ){ | |
| 1204 | + if( myHuman->GetScopeMode() == 0 ){ //スコープを使用していなければ、スコープを設定 | |
| 1205 | + myHuman->SetEnableScope(); | |
| 1206 | + } | |
| 1207 | + else{ //使用中なら、解除 | |
| 1208 | + myHuman->SetDisableScope(); | |
| 1209 | + } | |
| 1210 | + } | |
| 1211 | + | |
| 1212 | + //連射モード変更操作かチェック | |
| 1213 | + if( CheckInputControl(KEY_ShotMODE, 1) ){ | |
| 1214 | + myHuman->ChangeShotMode(); | |
| 1215 | + } | |
| 1216 | + | |
| 1217 | + //ゲーム終了操作かチェック | |
| 1218 | + if( inputCtrl->CheckKeyDown(GetEscKeycode()) ){ | |
| 1219 | + GameState->PushBackSpaceKey(); | |
| 1220 | + } | |
| 1221 | + | |
| 1222 | + //カメラ表示モード変更操作かチェック | |
| 1223 | + if( inputCtrl->CheckKeyDown( GetFunctionKeycode(1) ) ){ | |
| 1224 | + if( Camera_F1mode == false ){ | |
| 1225 | + Camera_F1mode = true; | |
| 1226 | + view_rx = 0.0f; | |
| 1227 | + view_ry = (float)M_PI/8 * -1; | |
| 1228 | + } | |
| 1229 | + else{ | |
| 1230 | + Camera_F1mode = false; | |
| 1231 | + view_rx = 0.0f; | |
| 1232 | + view_ry = 0.0f; | |
| 1233 | + } | |
| 1234 | + } | |
| 1235 | + | |
| 1236 | + //カメラ操作 | |
| 1237 | + if( Camera_F1mode == true ){ | |
| 1238 | + if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x0C) ) ){ //NUM8 | |
| 1239 | + view_ry -= (float)M_PI/180 * 2; | |
| 1240 | + } | |
| 1241 | + if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x09) ) ){ //NUM5 | |
| 1242 | + view_ry += (float)M_PI/180 * 2; | |
| 1243 | + } | |
| 1244 | + if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x08) ) ){ //NUM4 | |
| 1245 | + view_rx -= (float)M_PI/180 * 2; | |
| 1246 | + } | |
| 1247 | + if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x0A) ) ){ //NUM6 | |
| 1248 | + view_rx += (float)M_PI/180 * 2; | |
| 1249 | + } | |
| 1250 | + } | |
| 1251 | + | |
| 1252 | + //画面のUI変更操作かチェック | |
| 1253 | + if( inputCtrl->CheckKeyDown( GetFunctionKeycode(2) ) ){ | |
| 1254 | + if( Camera_F2mode == 2 ){ | |
| 1255 | + Camera_F2mode = 0; | |
| 1256 | + } | |
| 1257 | + else{ | |
| 1258 | + Camera_F2mode += 1; | |
| 1259 | + } | |
| 1260 | + } | |
| 1261 | + | |
| 1262 | + //リセット操作かチェック | |
| 1263 | + if( inputCtrl->CheckKeyDown( GetFunctionKeycode(12) ) ){ | |
| 1264 | + GameState->PushF12Key(); | |
| 1265 | + } | |
| 1266 | + | |
| 1267 | + //裏技・上昇の操作かチェック | |
| 1268 | + if( inputCtrl->CheckKeyNow( GetFunctionKeycode(5) ) ){ | |
| 1269 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x0F)) ){ // [ENTER] | |
| 1270 | + Cmd_F5 = true; | |
| 1271 | + } | |
| 1272 | + else{ | |
| 1273 | + Cmd_F5 = false; | |
| 1274 | + } | |
| 1275 | + } | |
| 1276 | + else{ | |
| 1277 | + Cmd_F5 = false; | |
| 1278 | + } | |
| 1279 | + | |
| 1280 | + //裏技・弾追加の操作かチェック | |
| 1281 | + if( inputCtrl->CheckKeyNow( GetFunctionKeycode(6) ) ){ | |
| 1282 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x0F)) ){ // [ENTER] | |
| 1283 | + int selectweapon; | |
| 1284 | + weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1285 | + int id_param, lnbs, nbs; | |
| 1286 | + WeaponParameter ParamData; | |
| 1287 | + | |
| 1288 | + //所持している武器を取得 | |
| 1289 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1290 | + weapon[i] = NULL; | |
| 1291 | + } | |
| 1292 | + myHuman->GetWeapon(&selectweapon, weapon); | |
| 1293 | + | |
| 1294 | + //何かしらの武器を持っていれば | |
| 1295 | + if( weapon[selectweapon] != NULL ){ | |
| 1296 | + //武器の種類と弾数、武器の設定値を取得 | |
| 1297 | + weapon[selectweapon]->GetParamData(&id_param, &lnbs, &nbs); | |
| 1298 | + if( GameParamInfo.GetWeapon(id_param, &ParamData) == 0 ){ | |
| 1299 | + //最大弾数分加算し、適用 | |
| 1300 | + nbs += ParamData.nbsmax; | |
| 1301 | + weapon[selectweapon]->ResetWeaponParam(&Resource, id_param, lnbs, nbs); | |
| 1302 | + } | |
| 1303 | + } | |
| 1304 | + } | |
| 1305 | + } | |
| 1306 | + | |
| 1307 | + //裏技・武器変更の操作かチェック | |
| 1308 | + if( inputCtrl->CheckKeyNow( GetFunctionKeycode(7) ) ){ | |
| 1309 | + if( (inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)))||(inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03))) ){ // [←]・[→] | |
| 1310 | + HumanParameter humandata; | |
| 1311 | + int selectweapon; | |
| 1312 | + weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1313 | + int id_param, lnbs, nbs; | |
| 1314 | + | |
| 1315 | + //ゾンビかどうか判定 | |
| 1316 | + myHuman->GetParamData(&id_param, NULL, NULL, NULL); | |
| 1317 | + GameParamInfo.GetHuman(id_param, &humandata); | |
| 1318 | + if( humandata.type != 2 ){ | |
| 1319 | + | |
| 1320 | + //所持している武器を取得 | |
| 1321 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1322 | + weapon[i] = NULL; | |
| 1323 | + } | |
| 1324 | + myHuman->GetWeapon(&selectweapon, weapon); | |
| 1325 | + | |
| 1326 | + if( weapon[selectweapon] == NULL ){ //武器を所有していなければ | |
| 1327 | + int dataid = -1; | |
| 1328 | + | |
| 1329 | + //新しい武器を配置 | |
| 1330 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)) ){ // [←] | |
| 1331 | + dataid = ObjMgr.AddVisualWeaponIndex(1, false); | |
| 1332 | + } | |
| 1333 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03)) ){ // [→] | |
| 1334 | + dataid = ObjMgr.AddVisualWeaponIndex(TOTAL_PARAMETERINFO_WEAPON-1, false); | |
| 1335 | + } | |
| 1336 | + | |
| 1337 | + //武器が配置できれば、武器を拾わせる | |
| 1338 | + if( dataid != -1 ){ | |
| 1339 | + myHuman->PickupWeapon( ObjMgr.GeWeaponObject(dataid) ); | |
| 1340 | + } | |
| 1341 | + } | |
| 1342 | + else{ //武器を所有していれば | |
| 1343 | + //武器設定を取得 | |
| 1344 | + weapon[selectweapon]->GetParamData(&id_param, &lnbs, &nbs); | |
| 1345 | + | |
| 1346 | + //次の武器番号を計算 | |
| 1347 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)) ){ // [←] | |
| 1348 | + if( id_param >= TOTAL_PARAMETERINFO_WEAPON-1 ){ id_param = 0; } | |
| 1349 | + else{ id_param += 1; } | |
| 1350 | + } | |
| 1351 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03)) ){ // [→] | |
| 1352 | + if( id_param <= 0 ){ id_param = TOTAL_PARAMETERINFO_WEAPON-1; } | |
| 1353 | + else{ id_param -= 1; } | |
| 1354 | + } | |
| 1355 | + | |
| 1356 | + if( id_param == ID_WEAPON_NONE ){ | |
| 1357 | + if( myHuman->DumpWeapon() == true ){ | |
| 1358 | + weapon[selectweapon]->SetDrawFlag(false); | |
| 1359 | + } | |
| 1360 | + } | |
| 1361 | + else{ | |
| 1362 | + //武器設定を適用 | |
| 1363 | + weapon[selectweapon]->ResetWeaponParam(&Resource, id_param, lnbs, nbs); | |
| 1364 | + } | |
| 1365 | + } | |
| 1366 | + } | |
| 1367 | + } | |
| 1368 | + } | |
| 1369 | + | |
| 1370 | + //裏技・人変更の操作かチェック | |
| 1371 | + if( inputCtrl->CheckKeyNow( GetFunctionKeycode(8) ) ){ | |
| 1372 | + int Player_HumanID; | |
| 1373 | + | |
| 1374 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)) ){ // [←] | |
| 1375 | + //現在のプレイヤー番号を取得 | |
| 1376 | + Player_HumanID = ObjMgr.GetPlayerID(); | |
| 1377 | + | |
| 1378 | + //次の人を計算 | |
| 1379 | + Player_HumanID += 1; | |
| 1380 | + if( Player_HumanID >= MAX_HUMAN ){ Player_HumanID = 0; } | |
| 1381 | + | |
| 1382 | + //対象プレイヤー番号を適用 | |
| 1383 | + ObjMgr.SetPlayerID(Player_HumanID); | |
| 1384 | + | |
| 1385 | + //プレイヤーの向きを取得 | |
| 1386 | + ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry); | |
| 1387 | + } | |
| 1388 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03)) ){ // [→] | |
| 1389 | + //現在のプレイヤー番号を取得 | |
| 1390 | + Player_HumanID = ObjMgr.GetPlayerID(); | |
| 1391 | + | |
| 1392 | + //次の人を計算 | |
| 1393 | + Player_HumanID -= 1; | |
| 1394 | + if( Player_HumanID < 0 ){ Player_HumanID = MAX_HUMAN-1; } | |
| 1395 | + | |
| 1396 | + //対象プレイヤー番号を適用 | |
| 1397 | + ObjMgr.SetPlayerID(Player_HumanID); | |
| 1398 | + | |
| 1399 | + //プレイヤーの向きを取得 | |
| 1400 | + ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry); | |
| 1401 | + } | |
| 1402 | + } | |
| 1403 | + | |
| 1404 | + //裏技・人追加の操作かチェック | |
| 1405 | + if( inputCtrl->CheckKeyNow( GetFunctionKeycode(9) ) ){ | |
| 1406 | + if( (inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x00)))||(inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x01))) ){ // [↑]・[↓] | |
| 1407 | + float x, y, z, r; | |
| 1408 | + int param, dataid, team; | |
| 1409 | + int selectweapon; | |
| 1410 | + weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1411 | + int weapon_paramid[TOTAL_HAVEWEAPON]; | |
| 1412 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1413 | + weapon[i] = NULL; | |
| 1414 | + weapon_paramid[i] = 0; | |
| 1415 | + } | |
| 1416 | + int id; | |
| 1417 | + | |
| 1418 | + //プレイヤーの座標や武器を取得 | |
| 1419 | + myHuman->GetPosData(&x, &y, &z, &r); | |
| 1420 | + myHuman->GetParamData(¶m, &dataid, NULL, &team); | |
| 1421 | + myHuman->GetWeapon(&selectweapon, weapon); | |
| 1422 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1423 | + if( weapon[i] != NULL ){ | |
| 1424 | + weapon[i]->GetParamData(&weapon_paramid[i], NULL, NULL); | |
| 1425 | + } | |
| 1426 | + } | |
| 1427 | + | |
| 1428 | + //プレイヤーの目の前の座標を取得 | |
| 1429 | + x += cos(r*-1 + (float)M_PI/2)*10.0f; | |
| 1430 | + y += 5.0f; | |
| 1431 | + z += sin(r*-1 + (float)M_PI/2)*10.0f; | |
| 1432 | + | |
| 1433 | + //人を追加 | |
| 1434 | + id = ObjMgr.AddHumanIndex(x, y, z, r, param, team, weapon_paramid); | |
| 1435 | + if( id >= 0 ){ | |
| 1436 | + ObjMgr.GeHumanObject(id)->ChangeWeapon(selectweapon); | |
| 1437 | + | |
| 1438 | + //AIを設定 | |
| 1439 | + HumanAI[id].Init(); | |
| 1440 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x00)) ){ // [↑] | |
| 1441 | + HumanAI[id].SetHoldTracking(dataid); | |
| 1442 | + } | |
| 1443 | + if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x01)) ){ // [↓] | |
| 1444 | + HumanAI[id].SetHoldWait(x, z, r); | |
| 1445 | + } | |
| 1446 | + } | |
| 1447 | + } | |
| 1448 | + } | |
| 1449 | + | |
| 1450 | + //裏技・腕表示の操作かチェック | |
| 1451 | + if( inputCtrl->CheckKeyDown( GetHomeKeycode() ) ){ | |
| 1452 | + if( Camera_HOMEmode == false ){ | |
| 1453 | + Camera_HOMEmode = true; | |
| 1454 | + } | |
| 1455 | + else{ | |
| 1456 | + Camera_HOMEmode = false; | |
| 1457 | + } | |
| 1458 | + } | |
| 1459 | + | |
| 1460 | + //デバックモード使用操作かチェック | |
| 1461 | +#ifdef _DEBUG | |
| 1462 | + if( inputCtrl->CheckKeyDown( GetFunctionKeycode(4) ) ){ | |
| 1463 | +#else | |
| 1464 | + if( 0 ){ | |
| 1465 | +#endif | |
| 1466 | + if( Camera_Debugmode == false ){ | |
| 1467 | + Camera_Debugmode = true; | |
| 1468 | + } | |
| 1469 | + else{ | |
| 1470 | + Camera_Debugmode = false; | |
| 1471 | + } | |
| 1472 | + | |
| 1473 | + //デバックモード開始時のカメラ設定 | |
| 1474 | + if( Camera_Debugmode == true ){ | |
| 1475 | + camera_x = 100.0f; | |
| 1476 | + camera_y = 100.0f; | |
| 1477 | + camera_z = -100.0f; | |
| 1478 | + camera_rx = (float)M_PI/180*135; | |
| 1479 | + camera_ry = (float)M_PI/180*(-40); | |
| 1480 | + } | |
| 1481 | + } | |
| 1482 | + | |
| 1483 | + //ゲーム実行情報の表示操作かチェック | |
| 1484 | + if( inputCtrl->CheckKeyDown( GetFunctionKeycode(11) ) ){ | |
| 1485 | + if( ShowInfo_Debugmode == false ){ | |
| 1486 | + ShowInfo_Debugmode = true; | |
| 1487 | + } | |
| 1488 | + else{ | |
| 1489 | + ShowInfo_Debugmode = false; | |
| 1490 | + } | |
| 1491 | + } | |
| 1492 | + | |
| 1493 | + //マウスの移動量取得 | |
| 1494 | + int x, y; | |
| 1495 | + float MouseSensitivity; | |
| 1496 | + inputCtrl->GetMouseMovement(&x, &y); | |
| 1497 | + | |
| 1498 | + //視点の移動量計算 | |
| 1499 | + float mang; | |
| 1500 | + if( myHuman->GetScopeMode() == 0 ){ mang = 0.01f; } | |
| 1501 | + if( myHuman->GetScopeMode() == 1 ){ mang = 0.0032f; } | |
| 1502 | + if( myHuman->GetScopeMode() == 2 ){ mang = 0.0060f; } | |
| 1503 | + MouseSensitivity = (float)M_PI/180 * mang * GameConfig.GetMouseSensitivity(); | |
| 1504 | + | |
| 1505 | + //マウス反転(オプション設定)が有効ならば、反転する。 | |
| 1506 | + if( GameConfig.GetInvertMouseFlag() == true ){ | |
| 1507 | + y *= -1; | |
| 1508 | + } | |
| 1509 | + | |
| 1510 | + if( Camera_Debugmode == false ){ //通常モードならば | |
| 1511 | + if( myHuman->GetHP() > 0 ){ | |
| 1512 | + //マウスによる向きを計算 | |
| 1513 | + mouse_rx += x * MouseSensitivity; | |
| 1514 | + mouse_ry -= y * MouseSensitivity; | |
| 1515 | + | |
| 1516 | + //キー操作による向きを計算 | |
| 1517 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x00)) ){ mouse_ry += (float)M_PI/180 * 3; } // [↑] | |
| 1518 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x01)) ){ mouse_ry -= (float)M_PI/180 * 3; } // [↓] | |
| 1519 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x02)) ){ mouse_rx -= (float)M_PI/180 * 3; } // [←] | |
| 1520 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x03)) ){ mouse_rx += (float)M_PI/180 * 3; } // [→] | |
| 1521 | + | |
| 1522 | + if( mouse_ry > (float)M_PI/3 ) mouse_ry = (float)M_PI/3; | |
| 1523 | + if( mouse_ry < (float)M_PI/3 *-1 ) mouse_ry = (float)M_PI/3 *-1; | |
| 1524 | + } | |
| 1525 | + } | |
| 1526 | + else{ //デバックモードならば | |
| 1527 | + //キー操作によりカメラ座標を計算 | |
| 1528 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x00)) ){ camera_x += 2.0f; } // [↑] | |
| 1529 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x01)) ){ camera_x -= 2.0f; } // [↓] | |
| 1530 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x02)) ){ camera_z += 2.0f; } // [←] | |
| 1531 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x03)) ){ camera_z -= 2.0f; } // [→] | |
| 1532 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x48)) ){ camera_y += 2.0f; } //[NUM +] | |
| 1533 | + if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x49)) ){ camera_y -= 2.0f; } //[NUM -] | |
| 1534 | + | |
| 1535 | + //マウス移動をカメラの向きとして適用 | |
| 1536 | + //camera_rx -= x*0.0025f; | |
| 1537 | + //camera_ry -= y*0.0025f; | |
| 1538 | + camera_rx -= x * MouseSensitivity; | |
| 1539 | + camera_ry -= y * MouseSensitivity; | |
| 1540 | + if( camera_ry > (float)M_PI/3 ) camera_ry = (float)M_PI/3; | |
| 1541 | + if( camera_ry < (float)M_PI/3 *-1 ) camera_ry = (float)M_PI/3 *-1; | |
| 1542 | + } | |
| 1543 | + | |
| 1544 | + time_input = GetTimeMS() - time; | |
| 1545 | +} | |
| 1546 | + | |
| 1547 | +void maingame::Process() | |
| 1548 | +{ | |
| 1549 | + //プレイヤーのクラスを取得 | |
| 1550 | + human *myHuman = ObjMgr.GetPlayerHumanObject(); | |
| 1551 | + | |
| 1552 | + int ontarget, kill, headshot; | |
| 1553 | + | |
| 1554 | + //----------------------------------- | |
| 1555 | + | |
| 1556 | + time = GetTimeMS(); | |
| 1557 | + | |
| 1558 | + //武器の持ち方を取得 | |
| 1559 | + int weaponid; | |
| 1560 | + WeaponParameter data; | |
| 1561 | + weaponid = myHuman->GetMainWeaponTypeNO(); | |
| 1562 | + GameParamInfo.GetWeapon(weaponid, &data); | |
| 1563 | + | |
| 1564 | + //プレイヤー(オブジェクト)の向きを設定 | |
| 1565 | + if( data.WeaponP == 2 ){ | |
| 1566 | + myHuman->SetRxRy(mouse_rx, ARMRAD_NOWEAPON); | |
| 1567 | + } | |
| 1568 | + else{ | |
| 1569 | + myHuman->SetRxRy(mouse_rx, mouse_ry); | |
| 1570 | + } | |
| 1571 | + | |
| 1572 | + //オブジェクトマネージャーを実行 | |
| 1573 | + if( Cmd_F5 == true ){ | |
| 1574 | + ObjMgr.Process( ObjMgr.GetPlayerID() , camera_x, camera_y, camera_z, camera_rx, camera_ry); | |
| 1575 | + } | |
| 1576 | + else{ | |
| 1577 | + ObjMgr.Process(-1, camera_x, camera_y, camera_z, camera_rx, camera_ry); | |
| 1578 | + } | |
| 1579 | + | |
| 1580 | + //プレイヤーの戦歴を加算 | |
| 1581 | + ObjMgr.GetHumanShotInfo( ObjMgr.GetPlayerID(), &ontarget, &kill, &headshot); | |
| 1582 | + MainGameInfo.ontarget += ontarget; | |
| 1583 | + MainGameInfo.kill += kill; | |
| 1584 | + MainGameInfo.headshot += headshot; | |
| 1585 | + | |
| 1586 | + time_process_object = GetTimeMS() - time; | |
| 1587 | + | |
| 1588 | + //----------------------------------- | |
| 1589 | + | |
| 1590 | + time = GetTimeMS(); | |
| 1591 | + int PlayerID = ObjMgr.GetPlayerID(); | |
| 1592 | + for(int i=0; i<MAX_HUMAN; i++){ | |
| 1593 | + if( i != PlayerID ){ | |
| 1594 | + //AIを実行 | |
| 1595 | + HumanAI[i].Process(); | |
| 1596 | + } | |
| 1597 | + } | |
| 1598 | + time_process_ai = GetTimeMS() - time; | |
| 1599 | + | |
| 1600 | + //----------------------------------- | |
| 1601 | + | |
| 1602 | + //ミッションが終了していなければ、 | |
| 1603 | + if( end_framecnt == 0 ){ | |
| 1604 | + int check = ObjMgr.CheckGameOverorComplete(); | |
| 1605 | + | |
| 1606 | + //ゲームクリアー判定 | |
| 1607 | + if( check == 1 ){ | |
| 1608 | + end_framecnt += 1; | |
| 1609 | + MainGameInfo.missioncomplete = true; | |
| 1610 | + } | |
| 1611 | + | |
| 1612 | + //ゲームオーバー判定 | |
| 1613 | + if( check == 2 ){ | |
| 1614 | + end_framecnt += 1; | |
| 1615 | + MainGameInfo.missioncomplete = false; | |
| 1616 | + } | |
| 1617 | + } | |
| 1618 | + | |
| 1619 | + //----------------------------------- | |
| 1620 | + | |
| 1621 | + time = GetTimeMS(); | |
| 1622 | + bool SetMessageID; | |
| 1623 | + if( end_framecnt == 0 ){ | |
| 1624 | + //イベント実行 | |
| 1625 | + for(int i=0; i<TOTAL_EVENTLINE; i++){ | |
| 1626 | + SetMessageID = false; | |
| 1627 | + Event[i].Execution(&end_framecnt, &MainGameInfo.missioncomplete, &message_id, &SetMessageID); | |
| 1628 | + | |
| 1629 | + //イベントメッセージが再セットされていたら、カウントを戻す。 | |
| 1630 | + if( SetMessageID == true ){ | |
| 1631 | + message_cnt = 0; | |
| 1632 | + } | |
| 1633 | + } | |
| 1634 | + } | |
| 1635 | + if( (message_id != -1)&&(message_cnt < TOTAL_EVENTENT_SHOWMESCNT) ){ | |
| 1636 | + message_cnt += 1; | |
| 1637 | + } | |
| 1638 | + else{ | |
| 1639 | + message_id = -1; | |
| 1640 | + message_cnt = 0; | |
| 1641 | + } | |
| 1642 | + time_process_event = GetTimeMS() - time; | |
| 1643 | + | |
| 1644 | + //----------------------------------- | |
| 1645 | + | |
| 1646 | + float x, y, z; | |
| 1647 | + myHuman->GetPosData(&x, &y, &z, NULL); | |
| 1648 | + | |
| 1649 | + //カメラワークを求める | |
| 1650 | + if( Camera_Debugmode == true ){ | |
| 1651 | + // | |
| 1652 | + } | |
| 1653 | + else if( myHuman->GetHP() <= 0 ){ | |
| 1654 | + float rx = (float)M_PI/180*end_framecnt; | |
| 1655 | + float ry = (float)M_PI/180*85*-1; | |
| 1656 | + float r = 25.0f; | |
| 1657 | + | |
| 1658 | + camera_x = x + cos(rx)*cos(ry)*r; | |
| 1659 | + camera_y = y - sin(ry)*r; | |
| 1660 | + camera_z = z + sin(rx)*cos(ry)*r; | |
| 1661 | + camera_rx = rx; | |
| 1662 | + camera_ry = ry; | |
| 1663 | + } | |
| 1664 | + else if( Camera_F1mode == true ){ | |
| 1665 | + float crx = view_rx + mouse_rx*-1 + (float)M_PI/2; | |
| 1666 | + float cry = view_ry + mouse_ry; | |
| 1667 | + float dist; | |
| 1668 | + if( CollD.CheckALLBlockIntersectRay(x, y + HUMAN_HEIGTH, z, cos(crx)*cos(cry)*-1, sin(cry*-1), sin(crx)*cos(cry)*-1, NULL, NULL, &dist, 13.0f) == true ){ | |
| 1669 | + dist -= 1.0f; | |
| 1670 | + } | |
| 1671 | + else{ | |
| 1672 | + dist = 13.0f; | |
| 1673 | + } | |
| 1674 | + camera_x = x - cos(crx)*cos(cry)*dist; | |
| 1675 | + camera_y = y + HUMAN_HEIGTH + sin(cry*-1)*dist; | |
| 1676 | + camera_z = z - sin(crx)*cos(cry)*dist; | |
| 1677 | + camera_rx = crx; | |
| 1678 | + camera_ry = cry; | |
| 1679 | + } | |
| 1680 | + else{ | |
| 1681 | + camera_x = x; | |
| 1682 | + camera_y = y + VIEW_HEIGHT; | |
| 1683 | + camera_z = z; | |
| 1684 | + camera_rx = view_rx + mouse_rx*-1 + (float)M_PI/2; | |
| 1685 | + camera_ry = view_ry + mouse_ry; | |
| 1686 | + } | |
| 1687 | + | |
| 1688 | + //ダメージを受けていれば、レッドフラッシュを描画する | |
| 1689 | + redflash_flag = myHuman->CheckHit(); | |
| 1690 | + | |
| 1691 | + framecnt += 1; | |
| 1692 | + if( start_framecnt < 1*((int)GAMEFPS) ){ //ミッション開始中なら | |
| 1693 | + start_framecnt += 1; | |
| 1694 | + } | |
| 1695 | + if( end_framecnt == 1 ){ //ミッション終了直後ならば | |
| 1696 | + MainGameInfo.framecnt = framecnt; | |
| 1697 | + GameInfoData = MainGameInfo; | |
| 1698 | + end_framecnt += 1; | |
| 1699 | + } | |
| 1700 | + else if( end_framecnt > 0 ){ //ミッション終了中ならば | |
| 1701 | + if( end_framecnt < 5*((int)GAMEFPS) ){ | |
| 1702 | + end_framecnt += 1; | |
| 1703 | + } | |
| 1704 | + else{ | |
| 1705 | + GameState->PushMouseButton(); | |
| 1706 | + } | |
| 1707 | + } | |
| 1708 | +} | |
| 1709 | + | |
| 1710 | +void maingame::Sound() | |
| 1711 | +{ | |
| 1712 | + time = GetTimeMS(); | |
| 1713 | + | |
| 1714 | + //サウンドを再生 | |
| 1715 | + GameSound->PlayWorldSound(camera_x, camera_y, camera_z, camera_rx); | |
| 1716 | + | |
| 1717 | + time_sound = GetTimeMS() - time; | |
| 1718 | +} | |
| 1719 | + | |
| 1720 | +void maingame::Render3D() | |
| 1721 | +{ | |
| 1722 | + time = GetTimeMS(); | |
| 1723 | + | |
| 1724 | + | |
| 1725 | + int skymodel, skytexture; | |
| 1726 | + human *myHuman = ObjMgr.GetPlayerHumanObject(); | |
| 1727 | + | |
| 1728 | + //フォグとカメラを設定 | |
| 1729 | + d3dg->SetFog(MIFdata.GetSkynumber()); | |
| 1730 | + if( Camera_F1mode == false ){ | |
| 1731 | + int scopemode = myHuman->GetScopeMode(); | |
| 1732 | + float viewangle; | |
| 1733 | + | |
| 1734 | + //スコープによる視野角を決定 | |
| 1735 | + if( scopemode == 0 ){ viewangle = VIEWANGLE_NORMAL; } | |
| 1736 | + if( scopemode == 1 ){ viewangle = VIEWANGLE_SCOPE_1; } | |
| 1737 | + if( scopemode == 2 ){ viewangle = VIEWANGLE_SCOPE_2; } | |
| 1738 | + | |
| 1739 | + d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, viewangle); | |
| 1740 | + } | |
| 1741 | + else{ | |
| 1742 | + d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL); | |
| 1743 | + } | |
| 1744 | + | |
| 1745 | + //カメラ座標に背景空を描画 | |
| 1746 | + d3dg->SetWorldTransform(camera_x, camera_y, camera_z, 0.0f, 0.0f, 1.0f); | |
| 1747 | + Resource.GetSkyModelTexture(&skymodel, &skytexture); | |
| 1748 | + d3dg->RenderModel(skymodel, skytexture); | |
| 1749 | + | |
| 1750 | + //Zバッファを初期化 | |
| 1751 | + d3dg->ResetZbuffer(); | |
| 1752 | + | |
| 1753 | + //中心線描画(デバック用) | |
| 1754 | + //d3dg->Centerline(); | |
| 1755 | + | |
| 1756 | + //マップを描画 | |
| 1757 | + d3dg->ResetWorldTransform(); | |
| 1758 | + d3dg->DrawMapdata(); | |
| 1759 | + | |
| 1760 | + //プレイヤーの描画有無の決定 | |
| 1761 | + int DrawPlayer = 0; | |
| 1762 | + if( (Camera_F1mode == false)&&(Camera_Debugmode == false)&&(myHuman->GetHP() > 0) ){ | |
| 1763 | + if( Camera_HOMEmode == false ){ | |
| 1764 | + DrawPlayer = 1; | |
| 1765 | + } | |
| 1766 | + else{ | |
| 1767 | + DrawPlayer = 2; | |
| 1768 | + } | |
| 1769 | + } | |
| 1770 | + //オブジェクトを描画 | |
| 1771 | + ObjMgr.Render(camera_x, camera_y, camera_z, DrawPlayer); | |
| 1772 | +} | |
| 1773 | + | |
| 1774 | +void maingame::Render2D() | |
| 1775 | +{ | |
| 1776 | + char str[256]; | |
| 1777 | + float fps = GetFps(10); | |
| 1778 | + float effect; | |
| 1779 | + | |
| 1780 | + human *myHuman = ObjMgr.GetPlayerHumanObject(); | |
| 1781 | + | |
| 1782 | + int selectweapon; | |
| 1783 | + weapon *weapon[TOTAL_HAVEWEAPON]; | |
| 1784 | + int weapon_paramid[TOTAL_HAVEWEAPON]; | |
| 1785 | + WeaponParameter weapon_paramdata; | |
| 1786 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1787 | + weapon[i] = NULL; | |
| 1788 | + weapon_paramid[i] = 0; | |
| 1789 | + } | |
| 1790 | + int lnbs = 0; | |
| 1791 | + int nbs = 0; | |
| 1792 | + int reloadcnt = 0; | |
| 1793 | + int selectweaponcnt = 0; | |
| 1794 | + int weaponmodel, weapontexture; | |
| 1795 | + char weaponname[16]; | |
| 1796 | + int hp; | |
| 1797 | + int param_scopemode; | |
| 1798 | + int ErrorRange; | |
| 1799 | + | |
| 1800 | + //各種設定やゲーム情報を取得 | |
| 1801 | + myHuman->GetWeapon(&selectweapon, weapon); | |
| 1802 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 1803 | + if( weapon[i] != NULL ){ | |
| 1804 | + if( selectweapon == i ){ | |
| 1805 | + weapon[i]->GetParamData(&weapon_paramid[i], &lnbs, &nbs); | |
| 1806 | + reloadcnt = weapon[i]->GetReloadCnt(); | |
| 1807 | + } | |
| 1808 | + else{ | |
| 1809 | + weapon[i]->GetParamData(&weapon_paramid[i], NULL, NULL); | |
| 1810 | + } | |
| 1811 | + } | |
| 1812 | + } | |
| 1813 | + selectweaponcnt = myHuman->GetChangeWeaponCnt(); | |
| 1814 | + WeaponParameter param; | |
| 1815 | + GameParamInfo.GetWeapon(weapon_paramid[selectweapon], ¶m); | |
| 1816 | + strcpy(weaponname, param.name); | |
| 1817 | + hp = myHuman->GetHP(); | |
| 1818 | + param_scopemode = param.scopemode; | |
| 1819 | + ErrorRange = myHuman->GetGunsightErrorRange(); | |
| 1820 | + | |
| 1821 | + float human_x, human_y, human_z, human_rx; | |
| 1822 | + myHuman->GetPosData(&human_x, &human_y, &human_z, &human_rx); | |
| 1823 | + | |
| 1824 | + //レッドフラッシュ描画 | |
| 1825 | + if( redflash_flag == true ){ | |
| 1826 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 1827 | + redflash_flag = false; | |
| 1828 | + } | |
| 1829 | + | |
| 1830 | + //スコープ表示 | |
| 1831 | + if( (Camera_F1mode == false)&&(myHuman->GetScopeMode() == 1) ){ | |
| 1832 | + d3dg->Draw2DTexture(0, 0, Resource.GetScopeTexture(), SCREEN_WIDTH, SCREEN_HEIGTH, 1.0f); | |
| 1833 | + d3dg->Draw2DLine(SCREEN_WIDTH/2-49, SCREEN_HEIGTH/2, SCREEN_WIDTH/2-4, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1834 | + d3dg->Draw2DLine(SCREEN_WIDTH/2+4, SCREEN_HEIGTH/2, SCREEN_WIDTH/2+49, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1835 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGTH/2-49, SCREEN_WIDTH/2, SCREEN_HEIGTH/2-4, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1836 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGTH/2+4, SCREEN_WIDTH/2, SCREEN_HEIGTH/2+49, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1837 | + d3dg->Draw2DBox(SCREEN_WIDTH/2-50, SCREEN_HEIGTH/2-1, SCREEN_WIDTH/20+50, SCREEN_HEIGTH/2+1, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.5f)); | |
| 1838 | + d3dg->Draw2DBox(SCREEN_WIDTH/2-1, SCREEN_HEIGTH/2-50, SCREEN_WIDTH/2+1, SCREEN_HEIGTH/2+50, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.5f)); | |
| 1839 | + } | |
| 1840 | + if( (Camera_F1mode == false)&&(myHuman->GetScopeMode() == 2) ){ | |
| 1841 | + d3dg->Draw2DTexture(0, 0, Resource.GetScopeTexture(), SCREEN_WIDTH, SCREEN_HEIGTH, 1.0f); | |
| 1842 | + d3dg->Draw2DLine(0, SCREEN_HEIGTH/2, SCREEN_WIDTH, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1843 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, 0, SCREEN_WIDTH/2, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1844 | + d3dg->Draw2DBox(0, SCREEN_HEIGTH/2-1, SCREEN_WIDTH, SCREEN_HEIGTH/2+1, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.5f)); | |
| 1845 | + d3dg->Draw2DBox(SCREEN_WIDTH/2-1, 0, SCREEN_WIDTH/2+1, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.5f)); | |
| 1846 | + } | |
| 1847 | + | |
| 1848 | + //目隠し表示 | |
| 1849 | + if( hp > 0 ){ | |
| 1850 | + | |
| 1851 | + int scopemode = myHuman->GetScopeMode(); | |
| 1852 | + float addang; | |
| 1853 | + float adddist = 1.2f; | |
| 1854 | + | |
| 1855 | + //スコープによる視野角を決定 | |
| 1856 | + if( scopemode == 0 ){ addang = VIEWANGLE_NORMAL / 4; } | |
| 1857 | + if( scopemode == 1 ){ addang = VIEWANGLE_SCOPE_1 / 4; } | |
| 1858 | + if( scopemode == 2 ){ addang = VIEWANGLE_SCOPE_2 / 4; } | |
| 1859 | + | |
| 1860 | + //上 | |
| 1861 | + if( CollD.CheckALLBlockInside(camera_x + cos(camera_rx)*cos(camera_ry + addang) * adddist, camera_y + sin(camera_ry + addang) * adddist, camera_z + sin(camera_rx)*cos(camera_ry + addang) * adddist) == true ){ | |
| 1862 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1863 | + } | |
| 1864 | + | |
| 1865 | + //下 | |
| 1866 | + if( CollD.CheckALLBlockInside(camera_x + cos(camera_rx)*cos(camera_ry - addang) * adddist, camera_y + sin(camera_ry - addang) * adddist, camera_z + sin(camera_rx)*cos(camera_ry - addang) * adddist) == true ){ | |
| 1867 | + d3dg->Draw2DBox(0, SCREEN_HEIGTH/2, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1868 | + } | |
| 1869 | + | |
| 1870 | + //左 | |
| 1871 | + if( CollD.CheckALLBlockInside(camera_x + cos(camera_rx + addang)*cos(camera_ry) * adddist, camera_y + sin(camera_ry) * adddist, camera_z + sin(camera_rx + addang)*cos(camera_ry) * adddist) == true ){ | |
| 1872 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH/2, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1873 | + } | |
| 1874 | + | |
| 1875 | + //右 | |
| 1876 | + if( CollD.CheckALLBlockInside(camera_x + cos(camera_rx - addang)*cos(camera_ry) * adddist, camera_y + sin(camera_ry) * adddist, camera_z + sin(camera_rx - addang)*cos(camera_ry) * adddist) == true ){ | |
| 1877 | + d3dg->Draw2DBox(SCREEN_WIDTH/2, 0, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f)); | |
| 1878 | + } | |
| 1879 | + } | |
| 1880 | + | |
| 1881 | + //デバック用・ゲーム情報の表示 | |
| 1882 | + if( (ShowInfo_Debugmode == true)||(Camera_Debugmode == true) ){ | |
| 1883 | + //システムフォントによる表示 見やすい・重い | |
| 1884 | + /* | |
| 1885 | + sprintf(str, "OpenXOPS テスト\ncamera x:%.2f y:%.2f z:%.2f rx:%.2f ry:%.2f\n" | |
| 1886 | + "human[%d]:x:%.2f y:%.2f z:%.2f rx:%.2f\n" | |
| 1887 | + "I:%02dms PO:%02dms PA:%02dms PE:%02dms R:%02dms", | |
| 1888 | + camera_x, camera_y, camera_z, camera_rx, camera_ry, | |
| 1889 | + ObjMgr.GetPlayerID(), human_x, human_y, human_z, human_rx, | |
| 1890 | + time_input, time_process_object, time_process_ai, time_process_event, time_render); | |
| 1891 | + d3dg->Draw2DMSFontText(10+1, 10+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f)); | |
| 1892 | + d3dg->Draw2DMSFontText(10, 10, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f)); | |
| 1893 | + */ | |
| 1894 | + | |
| 1895 | + //テクスチャフォントによる表示 軽い・見にくい | |
| 1896 | + sprintf(str, "frame:%d time %02d:%02d", framecnt, framecnt/(int)GAMEFPS/60, framecnt/(int)GAMEFPS%60); | |
| 1897 | + d3dg->Draw2DTextureFontText(10+1, 10+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 10, 14); | |
| 1898 | + d3dg->Draw2DTextureFontText(10, 10, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 10, 14); | |
| 1899 | + sprintf(str, "camera x:%.2f y:%.2f z:%.2f rx:%.2f ry:%.2f", camera_x, camera_y, camera_z, camera_rx, camera_ry); | |
| 1900 | + d3dg->Draw2DTextureFontText(10+1, 30+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 10, 14); | |
| 1901 | + d3dg->Draw2DTextureFontText(10, 30, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 10, 14); | |
| 1902 | + sprintf(str, "human[%d] x:%.2f y:%.2f z:%.2f rx:%.2f HP:%d", ObjMgr.GetPlayerID(), human_x, human_y, human_z, human_rx, hp); | |
| 1903 | + d3dg->Draw2DTextureFontText(10+1, 50+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 10, 14); | |
| 1904 | + d3dg->Draw2DTextureFontText(10, 50, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 10, 14); | |
| 1905 | + sprintf(str, "Input:%02dms Object:%02dms AI:%02dms Event:%02dms Sound:%02dms", time_input, time_process_object, time_process_ai, time_process_event, time_sound); | |
| 1906 | + d3dg->Draw2DTextureFontText(10+1, 70+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 10, 14); | |
| 1907 | + d3dg->Draw2DTextureFontText(10, 70, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 10, 14); | |
| 1908 | + sprintf(str, "Render:%02dms", time_render); | |
| 1909 | + d3dg->Draw2DTextureFontText(10+1, 90+1, str, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 10, 14); | |
| 1910 | + d3dg->Draw2DTextureFontText(10, 90, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 10, 14); | |
| 1911 | + } | |
| 1912 | + else{ | |
| 1913 | + d3dg->Draw2DTextureFontText(10+1, 10+1, "Debug information [F11]", D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,1.0f), 12, 18); | |
| 1914 | + d3dg->Draw2DTextureFontText(10, 10, "Debug information [F11]", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 12, 18); | |
| 1915 | + } | |
| 1916 | + | |
| 1917 | + //ゲーム実行速度の表示 | |
| 1918 | + if( 1 ){ | |
| 1919 | + sprintf(str, "fps:%.2f", fps); | |
| 1920 | + } | |
| 1921 | + else{ | |
| 1922 | + int speed = (int)(fps / (1000.0f/GAMEFRAMEMS) * 100); | |
| 1923 | + sprintf(str, "PROCESSING SPEED %d%%", speed); | |
| 1924 | + } | |
| 1925 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH - strlen(str)*14 - 14 +1, 10+1, str, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 14, 18); | |
| 1926 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH - strlen(str)*14 - 14, 10, str, D3DCOLOR_COLORVALUE(1.0f,0.5f,0.0f,1.0f), 14, 18); | |
| 1927 | + | |
| 1928 | + //HUD表示・モードA | |
| 1929 | + if( Camera_F2mode == 0 ){ | |
| 1930 | + //右下エリア用文字コード設定 | |
| 1931 | + str[0] = 'ー'; | |
| 1932 | + for(int i=1; i<HUDA_WEAPON_SIZEW-1; i++){ | |
| 1933 | + str[i] = 'ア'; | |
| 1934 | + } | |
| 1935 | + str[HUDA_WEAPON_SIZEW-1] = 'イ'; | |
| 1936 | + str[HUDA_WEAPON_SIZEW] = 0x00; | |
| 1937 | + | |
| 1938 | + //左下エリア描画 | |
| 1939 | + d3dg->Draw2DTextureFontText(15, SCREEN_HEIGTH - 105, "ウエエエエエエオ", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1940 | + d3dg->Draw2DTextureFontText(15, SCREEN_HEIGTH - 105 +32, "テトトトトトトナ", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1941 | + d3dg->Draw2DTextureFontText(15, SCREEN_HEIGTH - 55, "ウエエカキキキクケ", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1942 | + d3dg->Draw2DTextureFontText(15, SCREEN_HEIGTH - 55 +32, "テトトニヌヌヌネノ", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1943 | + | |
| 1944 | + //右下エリア描画 | |
| 1945 | + d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1946 | + for(int i=0; i<HUDA_WEAPON_SIZEW; i++){ str[i] += 0x10; } | |
| 1947 | + for(int i=1; i<HUDA_WEAPON_SIZEH-1; i++){ | |
| 1948 | + d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY + 32*i, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1949 | + } | |
| 1950 | + for(int i=0; i<HUDA_WEAPON_SIZEW; i++){ str[i] += 0x10; } | |
| 1951 | + d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY + 32*(HUDA_WEAPON_SIZEH-1), str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,0.5f), 32, 32); | |
| 1952 | + | |
| 1953 | + //武器の弾数表示 | |
| 1954 | + sprintf(str, "サ%d コ%d", lnbs, (nbs - lnbs)); | |
| 1955 | + d3dg->Draw2DTextureFontText(25, SCREEN_HEIGTH - 96, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 23, 24); | |
| 1956 | + | |
| 1957 | + //HPによる色の決定 | |
| 1958 | + int statecolor; | |
| 1959 | + if( hp >= 100 ){ | |
| 1960 | + statecolor = D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f); | |
| 1961 | + } | |
| 1962 | + else if( hp >= 50 ){ | |
| 1963 | + statecolor = D3DCOLOR_COLORVALUE(1.0f/50*(100-hp),1.0f,0.0f,1.0f); | |
| 1964 | + } | |
| 1965 | + else if( hp > 0 ){ | |
| 1966 | + statecolor = D3DCOLOR_COLORVALUE(1.0f,1.0f/50*hp,0.0f,1.0f); | |
| 1967 | + } | |
| 1968 | + else{ | |
| 1969 | + statecolor = D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f); | |
| 1970 | + } | |
| 1971 | + | |
| 1972 | + //HP表示 | |
| 1973 | + if( hp >= 80 ){ | |
| 1974 | + d3dg->Draw2DTextureFontText(23, SCREEN_HEIGTH - 45, "STATE", statecolor, 18, 24); | |
| 1975 | + d3dg->Draw2DTextureFontText(155, SCREEN_HEIGTH - 45, "FINE", statecolor, 18, 24); | |
| 1976 | + } | |
| 1977 | + else if( hp >= 40 ){ | |
| 1978 | + d3dg->Draw2DTextureFontText(23, SCREEN_HEIGTH - 45, "STATE", statecolor, 18, 24); | |
| 1979 | + d3dg->Draw2DTextureFontText(135, SCREEN_HEIGTH - 45, "CAUTION", statecolor, 18, 24); | |
| 1980 | + } | |
| 1981 | + else if( hp > 0 ){ | |
| 1982 | + d3dg->Draw2DTextureFontText(23, SCREEN_HEIGTH - 45, "STATE", statecolor, 18, 24); | |
| 1983 | + d3dg->Draw2DTextureFontText(140, SCREEN_HEIGTH - 45, "DANGER", statecolor, 18, 24); | |
| 1984 | + } | |
| 1985 | + else{ | |
| 1986 | + d3dg->Draw2DTextureFontText(23, SCREEN_HEIGTH - 45, "STATE", statecolor, 18, 24); | |
| 1987 | + d3dg->Draw2DTextureFontText(155, SCREEN_HEIGTH - 45, "DEAD", statecolor, 18, 24); | |
| 1988 | + } | |
| 1989 | + | |
| 1990 | + //武器名表示 | |
| 1991 | + d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX + 9, HUDA_WEAPON_POSY + 4, weaponname, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 16, 20); | |
| 1992 | + } | |
| 1993 | + | |
| 1994 | + //HUD表示・モードB | |
| 1995 | + if( Camera_F2mode == 1 ){ | |
| 1996 | + //画面周りの線 | |
| 1997 | + d3dg->Draw2DLine(0, 0, SCREEN_WIDTH-1, 0, D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f)); | |
| 1998 | + d3dg->Draw2DLine(SCREEN_WIDTH-1, 0, SCREEN_WIDTH-1, SCREEN_HEIGTH-1, D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f)); | |
| 1999 | + d3dg->Draw2DLine(0, 0, 0, SCREEN_HEIGTH-1, D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f)); | |
| 2000 | + d3dg->Draw2DLine(0, SCREEN_HEIGTH-1, SCREEN_WIDTH-1, SCREEN_HEIGTH-1, D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f)); | |
| 2001 | + | |
| 2002 | + //武器名表示 | |
| 2003 | + d3dg->Draw2DBox(8, SCREEN_HEIGTH - 32, 227, SCREEN_HEIGTH - 7, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,0.3f)); | |
| 2004 | + d3dg->Draw2DTextureFontText(10, SCREEN_HEIGTH - 30, weaponname, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 16, 20); | |
| 2005 | + } | |
| 2006 | + | |
| 2007 | + //イベントメッセージ表示 | |
| 2008 | + if( (message_id != -1)&&(message_cnt < TOTAL_EVENTENT_SHOWMESCNT) ){ | |
| 2009 | + char messtr[MAX_POINTMESSAGEBYTE]; | |
| 2010 | + PointData.GetMessageText(messtr, message_id); | |
| 2011 | + float effectA = 1.0f; | |
| 2012 | + if( message_cnt < (int)(0.2f*GAMEFPS) ){ effectA = 1.0f/(0.2f*GAMEFPS) * (message_cnt - (int)(0.0f*GAMEFPS)); } | |
| 2013 | + if( TOTAL_EVENTENT_SHOWMESCNT-(int)(0.2f*GAMEFPS) < message_cnt ){ effectA = 1.0f - 1.0f/(0.2f*GAMEFPS) * (message_cnt - TOTAL_EVENTENT_SHOWMESCNT-(int)(0.2f*GAMEFPS)); } | |
| 2014 | + d3dg->Draw2DMSFontTextCenter(0 +1, SCREEN_HEIGTH - 140 +1, SCREEN_WIDTH, 140, messtr, D3DCOLOR_COLORVALUE(0.1f,0.1f,0.1f,effectA)); | |
| 2015 | + d3dg->Draw2DMSFontTextCenter(0, SCREEN_HEIGTH - 140, SCREEN_WIDTH, 140, messtr, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,effectA)); | |
| 2016 | + } | |
| 2017 | + | |
| 2018 | + //リロード表示 | |
| 2019 | + if( reloadcnt > 0 ){ | |
| 2020 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 145 +3, SCREEN_HEIGTH - 180+3, "RELOADING", D3DCOLOR_COLORVALUE(0.2f,0.2f,0.2f,1.0f), 32, 34); | |
| 2021 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 145, SCREEN_HEIGTH - 180, "RELOADING", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 32, 34); | |
| 2022 | + } | |
| 2023 | + | |
| 2024 | + //武器切り替え表示 | |
| 2025 | + if( selectweaponcnt > 0 ){ | |
| 2026 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 130 +3, SCREEN_HEIGTH - 180+3, "CHANGING", D3DCOLOR_COLORVALUE(0.2f,0.2f,0.2f,1.0f), 32, 34); | |
| 2027 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 130, SCREEN_HEIGTH - 180, "CHANGING", D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 32, 34); | |
| 2028 | + } | |
| 2029 | + | |
| 2030 | + //照準表示 | |
| 2031 | + if( (Camera_F1mode == false)&&(weapon[selectweapon] != NULL)&&(end_framecnt == 0)&&(myHuman->GetScopeMode() == 0)&&(param_scopemode != 2) ){ | |
| 2032 | + if( GameConfig.GetAnotherGunsightFlag() ){ //オプション型 | |
| 2033 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGTH/2, SCREEN_WIDTH/2, SCREEN_HEIGTH/2+4, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 2034 | + d3dg->Draw2DLine(SCREEN_WIDTH/2-15, SCREEN_HEIGTH/2+15, SCREEN_WIDTH/2-19, SCREEN_HEIGTH/2+19, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 2035 | + d3dg->Draw2DLine(SCREEN_WIDTH/2+15, SCREEN_HEIGTH/2+15, SCREEN_WIDTH/2+19, SCREEN_HEIGTH/2+19, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f)); | |
| 2036 | + d3dg->Draw2DLine(SCREEN_WIDTH/2-4, SCREEN_HEIGTH/2+4, SCREEN_WIDTH/2+4, SCREEN_HEIGTH/2+4, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2037 | + | |
| 2038 | + d3dg->Draw2DLine(SCREEN_WIDTH/2-4 - ErrorRange, SCREEN_HEIGTH/2-4 - ErrorRange, SCREEN_WIDTH/2-4 - ErrorRange, SCREEN_HEIGTH/2+4 + ErrorRange, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2039 | + d3dg->Draw2DLine(SCREEN_WIDTH/2+4 + ErrorRange, SCREEN_HEIGTH/2-4 - ErrorRange, SCREEN_WIDTH/2+4 + ErrorRange, SCREEN_HEIGTH/2+4 + ErrorRange, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2040 | + } | |
| 2041 | + else{ //標準型 | |
| 2042 | + d3dg->Draw2DLine(SCREEN_WIDTH/2-13, SCREEN_HEIGTH/2, SCREEN_WIDTH/2-3, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2043 | + d3dg->Draw2DLine(SCREEN_WIDTH/2+13, SCREEN_HEIGTH/2, SCREEN_WIDTH/2+3, SCREEN_HEIGTH/2, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2044 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGTH/2-13, SCREEN_WIDTH/2, SCREEN_HEIGTH/2-3, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2045 | + d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGTH/2+13, SCREEN_WIDTH/2, SCREEN_HEIGTH/2+3, D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f)); | |
| 2046 | + | |
| 2047 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 16 - ErrorRange, SCREEN_HEIGTH/2 - 16, "ス", D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f), 32, 32); | |
| 2048 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 16 + ErrorRange, SCREEN_HEIGTH/2 - 16, "セ", D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,0.5f), 32, 32); | |
| 2049 | + } | |
| 2050 | + } | |
| 2051 | + | |
| 2052 | + | |
| 2053 | + //----------------------------------- | |
| 2054 | + | |
| 2055 | + //Zバッファを初期化 | |
| 2056 | + d3dg->ResetZbuffer(); | |
| 2057 | + | |
| 2058 | + | |
| 2059 | + //HUD表示・モードA | |
| 2060 | + if( Camera_F2mode == 0 ){ | |
| 2061 | + int notselectweapon = selectweapon + 1; | |
| 2062 | + if( notselectweapon == TOTAL_HAVEWEAPON ){ notselectweapon = 0; } | |
| 2063 | + | |
| 2064 | + //(3D描画)カメラ座標を暫定設定 | |
| 2065 | + d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL); | |
| 2066 | + | |
| 2067 | + //(3D描画)所持している武器モデルの描画・メイン武器 | |
| 2068 | + GameParamInfo.GetWeapon(weapon_paramid[selectweapon], &weapon_paramdata); | |
| 2069 | + Resource.GetWeaponModelTexture(weapon_paramid[selectweapon], &weaponmodel, &weapontexture); | |
| 2070 | + d3dg->SetWorldTransformPlayerWeapon(true, camera_x, camera_y, camera_z, camera_rx, camera_ry, (float)M_PI/180*framecnt*2, weapon_paramdata.size); | |
| 2071 | + d3dg->RenderModel(weaponmodel, weapontexture); | |
| 2072 | + | |
| 2073 | + //(3D描画)所持している武器モデルの描画・サブ武器 | |
| 2074 | + GameParamInfo.GetWeapon(weapon_paramid[notselectweapon], &weapon_paramdata); | |
| 2075 | + Resource.GetWeaponModelTexture(weapon_paramid[notselectweapon], &weaponmodel, &weapontexture); | |
| 2076 | + d3dg->SetWorldTransformPlayerWeapon(false, camera_x, camera_y, camera_z, camera_rx, camera_ry, 0.0f, weapon_paramdata.size); | |
| 2077 | + d3dg->RenderModel(weaponmodel, weapontexture); | |
| 2078 | + } | |
| 2079 | + | |
| 2080 | + //----------------------------------- | |
| 2081 | + | |
| 2082 | + | |
| 2083 | + //スタート時のブラックアウト設定 | |
| 2084 | + if( start_framecnt < 1*((int)GAMEFPS) ){ | |
| 2085 | + effect = 1.0f/(1*((int)GAMEFPS)) * (1*((int)GAMEFPS) - start_framecnt); | |
| 2086 | + } | |
| 2087 | + else if( end_framecnt > 0 ){ | |
| 2088 | + effect = 1.0f/(4*((int)GAMEFPS)) * end_framecnt; | |
| 2089 | + if( effect > 1.0f ){ effect = 1.0f; } | |
| 2090 | + } | |
| 2091 | + else{ | |
| 2092 | + effect = 0.0f; | |
| 2093 | + } | |
| 2094 | + d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGTH, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,effect)); | |
| 2095 | + | |
| 2096 | + //終了時のブラックアウト設定 | |
| 2097 | + if( end_framecnt > 0 ){ | |
| 2098 | + if( end_framecnt < 1*((int)GAMEFPS) ){ | |
| 2099 | + effect = 1.0f/(1*((int)GAMEFPS)) * end_framecnt; | |
| 2100 | + } | |
| 2101 | + else if( end_framecnt > 4*((int)GAMEFPS) ){ | |
| 2102 | + effect = 1.0f/(1*((int)GAMEFPS)) * (5*((int)GAMEFPS) - end_framecnt); | |
| 2103 | + } | |
| 2104 | + else{ | |
| 2105 | + effect = 1.0f; | |
| 2106 | + } | |
| 2107 | + | |
| 2108 | + if( GameInfoData.missioncomplete == true ){ | |
| 2109 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 252, SCREEN_HEIGTH/2 + 10, "objective complete", D3DCOLOR_COLORVALUE(1.0f,0.5f,0.0f,effect), 28, 32); | |
| 2110 | + } | |
| 2111 | + else{ | |
| 2112 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 210, SCREEN_HEIGTH/2 + 10, "mission failure", D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,effect), 28, 32); | |
| 2113 | + } | |
| 2114 | + } | |
| 2115 | + | |
| 2116 | + | |
| 2117 | + time_render = GetTimeMS() - time; | |
| 2118 | +} | |
| 2119 | + | |
| 2120 | +void maingame::Destroy() | |
| 2121 | +{ | |
| 2122 | + //ブロックデータ解放 | |
| 2123 | + d3dg->CleanupMapdata(); | |
| 2124 | + | |
| 2125 | + //オブジェクトマネージャー解放 | |
| 2126 | + ObjMgr.Cleanup(); | |
| 2127 | + | |
| 2128 | + //背景空解放 | |
| 2129 | + Resource.CleanupSkyModelTexture(); | |
| 2130 | + | |
| 2131 | + GameState->NextState(); | |
| 2132 | +} | |
| 2133 | + | |
| 2134 | +//! コンストラクタ | |
| 2135 | +result::result() | |
| 2136 | +{} | |
| 2137 | + | |
| 2138 | +//! ディストラクタ | |
| 2139 | +result::~result() | |
| 2140 | +{} | |
| 2141 | + | |
| 2142 | +//! リザルト画面の2D描画部分 | |
| 2143 | +void result::Render2D() | |
| 2144 | +{ | |
| 2145 | + char mname[64]; | |
| 2146 | + char str[32]; | |
| 2147 | + float effectA = 1.0f - 0.8f/((int)GAMEFPS)*(framecnt%((int)GAMEFPS)); | |
| 2148 | + float rate; | |
| 2149 | + if( GameInfoData.fire == 0 ){ | |
| 2150 | + rate = 0.0f; | |
| 2151 | + } | |
| 2152 | + else{ | |
| 2153 | + rate = (float)GameInfoData.ontarget / GameInfoData.fire * 100; | |
| 2154 | + } | |
| 2155 | + | |
| 2156 | + //メモ:背景画像の描画は、自動的に行われる。 | |
| 2157 | + | |
| 2158 | + //固定文字描画 | |
| 2159 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 50*3, 40, "RESULT", D3DCOLOR_COLORVALUE(1.0f,0.0f,1.0f,effectA), 50, 42); | |
| 2160 | + | |
| 2161 | + //ミッション名を取得し描画 | |
| 2162 | + if( MIFdata.GetFiletype() == false ){ | |
| 2163 | + GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, mname, NULL, NULL); | |
| 2164 | + } | |
| 2165 | + else{ | |
| 2166 | + strcpy(mname, MIFdata.GetMissionFullname()); | |
| 2167 | + } | |
| 2168 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(mname)*18/2, 100, mname, D3DCOLOR_COLORVALUE(0.5f,0.5f,1.0f,1.0f), 18, 25); | |
| 2169 | + | |
| 2170 | + //ミッションクリアーの有無 | |
| 2171 | + if( GameInfoData.missioncomplete == true ){ | |
| 2172 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 216, 150, "mission successful", D3DCOLOR_COLORVALUE(0.0f,1.0f,0.0f,1.0f), 24, 32); | |
| 2173 | + } | |
| 2174 | + else{ | |
| 2175 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 180, 150, "mission failure", D3DCOLOR_COLORVALUE(1.0f,0.0f,0.0f,1.0f), 24, 32); | |
| 2176 | + } | |
| 2177 | + | |
| 2178 | + //結果表示 | |
| 2179 | + sprintf(str, "Time %dmin %dsec", GameInfoData.framecnt/(int)GAMEFPS/60, GameInfoData.framecnt/(int)GAMEFPS%60); | |
| 2180 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 210, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 20, 32); | |
| 2181 | + sprintf(str, "Rounds fired %d", GameInfoData.fire); | |
| 2182 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 260, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 20, 32); | |
| 2183 | + sprintf(str, "Rounds on target %d", GameInfoData.ontarget); | |
| 2184 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 310, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 20, 32); | |
| 2185 | + sprintf(str, "Accuracy rate %.1f%%", rate); | |
| 2186 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 360, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 20, 32); | |
| 2187 | + sprintf(str, "Kill %d / HeadShot %d", GameInfoData.kill, GameInfoData.headshot); | |
| 2188 | + d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 410, str, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,1.0f), 20, 32); | |
| 2189 | +} | |
| 2190 | + | |
| 2191 | +//! screen派生クラスの初期化(クラスの設定) | |
| 2192 | +void InitScreen(opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result) | |
| 2193 | +{ | |
| 2194 | + Opening->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound); | |
| 2195 | + MainMenu->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound); | |
| 2196 | + Briefing->SetClass(&GameState, &d3dg, &inputCtrl); | |
| 2197 | + MainGame->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound); | |
| 2198 | + Result->SetClass(&GameState, &d3dg, &inputCtrl); | |
| 2199 | +} | |
| 2200 | + | |
| 2201 | +//! screen派生クラスの実行 | |
| 2202 | +void ProcessScreen(HWND hWnd, opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result, unsigned int framecnt) | |
| 2203 | +{ | |
| 2204 | + int error; | |
| 2205 | + | |
| 2206 | + switch(GameState.GetState()){ | |
| 2207 | + //オープニング初期化 | |
| 2208 | + case STATE_CREATE_OPENING: | |
| 2209 | + error = Opening->Create(); | |
| 2210 | + if( error == 1 ){ | |
| 2211 | + MessageBox(hWnd, "block data open failed", "error", MB_OK); | |
| 2212 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2213 | + } | |
| 2214 | + if( error == 2 ){ | |
| 2215 | + MessageBox(hWnd, "point data open failed", "error", MB_OK); | |
| 2216 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2217 | + } | |
| 2218 | + break; | |
| 2219 | + | |
| 2220 | + //オープニング実行 | |
| 2221 | + case STATE_NOW_OPENING: | |
| 2222 | + Opening->Input(); | |
| 2223 | + Opening->Process(); | |
| 2224 | + Opening->Sound(); | |
| 2225 | + if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){ | |
| 2226 | + Opening->RenderMain(); | |
| 2227 | + } | |
| 2228 | + break; | |
| 2229 | + | |
| 2230 | + //オープニング廃棄 | |
| 2231 | + case STATE_DESTROY_OPENING: | |
| 2232 | + Opening->Destroy(); | |
| 2233 | + break; | |
| 2234 | + | |
| 2235 | + //メニュー初期化 | |
| 2236 | + case STATE_CREATE_MENU: | |
| 2237 | + error = MainMenu->Create(); | |
| 2238 | + if( error == 1 ){ | |
| 2239 | + MessageBox(hWnd, "block data open failed", "error", MB_OK); | |
| 2240 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2241 | + } | |
| 2242 | + if( error == 2 ){ | |
| 2243 | + MessageBox(hWnd, "point data open failed", "error", MB_OK); | |
| 2244 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2245 | + } | |
| 2246 | + break; | |
| 2247 | + | |
| 2248 | + //メニュー実行 | |
| 2249 | + case STATE_NOW_MENU: | |
| 2250 | + MainMenu->Input(); | |
| 2251 | + MainMenu->Process(); | |
| 2252 | + MainMenu->Sound(); | |
| 2253 | + if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){ | |
| 2254 | + MainMenu->RenderMain(); | |
| 2255 | + } | |
| 2256 | + break; | |
| 2257 | + | |
| 2258 | + //メニュー廃棄 | |
| 2259 | + case STATE_DESTROY_MENU: | |
| 2260 | + MainMenu->Destroy(); | |
| 2261 | + break; | |
| 2262 | + | |
| 2263 | + //ブリーフィング初期化 | |
| 2264 | + case STATE_CREATE_BRIEFING: | |
| 2265 | + error = Briefing->Create(); | |
| 2266 | + if( error == 1 ){ | |
| 2267 | + MessageBox(hWnd, "briefing data open failed", "error", MB_OK); | |
| 2268 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2269 | + } | |
| 2270 | + break; | |
| 2271 | + | |
| 2272 | + //ブリーフィング実行 | |
| 2273 | + case STATE_NOW_BRIEFING: | |
| 2274 | + Briefing->Input(); | |
| 2275 | + Briefing->Process(); | |
| 2276 | + if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){ | |
| 2277 | + Briefing->RenderMain(); | |
| 2278 | + } | |
| 2279 | + break; | |
| 2280 | + | |
| 2281 | + //ブリーフィング廃棄 | |
| 2282 | + case STATE_DESTROY_BRIEFING: | |
| 2283 | + Briefing->Destroy(); | |
| 2284 | + break; | |
| 2285 | + | |
| 2286 | + //メインゲーム初期化 | |
| 2287 | + case STATE_CREATE_MAINGAME: | |
| 2288 | + error = MainGame->Create(); | |
| 2289 | + if( error == 1 ){ | |
| 2290 | + MessageBox(hWnd, "block data open failed", "error", MB_OK); | |
| 2291 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2292 | + } | |
| 2293 | + if( error == 2 ){ | |
| 2294 | + MessageBox(hWnd, "point data open failed", "error", MB_OK); | |
| 2295 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2296 | + } | |
| 2297 | + break; | |
| 2298 | + | |
| 2299 | + //メインゲーム実行 | |
| 2300 | + case STATE_NOW_MAINGAME: | |
| 2301 | + MainGame->Input(); | |
| 2302 | + MainGame->Process(); | |
| 2303 | + MainGame->Sound(); | |
| 2304 | + if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){ | |
| 2305 | + MainGame->RenderMain(); | |
| 2306 | + } | |
| 2307 | + break; | |
| 2308 | + | |
| 2309 | + //メインゲーム廃棄 | |
| 2310 | + case STATE_DESTROY_MAINGAME: | |
| 2311 | + MainGame->Destroy(); | |
| 2312 | + break; | |
| 2313 | + | |
| 2314 | + //リザルト初期化 | |
| 2315 | + case STATE_CREATE_RESULT: | |
| 2316 | + error = Result->Create(); | |
| 2317 | + break; | |
| 2318 | + | |
| 2319 | + //リザルト実行 | |
| 2320 | + case STATE_NOW_RESULT: | |
| 2321 | + Result->Input(); | |
| 2322 | + Result->Process(); | |
| 2323 | + if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){ | |
| 2324 | + Result->RenderMain(); | |
| 2325 | + } | |
| 2326 | + break; | |
| 2327 | + | |
| 2328 | + //リザルト廃棄 | |
| 2329 | + case STATE_DESTROY_RESULT: | |
| 2330 | + Result->Destroy(); | |
| 2331 | + break; | |
| 2332 | + | |
| 2333 | + //ゲーム終了 | |
| 2334 | + case STATE_EXIT: | |
| 2335 | + PostMessage(hWnd, WM_CLOSE, 0L, 0L); | |
| 2336 | + break; | |
| 2337 | + | |
| 2338 | + default: | |
| 2339 | + break; | |
| 2340 | + } | |
| 2341 | +} | |
| \ No newline at end of file |
| @@ -0,0 +1,203 @@ | ||
| 1 | +//! @file event.cpp | |
| 2 | +//! @brief EventControlクラスの定義 | |
| 3 | + | |
| 4 | +//-------------------------------------------------------------------------------- | |
| 5 | +// | |
| 6 | +// OpenXOPS | |
| 7 | +// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved. | |
| 8 | +// | |
| 9 | +// Redistribution and use in source and binary forms, with or without | |
| 10 | +// modification, are permitted provided that the following conditions are met: | |
| 11 | +// * Redistributions of source code must retain the above copyright notice, | |
| 12 | +// this list of conditions and the following disclaimer. | |
| 13 | +// * Redistributions in binary form must reproduce the above copyright notice, | |
| 14 | +// this list of conditions and the following disclaimer in the documentation | |
| 15 | +// and/or other materials provided with the distribution. | |
| 16 | +// * Neither the name of the OpenXOPS Project nor the names of its contributors | |
| 17 | +// may be used to endorse or promote products derived from this software | |
| 18 | +// without specific prior written permission. | |
| 19 | +// | |
| 20 | +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| 21 | +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| 22 | +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| 23 | +// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY | |
| 24 | +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| 25 | +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| 26 | +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| 27 | +// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 28 | +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| 29 | +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 30 | +//-------------------------------------------------------------------------------- | |
| 31 | + | |
| 32 | +#include "event.h" | |
| 33 | + | |
| 34 | +//! コンストラクタ | |
| 35 | +EventControl::EventControl(PointDataInterface *in_Point, ObjectManager *in_ObjMgr) | |
| 36 | +{ | |
| 37 | + Point = in_Point; | |
| 38 | + ObjMgr = in_ObjMgr; | |
| 39 | + nextp4 = 0; | |
| 40 | + waitcnt = 0; | |
| 41 | +} | |
| 42 | + | |
| 43 | +//! ディストラクタ | |
| 44 | +EventControl::~EventControl() | |
| 45 | +{} | |
| 46 | + | |
| 47 | +//! 対象クラスを設定 | |
| 48 | +//! @param in_Point ポイントデータ管理クラス | |
| 49 | +//! @param in_ObjMgr オブジェクト管理クラス | |
| 50 | +//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。 | |
| 51 | +void EventControl::SetClass(PointDataInterface *in_Point, ObjectManager *in_ObjMgr) | |
| 52 | +{ | |
| 53 | + Point = in_Point; | |
| 54 | + ObjMgr = in_ObjMgr; | |
| 55 | +} | |
| 56 | + | |
| 57 | +//! リセット | |
| 58 | +//! @param EntryP4 イベント処理を開始する認識番号 (-100、-110、-120 など) | |
| 59 | +void EventControl::Reset(signed char EntryP4) | |
| 60 | +{ | |
| 61 | + nextp4 = EntryP4; | |
| 62 | + waitcnt = 0; | |
| 63 | +} | |
| 64 | + | |
| 65 | +//! 対象の人物がケースを持っているかチェック | |
| 66 | +//! @param in_human 調べる対象のhumanのポインタ | |
| 67 | +//! @return 持っている:true 持っていない:false | |
| 68 | +bool EventControl::CheckHaveCase(human *in_human) | |
| 69 | +{ | |
| 70 | + int selectweapon; | |
| 71 | + weapon *out_weapon[TOTAL_HAVEWEAPON]; | |
| 72 | + int weaponid; | |
| 73 | + | |
| 74 | + //所有する武器オブジェクトを全て取得 | |
| 75 | + in_human->GetWeapon(&selectweapon, out_weapon); | |
| 76 | + | |
| 77 | + //全て調べる | |
| 78 | + for(int i=0; i<TOTAL_HAVEWEAPON; i++){ | |
| 79 | + if( out_weapon[i] != NULL ){ | |
| 80 | + | |
| 81 | + //武器の種類番号を取得し、それがケースかどうか。 | |
| 82 | + out_weapon[i]->GetParamData(&weaponid, NULL, NULL); | |
| 83 | + if( weaponid == ID_WEAPON_CASE ){ | |
| 84 | + return true; | |
| 85 | + } | |
| 86 | + } | |
| 87 | + } | |
| 88 | + return false; | |
| 89 | +} | |
| 90 | + | |
| 91 | +//! 処理を実行 | |
| 92 | +//! @param endcnt 終了カウントのポインタ | |
| 93 | +//! @param complete ミッション成功フラグのポインタ | |
| 94 | +//! @param MessageID イベントメッセージ番号のポインタ | |
| 95 | +//! @param SetMessageID イベントメッセージ読み出しフラグ | |
| 96 | +//! @return 実行したステップ数 | |
| 97 | +//! @attention 渡された引数に変更がない場合、渡された引数のデータは操作されません。 | |
| 98 | +//! @attention SetMessageID は、メッセージイベントが実行された場合に true になります。<b>前回から変更されたとは限りません。</b> | |
| 99 | +int EventControl::Execution(int *endcnt, bool *complete, int *MessageID, bool *SetMessageID) | |
| 100 | +{ | |
| 101 | + pointdata data, pathdata; | |
| 102 | + int cnt; | |
| 103 | + human* thuman; | |
| 104 | + smallobject* tsmallobject; | |
| 105 | + float hx, hy, hz; | |
| 106 | + float x, y, z; | |
| 107 | + int pid; | |
| 108 | + | |
| 109 | + for(int i=0; i<TOTAL_EVENTFRAMESTEP; i++){ | |
| 110 | + cnt = i; | |
| 111 | + | |
| 112 | + //次のポイントを探す | |
| 113 | + if( Point->SearchPointdata(&data, 0x08, 0, 0, 0, nextp4, 0) == 0 ){ return cnt; } | |
| 114 | + if( (data.p1 < 10)&&(19 < data.p1) ){ return cnt; } | |
| 115 | + | |
| 116 | + switch(data.p1){ | |
| 117 | + case 10: //任務達成 | |
| 118 | + *endcnt += 1; | |
| 119 | + *complete = true; | |
| 120 | + return cnt; | |
| 121 | + | |
| 122 | + case 11: //任務失敗 | |
| 123 | + *endcnt += 1; | |
| 124 | + *complete = false; | |
| 125 | + return cnt; | |
| 126 | + | |
| 127 | + case 12: //死亡待ち | |
| 128 | + thuman = ObjMgr->SearchHuman(data.p2); | |
| 129 | + if( thuman == NULL ){ return cnt; } | |
| 130 | + if( thuman->GetDeadFlag() == false ){ return cnt; } | |
| 131 | + nextp4 = data.p3; | |
| 132 | + break; | |
| 133 | + | |
| 134 | + case 13: //到着待ち | |
| 135 | + thuman = ObjMgr->SearchHuman(data.p2); | |
| 136 | + if( thuman == NULL ){ return cnt; } | |
| 137 | + thuman->GetPosData(&hx, &hy, &hz, NULL); | |
| 138 | + x = hx - data.x; | |
| 139 | + y = hy - data.y; | |
| 140 | + z = hz - data.z; | |
| 141 | + if( sqrt(x*x + y*y+ + z*z) > DISTANCE_CHECKPOINT ){ return cnt; } | |
| 142 | + nextp4 = data.p3; | |
| 143 | + break; | |
| 144 | + | |
| 145 | + case 14: //歩きに変更 | |
| 146 | + if( Point->SearchPointdata(&pid, 0x08, 0, 0, 0, data.p2, 0) > 0 ){ | |
| 147 | + //対象がAIパスならば、強制的にパラメータを書き換える | |
| 148 | + Point->Getdata(&pathdata, pid); | |
| 149 | + if( (pathdata.p1 == 3)||(pathdata.p1 == 8) ){ | |
| 150 | + pathdata.p2 = 0; | |
| 151 | + } | |
| 152 | + Point->SetParam(pid, pathdata.p1, pathdata.p2, pathdata.p3, p |
Part of diff was cut off due to size limit. Use your local client to view the full diff.