• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

X operations(XOPS)に非常に近いFPSゲームを制作・リメイクし、成果物をオープンソースとして公開することを目的としたプロジェクトです。


Commit MetaInfo

Revision2 (tree)
Time2015-01-10 02:26:25
Authorxops-mikan

Log Message

初版コミット

Change Summary

Incremental Difference

--- trunk/input.h (nonexistent)
+++ trunk/input.h (revision 2)
@@ -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
--- trunk/objectmanager.h (nonexistent)
+++ trunk/objectmanager.h (revision 2)
@@ -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
--- trunk/window.cpp (nonexistent)
+++ trunk/window.cpp (revision 2)
@@ -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+}
--- trunk/config.h (nonexistent)
+++ trunk/config.h (revision 2)
@@ -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
--- trunk/statemachine.h (nonexistent)
+++ trunk/statemachine.h (revision 2)
@@ -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
--- trunk/object.h (nonexistent)
+++ trunk/object.h (revision 2)
@@ -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
--- trunk/datafile.h (nonexistent)
+++ trunk/datafile.h (revision 2)
@@ -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
--- trunk/parameter.cpp (nonexistent)
+++ trunk/parameter.cpp (revision 2)
@@ -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
--- trunk/doxygen.h (nonexistent)
+++ trunk/doxygen.h (revision 2)
@@ -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
--- trunk/gamemain.h (nonexistent)
+++ trunk/gamemain.h (revision 2)
@@ -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
--- trunk/soundmanager.cpp (nonexistent)
+++ trunk/soundmanager.cpp (revision 2)
@@ -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
--- trunk/main.cpp (nonexistent)
+++ trunk/main.cpp (revision 2)
@@ -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
--- trunk/event.h (nonexistent)
+++ trunk/event.h (revision 2)
@@ -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
--- trunk/sound.cpp (nonexistent)
+++ trunk/sound.cpp (revision 2)
@@ -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
--- trunk/ai.cpp (nonexistent)
+++ trunk/ai.cpp (revision 2)
@@ -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(&paramid, 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(&paramid, 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(&paramid, &target_pointid, NULL, NULL);
1749+ Param->GetHuman(paramid, &paramdata);
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
--- trunk/d3dgraphics.cpp (nonexistent)
+++ trunk/d3dgraphics.cpp (revision 2)
@@ -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
--- trunk/resource.h (nonexistent)
+++ trunk/resource.h (revision 2)
@@ -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
--- trunk/input.cpp (nonexistent)
+++ trunk/input.cpp (revision 2)
@@ -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
--- trunk/collision.h (nonexistent)
+++ trunk/collision.h (revision 2)
@@ -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
--- trunk/objectmanager.cpp (nonexistent)
+++ trunk/objectmanager.cpp (revision 2)
@@ -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
--- trunk/scene.h (nonexistent)
+++ trunk/scene.h (revision 2)
@@ -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
--- trunk/config.cpp (nonexistent)
+++ trunk/config.cpp (revision 2)
@@ -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+}
--- trunk/statemachine.cpp (nonexistent)
+++ trunk/statemachine.cpp (revision 2)
@@ -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
--- trunk/object.cpp (nonexistent)
+++ trunk/object.cpp (revision 2)
@@ -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(&param_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(&param_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(&param_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(&param_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(&param, 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, &paramdata);
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, &param) == 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, &paramdata);
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, &paramdata) - 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
--- trunk/datafile.cpp (nonexistent)
+++ trunk/datafile.cpp (revision 2)
@@ -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+}
--- trunk/window.h (nonexistent)
+++ trunk/window.h (revision 2)
@@ -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
--- trunk/gamemain.cpp (nonexistent)
+++ trunk/gamemain.cpp (revision 2)
@@ -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(&param, &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], &param);
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
--- trunk/event.cpp (nonexistent)
+++ trunk/event.cpp (revision 2)
@@ -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.