• R/O
  • SSH
  • HTTPS

提交

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

修订版45 (tree)
时间2015-02-20 01:15:15
作者xops-mikan

Log Message

Version:1.010

更改概述

差异

--- tags/v1.010-20150220/main.h (nonexistent)
+++ tags/v1.010-20150220/main.h (revision 45)
@@ -0,0 +1,115 @@
1+//! @file main.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 MAIN_H
33+#define MAIN_H
34+
35+#define MAINICON 101 //!< Icon
36+
37+//BorlandC++ Compilerか判定
38+#ifndef _MSC_VER
39+ #define COMPILER_BCC //!< Use BorlandC++ Compiler.
40+#endif
41+
42+#ifdef _DEBUG
43+ #include <crtdbg.h>
44+#endif
45+
46+#ifndef H_LAYERLEVEL
47+ #define H_LAYERLEVEL 3 //!< Select include file.
48+#endif
49+
50+#pragma warning(disable:4996) //VC++警告防止
51+
52+//定数
53+#define GAMENAME "OpenXOPS" //!< ゲーム名
54+#define GAMEVERSION "1.010" //!< ゲームのバージョン
55+#define GAMEFRAMEMS 30 //!< フレームあたりの処理時間(ms)
56+#define GAMEFPS (1000.0f/GAMEFRAMEMS) //!< FPS(フレームレート) 1000 / 30 = 33.333[FPS]
57+#define SCREEN_WIDTH 640 //!< スクリーンの幅
58+#define SCREEN_HEIGHT 480 //!< スクリーンの高さ
59+
60+#define MAX_ADDONLIST 128 //!< ADDONを読み込む最大数
61+
62+#define TOTAL_HAVEWEAPON 2 //!< 持てる武器の数
63+
64+//システムのインクルードファイル
65+#define _USE_MATH_DEFINES //!< math.h 'M_PI' enable
66+#include <stdio.h>
67+#include <stdlib.h>
68+#include <math.h>
69+
70+//BorlandC++ Compiler用の処理
71+#ifdef COMPILER_BCC
72+ #define sqrtf(df) sqrt(df)
73+ int _matherr(struct _exception *__e) { return 1; }
74+#endif
75+
76+#define SetFlag(value, bit) value = value | bit //!< ビットによるフラグ 設定
77+#define DelFlag(value, bit) value = value & (~bit) //!< ビットによるフラグ 解除
78+#define GetFlag(value, bit) (value & bit) //!< ビットによるフラグ 取得
79+
80+//低レイヤー
81+#if H_LAYERLEVEL >= 1
82+ #include "window.h"
83+ #include "config.h"
84+ #include "datafile.h"
85+ #include "d3dgraphics.h"
86+ #include "input.h"
87+ #include "sound.h"
88+ #include "parameter.h"
89+#endif
90+
91+//中間レイヤー
92+#if H_LAYERLEVEL >= 2
93+ #include "resource.h"
94+ #include "collision.h"
95+ #include "object.h"
96+ #include "soundmanager.h"
97+#endif
98+
99+//高レイヤー
100+#if H_LAYERLEVEL >= 3
101+ #include "objectmanager.h"
102+ #include "scene.h"
103+ #include "gamemain.h"
104+ #include "ai.h"
105+ #include "statemachine.h"
106+ #include "event.h"
107+#endif
108+
109+//追加ライブラリ
110+// not .lib
111+
112+extern class StateMachine GameState;
113+extern class Config GameConfig;
114+
115+#endif
\ No newline at end of file
--- tags/v1.010-20150220/ai.cpp (nonexistent)
+++ tags/v1.010-20150220/ai.cpp (revision 45)
@@ -0,0 +1,1863 @@
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+//! @brief コンストラクタ
35+AIcontrol::AIcontrol(class ObjectManager *in_ObjMgr, int in_ctrlid, 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+ ctrlid = in_ctrlid;
39+ ctrlhuman = in_ObjMgr->GeHumanObject(in_ctrlid);
40+ blocks = in_blocks;
41+ Points = in_Points;
42+ Param = in_Param;
43+ CollD = in_CollD;
44+ GameSound = in_GameSound;
45+
46+ battlemode = AI_NORMAL;
47+ movemode = AI_WAIT;
48+ target_pointid = -1;
49+ target_posx = 0.0f;
50+ target_posz = 0.0f;
51+ target_rx = 0.0f;
52+ total_move = 0.0f;
53+ waitcnt = 0;
54+ movejumpcnt = 1*((int)GAMEFPS);
55+ gotocnt = 0;
56+ moveturn_mode = 0;
57+ longattack = false;
58+}
59+
60+//! @brief ディストラクタ
61+AIcontrol::~AIcontrol()
62+{}
63+
64+//! @brief 対象クラスを設定
65+//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。
66+void AIcontrol::SetClass(class ObjectManager *in_ObjMgr, int in_ctrlid, class BlockDataInterface *in_blocks, class PointDataInterface *in_Points, class ParameterInfo *in_Param, class Collision *in_CollD, class SoundManager *in_GameSound)
67+{
68+ ObjMgr = in_ObjMgr;
69+ ctrlid = in_ctrlid;
70+ ctrlhuman = in_ObjMgr->GeHumanObject(in_ctrlid);
71+ blocks = in_blocks;
72+ Points = in_Points;
73+ Param = in_Param;
74+ CollD = in_CollD;
75+ GameSound = in_GameSound;
76+}
77+
78+//! @brief ランダムな整数値を返す
79+//! @param num 範囲
80+//! @return 0〜num-1
81+int AIcontrol::random(int num)
82+{
83+ return GetRand(num);
84+}
85+
86+//! @brief 人を検索
87+//! @param in_p4 検索する人の第4パラメータ(認識番号)
88+//! @param out_x X座標を受け取るポインタ
89+//! @param out_z Z座標を受け取るポインタ
90+//! @return 成功:1 失敗:0
91+int AIcontrol::SearchHumanPos(signed char in_p4, float *out_x, float *out_z)
92+{
93+ float x, z;
94+ human* thuman;
95+
96+ //人を検索してクラスを取得
97+ thuman = ObjMgr->SearchHuman(in_p4);
98+ if( thuman == NULL ){ return 0; }
99+
100+ //X・Z座標を取得
101+ thuman->GetPosData(&x, NULL, &z, NULL);
102+ *out_x = x;
103+ *out_z = z;
104+ return 1;
105+}
106+
107+//! @brief 目標地点に移動しているか確認
108+//! @return 到達:true 非到達:false
109+bool AIcontrol::CheckTargetPos()
110+{
111+ //距離を算出
112+ float x = posx - target_posx;
113+ float z = posz - target_posz;
114+ float r = x * x + z * z;
115+
116+ if( movemode == AI_TRACKING ){ //追尾中なら
117+ if( r < AI_ARRIVALDIST_TRACKING * AI_ARRIVALDIST_TRACKING ){
118+ return true;
119+ }
120+ }
121+ else{ //それ以外なら
122+ if( r < (AI_ARRIVALDIST_PATH * AI_ARRIVALDIST_PATH) ){
123+ return true;
124+ }
125+ }
126+
127+ return false;
128+}
129+
130+//! @brief 目標地点を検索
131+//! @param next 次を検索する
132+//! @return 完了:true 失敗:false
133+bool AIcontrol::SearchTarget(bool next)
134+{
135+ //ポイントの情報を取得
136+ pointdata pdata;
137+ if( Points->Getdata(&pdata, target_pointid) != 0 ){
138+ movemode = AI_NULL;
139+ return false;
140+ }
141+
142+ signed char nextpointp4;
143+
144+ //次のポイントを検索するなら
145+ if( next == true ){
146+ nextpointp4 = pdata.p3;
147+
148+ //ランダムパス処理
149+ if( pdata.p1 == 8 ){
150+ if( random(2) == 0 ){
151+ nextpointp4 = pdata.p2;
152+ }
153+ else{
154+ nextpointp4 = pdata.p3;
155+ }
156+ movemode = AI_RANDOM;
157+ }
158+
159+ //ポイントを検索
160+ if( Points->SearchPointdata(&pdata, 0x08, 0, 0, 0, nextpointp4, 0) == 0 ){
161+ return false;
162+ }
163+ }
164+
165+ //ランダムパスなら次へ
166+ if( pdata.p1 == 8 ){
167+ target_pointid = pdata.id;
168+ movemode = AI_RANDOM;
169+ return false;
170+ }
171+
172+ //人なら座標を取得
173+ if( (pdata.p1 == 1)||(pdata.p1 == 6) ){
174+ SearchHumanPos(pdata.p4, &target_posx, &target_posz);
175+ return true;
176+ }
177+
178+ //移動パスなら〜
179+ if( pdata.p1 == 3 ){
180+ //情報適用
181+ target_pointid = pdata.id;
182+ target_posx = pdata.x;
183+ target_posz = pdata.z;
184+ target_rx = pdata.r;
185+
186+ //移動ステート設定
187+ switch(pdata.p2){
188+ case 0: movemode = AI_WALK; break;
189+ case 1: movemode = AI_RUN; break;
190+ case 2: movemode = AI_WAIT; break;
191+ case 3:
192+ movemode = AI_TRACKING;
193+ if( next == true ){
194+ nextpointp4 = pdata.p3;
195+
196+ //ポイント(人)の情報を取得
197+ if( Points->SearchPointdata(&pdata, 0x08, 0, 0, 0, nextpointp4, 0) == 0 ){
198+ return false;
199+ }
200+
201+ //情報保存
202+ target_pointid = pdata.id;
203+ target_posx = pdata.x;
204+ target_posz = pdata.z;
205+ }
206+ break;
207+ case 4: movemode = AI_WAIT; break;
208+ case 5: movemode = AI_STOP; break;
209+ case 6: movemode = AI_GRENADE; break;
210+ case 7: movemode = AI_RUN2; break;
211+ default: break;
212+ }
213+ return true;
214+ }
215+
216+ movemode = AI_NULL;
217+ return false;
218+}
219+
220+//! @brief 目標地点に移動
221+void AIcontrol::MoveTarget()
222+{
223+ float r, atan;
224+ int paramid;
225+ HumanParameter Paraminfo;
226+ bool zombie;
227+
228+ //ゾンビかどうか判定
229+ ctrlhuman->GetParamData(&paramid, NULL, NULL, NULL);
230+ Param->GetHuman(paramid, &Paraminfo);
231+ if( Paraminfo.type == 2 ){
232+ zombie = true;
233+ }
234+ else{
235+ zombie = false;
236+ }
237+
238+ //目標地点への角度を求める
239+ CheckTargetAngle(posx, 0.0f, posz, rx*-1 + (float)M_PI/2, 0.0f, target_posx, 0.0f, target_posz, 0.0f, &atan, NULL, &r);
240+
241+ //大きな差があれば少しづつ旋回するだけ
242+ if( atan > AI_TURNRAD ){
243+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
244+ }
245+ if( atan < AI_TURNRAD*-1 ){
246+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
247+ }
248+
249+ //微々たる差なら一気に向く
250+ if( abs(atan) <= AI_TURNRAD ){
251+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
252+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
253+ rx -= atan;
254+ }
255+
256+ //前進する
257+ if( zombie == true ){
258+ if( abs(atan) < (float)M_PI/18*2 ){
259+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
260+ }
261+ }
262+ else if( battlemode == AI_CAUTION ){
263+ if( abs(atan) < (float)M_PI/18*5 ){
264+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
265+ }
266+ }
267+ else if( movemode == AI_WALK ){
268+ if( abs(atan) < (float)M_PI/180*6 ){
269+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
270+ }
271+ }
272+ else if( (movemode == AI_RUN)||(movemode == AI_RUN2) ){
273+ if( abs(atan) < (float)M_PI/18*5 ){
274+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
275+ }
276+ }
277+ else if( (movemode == AI_WAIT)||(movemode == AI_STOP) ){
278+ if( abs(atan) < (float)M_PI/180*6 ){
279+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
280+ }
281+ }
282+ else{ //movemode == AI_TRACKING
283+ if( abs(atan) < (float)M_PI/18*2 ){
284+ if( r < (AI_ARRIVALDIST_WALKTRACKING * AI_ARRIVALDIST_WALKTRACKING) ){
285+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
286+ }
287+ else{
288+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
289+ }
290+ }
291+ }
292+
293+ //ジャンプ
294+ if( random(16) == 0 ){
295+ MoveJump();
296+ }
297+
298+ //引っ掛かっていたら、左右への回転をランダムに行う
299+ if( random(28) == 0 ){
300+ if( ctrlhuman->GetMovemode(true) != 0 ){
301+ if( ctrlhuman->GetTotalMove() - total_move < 0.1f ){
302+ if( random(2) == 0 ){ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); }
303+ else{ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); }
304+ }
305+ }
306+ }
307+ total_move = ctrlhuman->GetTotalMove();
308+}
309+
310+//! @brief 目標地点に移動(優先的な走り用)
311+void AIcontrol::MoveTarget2()
312+{
313+ float atan;
314+
315+ //目標地点への角度を求める
316+ CheckTargetAngle(posx, 0.0f, posz, rx*-1 + (float)M_PI/2, 0.0f, target_posx, 0.0f, target_posz, 0.0f, &atan, NULL, NULL);
317+
318+ //前後移動の処理
319+ if( abs(atan) < (float)M_PI/180*56 ){
320+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
321+ }
322+ if( abs(atan) > (float)M_PI/180*123.5f ){
323+ SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
324+ }
325+
326+ //左右移動の処理
327+ if( ((float)M_PI/180*-146 < atan)&&(atan < (float)M_PI/180*-33) ){
328+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
329+ }
330+ if( ((float)M_PI/180*33 < atan)&&(atan < (float)M_PI/180*146) ){
331+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
332+ }
333+
334+ //ジャンプ
335+ if( random(16) == 0 ){
336+ MoveJump();
337+ }
338+
339+ //引っ掛かっていたら、左右への回転をランダムに行う
340+ if( random(28) == 0 ){
341+ if( ctrlhuman->GetMovemode(true) != 0 ){
342+ if( ctrlhuman->GetTotalMove() - total_move < 0.1f ){
343+ if( random(2) == 0 ){ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT); }
344+ else{ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT); }
345+ }
346+ }
347+ }
348+ total_move = ctrlhuman->GetTotalMove();
349+}
350+
351+//! @brief 前後左右ランダムに移動(攻撃中用)
352+void AIcontrol::MoveRandom()
353+{
354+ int forwardstart, backstart, sidestart;
355+
356+ if( longattack == false ){
357+ forwardstart = 80;
358+ backstart = 90;
359+ sidestart = 70;
360+ }
361+ else{
362+ forwardstart = 120;
363+ backstart = 150;
364+ sidestart = 130;
365+ }
366+
367+ //ランダムに移動を始める
368+ if( random(forwardstart) == 0 ){
369+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
370+ }
371+ if( random(backstart) == 0 ){
372+ SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
373+ }
374+ if( random(sidestart) == 0 ){
375+ SetFlag(moveturn_mode, AI_CTRL_MOVELEFT);
376+ }
377+ if( random(sidestart) == 0 ){
378+ SetFlag(moveturn_mode, AI_CTRL_MOVERIGHT);
379+ }
380+
381+ // 1/3の確率か、移動フラグが設定されていたら
382+ if( (random(3) == 0)||(GetFlag(moveturn_mode, (AI_CTRL_MOVEFORWARD | AI_CTRL_MOVEBACKWARD | AI_CTRL_MOVELEFT | AI_CTRL_MOVERIGHT))) ){
383+ float vx, vz;
384+ float Dist;
385+
386+ if( random(2) == 0 ){
387+ //前方向のベクトルを計算
388+ vx = cos(rx*-1 + (float)M_PI/2);
389+ vz = sin(rx*-1 + (float)M_PI/2);
390+ if(
391+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる)
392+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる)
393+ ){
394+ //前進フラグを削除し、後退フラグを設定
395+ DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
396+ SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
397+ }
398+
399+ //後方向のベクトルを計算
400+ vx = cos(rx*-1 + (float)M_PI/2 + (float)M_PI);
401+ vz = sin(rx*-1 + (float)M_PI/2 + (float)M_PI);
402+ if(
403+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる)
404+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる)
405+ ){
406+ //後退フラグを削除し、前進フラグを設定
407+ DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
408+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
409+ }
410+ }
411+ else{
412+ //
413+ vx = cos(rx*-1);
414+ vz = sin(rx*-1);
415+ if(
416+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる)
417+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる)
418+ ){
419+ //右移動フラグを削除し、左移動フラグを設定
420+ DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT);
421+ SetFlag(moveturn_mode, AI_CTRL_MOVELEFT);
422+ }
423+
424+ vx = cos(rx*-1 + (float)M_PI);
425+ vz = sin(rx*-1 + (float)M_PI);
426+ if(
427+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy + HUMAN_MAPCOLLISION_HEIGTH, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == true)|| //腰の高さにブロックがある(ぶつかる)
428+ (CollD->CheckALLBlockIntersectDummyRay(posx, posy - 5.0f, posz, vx, 0, vz, NULL, NULL, &Dist, HUMAN_MAPCOLLISION_R) == false) //足元にブロックがない(落ちる)
429+ ){
430+ //左移動フラグを削除し、右移動フラグを設定
431+ DelFlag(moveturn_mode, AI_CTRL_MOVELEFT);
432+ SetFlag(moveturn_mode, AI_CTRL_MOVERIGHT);
433+ }
434+ }
435+ }
436+
437+ //攻撃対象がいるなら
438+ if( enemyhuman != NULL ){
439+ float tx, ty, tz;
440+
441+ enemyhuman->GetPosData(&tx, &ty, &tz, NULL);
442+
443+ float x = posx - tx;
444+ float y = posy - ty;
445+ float z = posz - tz;
446+ float r = x * x + y * y + z * z;
447+
448+ //敵に近づきすぎたなら後退する
449+ if( r < 20.0f * 20.0f ){
450+ DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
451+ if( random(70) == 0 ){
452+ SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
453+ }
454+ }
455+ }
456+}
457+
458+//! @brief その場を見まわす
459+void AIcontrol::TurnSeen()
460+{
461+ int turnstart, turnstop;
462+
463+ //回転の開始・終了確率を設定
464+ if( battlemode == AI_ACTION ){
465+ return;
466+ }
467+ else if( battlemode == AI_CAUTION ){
468+ turnstart = 20;
469+ turnstop = 20;
470+ }
471+ else{
472+ if( movemode == AI_TRACKING ){ turnstart = 65; }
473+ else{ turnstart = 85; }
474+ turnstop = 18;
475+ }
476+
477+ //ランダムに回転を始める
478+ if( random(turnstart) == 0 ){
479+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
480+ }
481+ if( random(turnstart) == 0 ){
482+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
483+ }
484+
485+ if( (battlemode == AI_NORMAL)&&(movemode == AI_WAIT) ){
486+ //ランダムにポイントの方を向こうとする
487+ //「ポイントの方向を少し重視する」の再現
488+ if( random(80) == 0 ){
489+ float tr;
490+ tr = target_rx - rx;
491+ for(; tr > (float)M_PI; tr -= (float)M_PI*2){}
492+ for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){}
493+
494+ if( tr > 0.0f ){
495+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
496+ }
497+ if( tr < 0.0f ){
498+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
499+ }
500+ }
501+ }
502+
503+ //回転をランダムに止める
504+ if( random(turnstop) == 0 ){
505+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
506+ }
507+ if( random(turnstop) == 0 ){
508+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
509+ }
510+}
511+
512+//! @brief 特定の方向を見続ける
513+bool AIcontrol::StopSeen()
514+{
515+ float tr;
516+ bool returnflag = false;
517+
518+ tr = target_rx - rx;
519+ for(; tr > (float)M_PI; tr -= (float)M_PI*2){}
520+ for(; tr < (float)M_PI*-1; tr += (float)M_PI*2){}
521+
522+ //大きな差があれば少しづつ旋回するだけ
523+ if( tr > AI_TURNRAD ){
524+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
525+ returnflag = false;
526+ }
527+ if( tr < AI_TURNRAD*-1 ){
528+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
529+ returnflag = false;
530+ }
531+
532+ //微々たる差なら一気に向ける。
533+ if( abs(tr) <= AI_TURNRAD ){
534+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
535+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
536+ rx += tr;
537+ returnflag = true;
538+ }
539+
540+ return returnflag;
541+}
542+
543+//! @brief 進行方向に障害物があればジャンプする
544+bool AIcontrol::MoveJump()
545+{
546+ //立ち止まっていれば処理しない
547+ if( ctrlhuman->GetMovemode(false) == 0 ){ return false; }
548+
549+ float dist_dummy;
550+
551+ float new_posx, new_posy, new_posz;
552+
553+ //腰付近のあたり判定
554+ new_posx = posx + cos(rx*-1 + (float)M_PI/2) * (AI_CHECKJUMP_DIST + HUMAN_MAPCOLLISION_R);
555+ new_posy = posy + HUMAN_MAPCOLLISION_HEIGTH;
556+ new_posz = posz + sin(rx*-1 + (float)M_PI/2) * (AI_CHECKJUMP_DIST + HUMAN_MAPCOLLISION_R);
557+ if( CollD->CheckALLBlockInside(new_posx, new_posy, new_posz) == true ){
558+ ObjMgr->MoveJump(ctrlid);
559+ return true;
560+ }
561+
562+ //体全体のあたり判定
563+ new_posx = posx + cos(rx*-1 + (float)M_PI/2) * AI_CHECKJUMP_DIST;
564+ new_posy = posy + AI_CHECKJUMP_HEIGHT;
565+ new_posz = posz + sin(rx*-1 + (float)M_PI/2) * AI_CHECKJUMP_DIST;
566+ if( CollD->CheckALLBlockInside(new_posx, new_posy, new_posz) == true ){
567+ ObjMgr->MoveJump(ctrlid);
568+ return true;
569+ }
570+ 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 ){
571+ ObjMgr->MoveJump(ctrlid);
572+ return true;
573+ }
574+
575+ return false;
576+}
577+
578+//! @brief 攻撃
579+//! @todo ゾンビの相手を捕まえる処理
580+void AIcontrol::Action()
581+{
582+ human* EnemyHuman = NULL;
583+ int paramid;
584+ HumanParameter Paraminfo;
585+ bool zombie;
586+ float posy2;
587+ float tx, ty, tz;
588+
589+ EnemyHuman = enemyhuman;
590+
591+ //座標を取得
592+ EnemyHuman->GetPosData(&tx, &ty, &tz, NULL);
593+ posy2 = posy + VIEW_HEIGHT;
594+ ty += VIEW_HEIGHT;
595+
596+ //ゾンビかどうか判定
597+ ctrlhuman->GetParamData(&paramid, NULL, NULL, NULL);
598+ Param->GetHuman(paramid, &Paraminfo);
599+ if( Paraminfo.type == 2 ){
600+ zombie = true;
601+ }
602+ else{
603+ zombie = false;
604+ }
605+
606+ //所持している武器の種類を取得
607+ int weaponid = ctrlhuman->GetMainWeaponTypeNO();
608+
609+ float atanx, atany, r;
610+
611+ //自分が手榴弾を持っていれば〜
612+ if( weaponid == ID_WEAPON_GRENADE ){
613+ if( zombie == false ){
614+ float x = posx - tx;
615+ float z = posz - tz;
616+ float r = x * x + z * z;
617+ float scale;
618+ if( longattack == false ){ scale = 0.12f; }
619+ else{ scale = 0.4f; }
620+
621+ //距離に応じて高さを変える
622+ ty += (sqrt(r) - 200.0f) * scale;
623+ }
624+ }
625+ else{
626+ float mx, mz;
627+ float scale;
628+ EnemyHuman->GetMovePos(&mx, NULL, &mz);
629+ if( longattack == false ){ scale = 1.5f; }
630+ else{ scale = 0.12f; }
631+
632+ //敵の移動を見超す
633+ tx += mx * scale;
634+ tz += mz * scale;
635+ }
636+
637+ //目標地点への角度を求める
638+ CheckTargetAngle(posx, posy2, posz, rx*-1 + (float)M_PI/2, ry, tx, ty, tz, 0.0f, &atanx, &atany, &r);
639+
640+ //大きな差があれば少しづつ旋回するだけ
641+ if( atanx > AI_TURNRAD ){
642+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
643+ }
644+ if( atanx < AI_TURNRAD*-1 ){
645+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
646+ }
647+
648+ //微々たる差なら一気に向ける
649+ if( abs(atanx) <= AI_TURNRAD ){
650+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
651+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
652+ rx -= atanx;
653+ rx += (float)M_PI/180 * (random(5) - 2);
654+ }
655+
656+ //腕の角度
657+ if( zombie == true ){
658+ //ry = 0.0f;
659+
660+ //大きな差があれば少しづつ旋回するだけ
661+ if( ry < AI_TURNRAD*-1 ){
662+ SetFlag(moveturn_mode, AI_CTRL_TURNUP);
663+ }
664+ if( ry > AI_TURNRAD ){
665+ SetFlag(moveturn_mode, AI_CTRL_TURNDOWN);
666+ }
667+
668+ //微々たる差なら一気に向ける
669+ if( abs(ry) <= AI_TURNRAD ){
670+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
671+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
672+ ry = 0.0f;
673+ }
674+ }
675+ else{
676+ float addry;
677+
678+ //自分が手ぶらならば〜
679+ if( weaponid == ID_WEAPON_NONE ){
680+ if( EnemyHuman->GetMainWeaponTypeNO() == ID_WEAPON_NONE ){ //敵も手ぶらならば〜
681+ addry = ARMRAD_NOWEAPON - ry;
682+ }
683+ else{ //敵が武器を持っていれば〜
684+ addry = (float)M_PI/18*8 - ry;
685+ }
686+ }
687+ else{
688+ addry = atany;
689+ }
690+
691+ //大きな差があれば少しづつ旋回するだけ
692+ if( addry > AI_TURNRAD ){
693+ SetFlag(moveturn_mode, AI_CTRL_TURNUP);
694+ }
695+ if( addry < AI_TURNRAD*-1 ){
696+ SetFlag(moveturn_mode, AI_CTRL_TURNDOWN);
697+ }
698+
699+ //微々たる差なら一気に向ける
700+ if( abs(addry) <= AI_TURNRAD ){
701+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
702+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
703+ ry += addry;
704+ ry += (float)M_PI/180 * (random(5) - 2);
705+ }
706+ }
707+
708+ //ゾンビ以外で手ぶらならば
709+ if( zombie == false ){
710+ if( weaponid == ID_WEAPON_NONE ){
711+ //一定の確率で後退する
712+ if( random(80) == 0 ){
713+ SetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
714+ }
715+ }
716+ }
717+
718+
719+ if( zombie == true ){ //ゾンビの攻撃
720+ float y = posy2 - ty;
721+
722+ //もし走っていれば、一度歩きに切り替える
723+ if( GetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD) ){
724+ DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
725+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
726+ }
727+
728+ //敵に向かって前進する
729+ if( abs(atanx) <= (float)M_PI/180*25 ){
730+ if( (abs(atanx) <= (float)M_PI/180*15) && (r < 24.0f*24.0f) && (actioncnt%50 > 20) ){
731+ //歩きを取り消し、走る
732+ SetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
733+ DelFlag(moveturn_mode, AI_CTRL_MOVEWALK);
734+ }
735+ else{
736+ SetFlag(moveturn_mode, AI_CTRL_MOVEWALK);
737+ }
738+ }
739+
740+ /*
741+ //ジャンプ
742+ if( random(16) == 0 ){
743+ MoveJump();
744+ }
745+ */
746+
747+ if( (r < 9.0f*9.0f)&&( abs(y) < 10.0f) ){
748+ float x = posx - tx;
749+ float z = posz - tz;
750+
751+ //捕まえる (敵を引き付ける)
752+ EnemyHuman->AddPosOrder(atan2(z, x), 0.0f, 0.5f);
753+
754+ //敵の視点をランダムに動かす
755+ float erx, ery;
756+ EnemyHuman->GetRxRy(&erx, &ery);
757+ switch(random(3)){
758+ case 0: erx -= (float)M_PI/180*2; break;
759+ case 1: erx += (float)M_PI/180*2; break;
760+ default: break;
761+ }
762+ switch(random(3)){
763+ case 0: ery -= (float)M_PI/180*2; break;
764+ case 1: ery += (float)M_PI/180*2; break;
765+ default: break;
766+ }
767+ EnemyHuman->SetRxRy(erx, ery);
768+ }
769+
770+ if( actioncnt%50 == 0){
771+ if( ObjMgr->CheckZombieAttack(ctrlhuman, EnemyHuman) == true ){
772+ ObjMgr->HitZombieAttack(EnemyHuman);
773+ }
774+ }
775+ }
776+ else{ //発砲する
777+ float ShotAngle;
778+ if( longattack == false ){
779+ //敵を捉えたと判定する、許容誤差を計算する
780+ ShotAngle = (float)M_PI/180*8;
781+ if( weaponid != ID_WEAPON_NONE ){
782+ WeaponParameter wparam;
783+ Param->GetWeapon(weaponid, &wparam);
784+ if( wparam.scopemode == 1 ){
785+ ShotAngle = (float)M_PI/180*6;
786+ }
787+ if( wparam.scopemode == 2 ){
788+ ShotAngle = (float)M_PI/180*4;
789+ }
790+ }
791+
792+ //AIレベルごとに調整
793+ ShotAngle += (float)M_PI/180*0.5f * LevelParam->limitserror;
794+
795+ if( movemode == AI_RUN2 ){
796+ ShotAngle *= 1.5f;
797+ }
798+ }
799+ else{
800+ //敵を捉えたと判定する、許容誤差を計算する
801+ ShotAngle = (float)M_PI/180*4;
802+ if( weaponid != ID_WEAPON_NONE ){
803+ WeaponParameter wparam;
804+ Param->GetWeapon(weaponid, &wparam);
805+ if( wparam.scopemode == 1 ){
806+ ShotAngle = (float)M_PI/180*3;
807+ }
808+ if( wparam.scopemode == 2 ){
809+ ShotAngle = (float)M_PI/180*2;
810+ }
811+ }
812+
813+ //AIレベルごとに調整
814+ ShotAngle += (float)M_PI/180*0.2f * LevelParam->limitserror;
815+ }
816+
817+ //敵を捉えていれば
818+ float atanxy = atanx + atany;
819+ if( atanxy < ShotAngle ){
820+ int rand = LevelParam->attack;
821+ if( longattack == true ){ rand += 1; }
822+
823+ //発砲
824+ if( random(rand) == 0 ){
825+ ObjMgr->ShotWeapon(ctrlid);
826+ }
827+ }
828+ }
829+
830+ //距離に応じて近距離・遠距離を切り替える
831+ // 200.0fピッタリで設定値維持
832+ if( r < 200.0f * 200.0f ){
833+ longattack = false;
834+ }
835+ if( (r > 200.0f * 200.0f)&&(movemode != AI_RUN2) ){
836+ longattack = true;
837+ }
838+
839+ if( zombie == false ){
840+ //ランダムに移動
841+ MoveRandom();
842+ }
843+
844+ actioncnt += 1;
845+}
846+
847+//! @brief 攻撃をキャンセル
848+bool AIcontrol::ActionCancel()
849+{
850+ //非戦闘化フラグが有効なら終了
851+ if( NoFight == true ){
852+ return true;
853+ }
854+
855+ //敵が死亡したら終了
856+ if( enemyhuman->GetDeadFlag() == true ){
857+ return true;
858+ }
859+
860+ //距離を取得
861+ float tx, ty, tz;
862+ enemyhuman->GetPosData(&tx, &ty, &tz, NULL);
863+ float x = posx - tx;
864+ float y = posy - ty;
865+ float z = posz - tz;
866+ float r = x*x + y*y + z*z;
867+
868+ //距離が離れ過ぎていたら終了
869+ if( r > 620.0f*620.0f ){
870+ return true;
871+ }
872+
873+ if( longattack == false ){
874+ //適当なタイミングで敵が見えるか確認
875+ if( random(40) == 0 ){
876+ //ブロックが遮っていた(=見えない)ならば終了
877+ if( CheckLookEnemy(enemyhuman, AI_SEARCH_RX, AI_SEARCH_RY, 620.0f, NULL) == false ){
878+ return true;
879+ }
880+ }
881+
882+ //強制的に終了
883+ if( random(550) == 0 ){
884+ return true;
885+ }
886+ }
887+ else{
888+ //適当なタイミングで敵が見えるか確認
889+ if( random(30) == 0 ){
890+ //ブロックが遮っていた(=見えない)ならば終了
891+ if( CheckLookEnemy(enemyhuman, AI_SEARCH_RX, AI_SEARCH_RY, 620.0f, NULL) == false ){
892+ return true;
893+ }
894+ }
895+
896+ //強制的に終了
897+ if( random(450) == 0 ){
898+ return true;
899+ }
900+ }
901+
902+ return false;
903+}
904+
905+//! @brief 武器を持つ
906+int AIcontrol::HaveWeapon()
907+{
908+ int selectweapon;
909+ class weapon *weapon[TOTAL_HAVEWEAPON];
910+ int weaponid;
911+
912+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
913+ weapon[i] = NULL;
914+ }
915+
916+ //武器の情報を取得
917+ ctrlhuman->GetWeapon(&selectweapon, weapon);
918+
919+ //武器を持っていれば、武器番号を取得
920+ if( weapon[selectweapon] != NULL ){
921+ weapon[selectweapon]->GetParamData(&weaponid, NULL, NULL);
922+ }
923+
924+ //武器を持っていないか、「ケース」ならば
925+ if( (weapon[selectweapon] == NULL)||(weaponid == ID_WEAPON_CASE) ){
926+ //次の武器を指定
927+ int notselectweapon = selectweapon + 1;
928+ if( notselectweapon == TOTAL_HAVEWEAPON ){ notselectweapon = 0; }
929+
930+ //持ち替える
931+ if( weapon[notselectweapon] != NULL ){
932+ ObjMgr->ChangeWeapon(ctrlid);
933+ return 1;
934+ }
935+ }
936+
937+ return 0;
938+}
939+
940+//! @brief 移動や方向転換をランダムに終了
941+void AIcontrol::CancelMoveTurn()
942+{
943+ int forward, back, side, updown, rightleft;
944+
945+ if( battlemode == AI_ACTION ){ //攻撃中
946+ if( movemode == AI_RUN2 ){ //優先的な走り
947+ DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
948+ DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
949+ DelFlag(moveturn_mode, AI_CTRL_MOVELEFT);
950+ DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT);
951+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
952+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
953+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
954+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
955+ if( random(3) == 0 ){
956+ DelFlag(moveturn_mode, AI_CTRL_MOVEWALK);
957+ }
958+ return;
959+ }
960+ else{ //優先的な走り 以外
961+ if( longattack == false ){
962+ forward = 6;
963+ back = 6;
964+ side = 7;
965+ updown = 5;
966+ rightleft = 6;
967+ }
968+ else{
969+ forward = 5;
970+ back = 4;
971+ side = 5;
972+ updown = 3;
973+ rightleft = 3;
974+ }
975+ }
976+ }
977+ else if( battlemode == AI_CAUTION ){ //警戒中
978+ forward = 10;
979+ back = 10;
980+ side = 10;
981+ updown = 14;
982+ rightleft = 20;
983+ }
984+ else{
985+ forward = 12;
986+ back = 12;
987+ side = 12;
988+ updown = 15;
989+ rightleft = 18;
990+ }
991+
992+ //移動をランダムに止める
993+ if( random(forward) == 0 ){
994+ DelFlag(moveturn_mode, AI_CTRL_MOVEFORWARD);
995+ }
996+ if( random(back) == 0 ){
997+ DelFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD);
998+ }
999+ if( random(side) == 0 ){
1000+ DelFlag(moveturn_mode, AI_CTRL_MOVELEFT);
1001+ }
1002+ if( random(side) == 0 ){
1003+ DelFlag(moveturn_mode, AI_CTRL_MOVERIGHT);
1004+ }
1005+ if( random(3) == 0 ){
1006+ DelFlag(moveturn_mode, AI_CTRL_MOVEWALK);
1007+ }
1008+
1009+ //回転をランダムに止める
1010+ if( random(updown) == 0 ){
1011+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
1012+ }
1013+ if( random(updown) == 0 ){
1014+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
1015+ }
1016+ if( random(rightleft) == 0 ){
1017+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
1018+ }
1019+ if( random(rightleft) == 0 ){
1020+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
1021+ }
1022+}
1023+
1024+//! @brief 移動や方向転換を実行
1025+void AIcontrol::ControlMoveTurn()
1026+{
1027+ //移動の実行
1028+ if( GetFlag(moveturn_mode, AI_CTRL_MOVEFORWARD) ){
1029+ ObjMgr->MoveForward(ctrlid);
1030+ }
1031+ if( GetFlag(moveturn_mode, AI_CTRL_MOVEBACKWARD) ){
1032+ ObjMgr->MoveBack(ctrlid);
1033+ }
1034+ if( GetFlag(moveturn_mode, AI_CTRL_MOVELEFT) ){
1035+ ObjMgr->MoveLeft(ctrlid);
1036+ }
1037+ if( GetFlag(moveturn_mode, AI_CTRL_MOVERIGHT) ){
1038+ ObjMgr->MoveRight(ctrlid);
1039+ }
1040+ if( GetFlag(moveturn_mode, AI_CTRL_MOVEWALK) ){
1041+ ObjMgr->MoveWalk(ctrlid);
1042+ }
1043+
1044+ //方向転換の実行
1045+ if( GetFlag(moveturn_mode, AI_CTRL_TURNUP) ){
1046+ ry += AI_TURNRAD;
1047+ }
1048+ if( GetFlag(moveturn_mode, AI_CTRL_TURNDOWN) ){
1049+ ry -= AI_TURNRAD;
1050+ }
1051+ if( GetFlag(moveturn_mode, AI_CTRL_TURNLEFT) ){
1052+ rx -= AI_TURNRAD;
1053+ }
1054+ if( GetFlag(moveturn_mode, AI_CTRL_TURNRIGHT) ){
1055+ rx += AI_TURNRAD;
1056+ }
1057+}
1058+
1059+//! @brief 武器をリロード・捨てる
1060+//! @return 捨てる:1 リロード:2 持ち替える:3 FULL/SEMI切り替え:4 何もしない:0
1061+int AIcontrol::ControlWeapon()
1062+{
1063+ int selectweapon;
1064+ class weapon *weapon[TOTAL_HAVEWEAPON];
1065+ int weaponid, lnbs, nbs;
1066+ WeaponParameter paramdata;
1067+ bool blazingmodeS, blazingmodeN;
1068+
1069+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1070+ weapon[i] = NULL;
1071+ }
1072+
1073+ //武器の情報を取得
1074+ ctrlhuman->GetWeapon(&selectweapon, weapon);
1075+ if( weapon[selectweapon] == NULL ){ return 0; }
1076+ weapon[selectweapon]->GetParamData(&weaponid, &lnbs, &nbs);
1077+
1078+ //武器の性能を取得
1079+ if( Param->GetWeapon(weaponid, &paramdata) == 1 ){ return 0; }
1080+
1081+ //スコープ解除
1082+ ctrlhuman->SetDisableScope();
1083+
1084+ //「ケース」なら何もしない
1085+ if( weaponid == ID_WEAPON_CASE ){ return 0; }
1086+
1087+ //戦闘中にグレネードを持っていれば
1088+ if( battlemode == AI_ACTION ){
1089+ if( weaponid == ID_WEAPON_GRENADE ){
1090+ int nextselectweapon, nextnds;
1091+
1092+ //次の武器の弾数を取得
1093+ nextselectweapon = selectweapon + 1;
1094+ nextnds = 0;
1095+ if( nextselectweapon == TOTAL_HAVEWEAPON ){
1096+ nextselectweapon = 0;
1097+ }
1098+ if( weapon[nextselectweapon] != NULL ){
1099+ weapon[nextselectweapon]->GetParamData(NULL, NULL, &nextnds);
1100+ }
1101+
1102+ if( longattack == false ){
1103+ // 1/100の確率で持ち替える
1104+ if( (random(100) == 0)&&(nextnds > 0) ){
1105+ ObjMgr->ChangeWeapon(ctrlid);
1106+ return 3;
1107+ }
1108+ }
1109+ else{
1110+ // 1/66の確率で持ち替える
1111+ if( (random(66) == 0)&&(nextnds > 0) ){
1112+ ObjMgr->ChangeWeapon(ctrlid);
1113+ return 3;
1114+ }
1115+ }
1116+ }
1117+ }
1118+
1119+ //残弾数が無ければ
1120+ if( lnbs == 0 ){
1121+ int ways;
1122+
1123+ //処理確率決定
1124+ if( battlemode == AI_NORMAL ){ ways = 1; }
1125+ else if( battlemode == AI_CAUTION ){ ways = 10; }
1126+ else{ ways = 8; }
1127+
1128+ // 1/waysの確率で処理
1129+ if( random(ways) == 0 ){
1130+ int under;
1131+
1132+ //リロード確率
1133+ if( battlemode == AI_NORMAL ){
1134+ ways = 1;
1135+ under = 0;
1136+ }
1137+ else if( battlemode == AI_CAUTION ){
1138+ ways = 5;
1139+ under = 3;
1140+ }
1141+ else{
1142+ if( longattack == false ){
1143+ // 確率は 3/4
1144+ ways = 4;
1145+ under = 2;
1146+ }
1147+ else{
1148+ // 確率は 2/3
1149+ ways = 3;
1150+ under = 1;
1151+ }
1152+ }
1153+
1154+ //弾が無ければ捨てる
1155+ if( nbs == 0 ){
1156+ ObjMgr->DumpWeapon(ctrlid);
1157+ return 1;
1158+ }
1159+
1160+ //ランダムに リロード実行 or 武器を持ちかえ
1161+ if( random(ways) <= under ){
1162+ ObjMgr->ReloadWeapon(ctrlid);
1163+ return 2;
1164+ }
1165+ //else{
1166+ ObjMgr->ChangeWeapon(ctrlid);
1167+ return 3;
1168+ //}
1169+ }
1170+ }
1171+
1172+ //連射切り替えが可能な武器なら
1173+ if( paramdata.ChangeWeapon != -1 ){
1174+ //現在の武器の連射設定を取得
1175+ blazingmodeS = paramdata.blazingmode;
1176+
1177+ //新たな武器の連射設定を取得
1178+ if( Param->GetWeapon(paramdata.ChangeWeapon, &paramdata) == 1 ){ return 0; }
1179+ blazingmodeN = paramdata.blazingmode;
1180+
1181+ if( longattack == false ){
1182+ //近距離攻撃中で、現在SEMI・切り替えるとFULLになるなら
1183+ if( (blazingmodeS == false)||(blazingmodeN == true) ){
1184+ ObjMgr->ChangeShotMode(ctrlid); //切り替える
1185+ return 4;
1186+ }
1187+ }
1188+ else{
1189+ //遠距離攻撃中で、現在FULL・切り替えるとSEMIになるなら
1190+ if( (blazingmodeS == true)||(blazingmodeN == false) ){
1191+ ObjMgr->ChangeShotMode(ctrlid); //切り替える
1192+ return 4;
1193+ }
1194+ }
1195+ }
1196+
1197+ return 0;
1198+}
1199+
1200+//! @brief 手榴弾を投げる
1201+//! @return 処理中:0 投げ終わった:1 手榴弾を持っていない:2
1202+int AIcontrol::ThrowGrenade()
1203+{
1204+ int selectweapon;
1205+ class weapon *weapon[TOTAL_HAVEWEAPON];
1206+ int weaponid, nbs, i;
1207+
1208+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1209+ weapon[i] = NULL;
1210+ }
1211+
1212+ //手榴弾を持っているか確認
1213+ ctrlhuman->GetWeapon(&selectweapon, weapon);
1214+ for(i=0; i<TOTAL_HAVEWEAPON; i++){
1215+ if( weapon[i] != NULL ){
1216+ weapon[i]->GetParamData(&weaponid, NULL, &nbs);
1217+ if( weaponid == ID_WEAPON_GRENADE ){
1218+ break;
1219+ }
1220+ }
1221+ }
1222+ if( i == TOTAL_HAVEWEAPON ){
1223+ return 2;
1224+ }
1225+
1226+ //手榴弾を持っていなければ、切り替える
1227+ if( i != selectweapon ){
1228+ ObjMgr->ChangeWeapon(ctrlid, i);
1229+ }
1230+
1231+ pointdata pdata;
1232+ float posy2;
1233+ float atan_rx, atan_ry;
1234+
1235+ //パスと人の高さを取得
1236+ Points->Getdata(&pdata, target_pointid);
1237+ posy2 = posy + VIEW_HEIGHT;
1238+
1239+ //目標地点への角度を求める
1240+ CheckTargetAngle(posx, pdata.y, posz, rx*-1 + (float)M_PI/2, ry, target_posx, posy2, target_posz, 0.0f, &atan_rx, &atan_ry, NULL);
1241+
1242+ //大きな差があれば少しづつ旋回するだけ
1243+ if( atan_rx > AI_TURNRAD ){
1244+ SetFlag(moveturn_mode, AI_CTRL_TURNLEFT);
1245+ }
1246+ if( atan_rx < AI_TURNRAD*-1 ){
1247+ SetFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
1248+ }
1249+ if( atan_ry > AI_TURNRAD ){
1250+ SetFlag(moveturn_mode, AI_CTRL_TURNUP);
1251+ }
1252+ if( atan_ry < AI_TURNRAD*-1 ){
1253+ SetFlag(moveturn_mode, AI_CTRL_TURNDOWN);
1254+ }
1255+
1256+ //微々たる差なら一気に向ける
1257+ if( abs(atan_rx) <= AI_TURNRAD ){
1258+ DelFlag(moveturn_mode, AI_CTRL_TURNRIGHT);
1259+ DelFlag(moveturn_mode, AI_CTRL_TURNLEFT);
1260+ rx += atan_rx;
1261+ }
1262+ if( abs(atan_ry) <= AI_TURNRAD ){
1263+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
1264+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
1265+ ry += atan_ry;
1266+ }
1267+
1268+ //投げる
1269+ if( (abs(atan_rx) < (float)M_PI/1800*15)&&(abs(atan_ry) < (float)M_PI/1800*15) ){
1270+ //角度を設定
1271+ ctrlhuman->SetRxRy(rx, ry);
1272+
1273+ if( ObjMgr->ShotWeapon(ctrlid) != 0 ){
1274+ return 1;
1275+ }
1276+ }
1277+
1278+ return 0;
1279+}
1280+
1281+//! @brief 腕の角度を設定
1282+void AIcontrol::ArmAngle()
1283+{
1284+ float addry;
1285+
1286+ if( ctrlhuman->GetMainWeaponTypeNO() == ID_WEAPON_NONE ){ //手ぶら
1287+ addry = ARMRAD_NOWEAPON - ry;
1288+ }
1289+ else if( (battlemode == AI_CAUTION)&&(cautioncnt > 0) ){ //警戒中
1290+ addry = 0.0f - ry;
1291+ }
1292+ else{ //平常時で武器所有中
1293+ addry = AI_WEAPON_ARMRAD - ry;
1294+ }
1295+
1296+ //大きな差があれば少しづつ旋回するだけ
1297+ if( addry > AI_TURNRAD ){
1298+ SetFlag(moveturn_mode, AI_CTRL_TURNUP);
1299+ }
1300+ if( addry < AI_TURNRAD*-1 ){
1301+ SetFlag(moveturn_mode, AI_CTRL_TURNDOWN);
1302+ }
1303+
1304+ //微々たる差なら一気に向ける
1305+ if( abs(addry) <= AI_TURNRAD ){
1306+ DelFlag(moveturn_mode, AI_CTRL_TURNUP);
1307+ DelFlag(moveturn_mode, AI_CTRL_TURNDOWN);
1308+ ry += addry;
1309+ }
1310+}
1311+
1312+//! @brief 敵を探す
1313+int AIcontrol::SearchEnemy()
1314+{
1315+ //非戦闘化フラグが有効なら敵を見つけない
1316+ if( NoFight == true ){
1317+ return 0;
1318+ }
1319+
1320+ if( battlemode == AI_ACTION ){ return 0; }
1321+
1322+ int weaponid = ctrlhuman->GetMainWeaponTypeNO();
1323+ int weaponscope = 0;
1324+ int searchloops;
1325+ float maxDist;
1326+ float A_rx, A_ry, B_rx, B_ry;
1327+
1328+ //武器を持っていれば、スコープモードを取得
1329+ if( weaponid != ID_WEAPON_NONE ){
1330+ WeaponParameter Wparam;
1331+
1332+ Param->GetWeapon(weaponid, &Wparam);
1333+ weaponscope = Wparam.scopemode;
1334+ }
1335+
1336+ //敵の探索回数と探索範囲(距離と角度)を設定
1337+ if( battlemode == AI_NORMAL ){
1338+ searchloops = (LevelParam->search) * 4;
1339+
1340+ if( weaponscope == 2 ){ maxDist = 50.0f; }
1341+ if( weaponscope == 1 ){ maxDist = 25.0f; }
1342+ else{ maxDist = 0.0f; }
1343+ maxDist += 12.0f*((LevelParam->search)-2) + 350.0f;
1344+ A_rx = (float)M_PI/180*60;
1345+ A_ry = (float)M_PI/180*110;
1346+ B_rx = (float)M_PI/180*40;
1347+ B_ry = (float)M_PI/180*60;
1348+ }
1349+ else { //battlemode == AI_CAUTION
1350+ searchloops = (LevelParam->search) * 5;
1351+
1352+ if( weaponscope == 2 ){ maxDist = 80.0f; }
1353+ if( weaponscope == 1 ){ maxDist = 40.0f; }
1354+ else{ maxDist = 0.0f; }
1355+ maxDist += 15.0f*((LevelParam->search)-2) + 420.0f;
1356+ A_rx = (float)M_PI/180*80;
1357+ A_ry = (float)M_PI/180*130;
1358+ B_rx = (float)M_PI/180*50;
1359+ B_ry = (float)M_PI/180*80;
1360+ }
1361+
1362+ //指定回数、敵を探索
1363+ for(int i=0; i<searchloops; i++){
1364+ int targetid = random(MAX_HUMAN);
1365+
1366+ if( CheckLookEnemy(targetid, A_rx, A_ry, 200.0f, NULL) == true ){
1367+ longattack = false;
1368+ return 1;
1369+ }
1370+
1371+ if( CheckLookEnemy(targetid, B_rx, B_ry, maxDist, NULL) == true ){
1372+ if( random(4) == 0 ){
1373+ if( movemode == AI_RUN2 ){ longattack = false; }
1374+ else{ longattack = true; }
1375+ return 2;
1376+ }
1377+ }
1378+ }
1379+ return 0;
1380+}
1381+
1382+//! @brief 敵を探す(遠距離攻撃中に近距離を探す)
1383+int AIcontrol::SearchShortEnemy()
1384+{
1385+ float A_rx, A_ry;
1386+ A_rx = (float)M_PI/180*100;
1387+ A_ry = (float)M_PI/180*52;
1388+
1389+ for(int i=0; i<3; i++){
1390+ int targetid = random(MAX_HUMAN);
1391+
1392+ if( CheckLookEnemy(targetid, A_rx, A_ry, 200.0f, NULL) == true ){
1393+ longattack = false;
1394+ return 1;
1395+ }
1396+ }
1397+ return 0;
1398+}
1399+
1400+//! @brief 敵が見えるか判定
1401+bool AIcontrol::CheckLookEnemy(int id, float search_rx, float search_ry, float maxDist, float *out_minDist)
1402+{
1403+ if( ObjMgr == NULL ){ return false; }
1404+
1405+ //人のオブジェクトを取得
1406+ class human* thuman;
1407+ thuman = ObjMgr->GeHumanObject(id);
1408+ if( thuman == NULL ){ return false; }
1409+
1410+ //同名関数をオーバーロード
1411+ return CheckLookEnemy(thuman, search_rx, search_ry, maxDist, out_minDist);
1412+}
1413+
1414+//! @brief 敵が見えるか判定
1415+bool AIcontrol::CheckLookEnemy(class human* thuman, float search_rx, float search_ry, float maxDist, float *out_minDist)
1416+{
1417+ //return false;
1418+
1419+ //無効なデータなら終了
1420+ if( ctrlhuman == NULL ){ return false; }
1421+ if( thuman == NULL ){ return false; }
1422+ if( thuman->GetDrawFlag() == false ){ return false; }
1423+ if( thuman->GetDeadFlag() == true ){ return false; }
1424+
1425+ //自分と敵の座標を取得
1426+ int ctrlteam, targetteam;
1427+ float tx, ty, tz;
1428+ ctrlhuman->GetParamData(NULL, NULL, NULL, &ctrlteam);
1429+ thuman->GetParamData(NULL, NULL, NULL, &targetteam);
1430+ thuman->GetPosData(&tx, &ty, &tz, NULL);
1431+
1432+ //自分と敵が同一人物でなければ
1433+ if( ctrlteam != targetteam ){
1434+ float mrx, mry;
1435+ float Dist2 , Dist;
1436+ float Dist_dummy;
1437+
1438+ //距離を判定し、角度も取得
1439+ if( CheckTargetAngle(posx, posy, posz, rx*-1 + (float)M_PI/2, 0.0f, tx, ty, tz, maxDist, &mrx, &mry, &Dist2) == true ){
1440+ //角度上、視界に入っていれば
1441+ if( (abs(mrx) < search_rx/2)&&(abs(mry) < search_ry/2) ){
1442+ float vx, vy, vz;
1443+
1444+ Dist = sqrt(Dist2);
1445+
1446+ //ベクトルを取得
1447+ vx = (tx - posx)/Dist;
1448+ vy = (ty - posy)/Dist;
1449+ vz = (tz - posz)/Dist;
1450+
1451+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
1452+ if( CollD->CheckALLBlockIntersectRay(posx, posy + VIEW_HEIGHT, posz, vx, vy, vz, NULL, NULL, &Dist_dummy, Dist) == false ){
1453+ if( out_minDist != NULL ){ *out_minDist = Dist; }
1454+ enemyhuman = thuman;
1455+ return true;
1456+ }
1457+ }
1458+ }
1459+ }
1460+ return false;
1461+}
1462+
1463+//! @brief 死体があるか確認
1464+bool AIcontrol::CheckCorpse(int id)
1465+{
1466+ //クラス設定がおかしければ処理しない
1467+ if( ObjMgr == NULL ){ return false; }
1468+ if( ctrlhuman == NULL ){ return false; }
1469+
1470+ //ターゲットのクラスを取得
1471+ class human* thuman;
1472+ thuman = ObjMgr->GeHumanObject(id);
1473+ if( thuman == NULL ){ return false; }
1474+ if( thuman->GetDrawFlag() == false ){ return false; }
1475+
1476+ //死亡していれば
1477+ if( thuman->GetDeadFlag() == true ){
1478+
1479+ //チーム番号を取得
1480+ int ctrlteam, targetteam;
1481+ ctrlhuman->GetParamData(NULL, NULL, NULL, &ctrlteam);
1482+ thuman->GetParamData(NULL, NULL, NULL, &targetteam);
1483+
1484+ //味方ならば
1485+ if( ctrlteam == targetteam ){
1486+ float tposx, tposy, tposz;
1487+ float atan;
1488+
1489+ //座標から距離を取得
1490+ thuman->GetPosData(&tposx, &tposy, &tposz, NULL);
1491+
1492+ //距離と角度を計算
1493+ if( CheckTargetAngle(posx, posy, posz, rx*-1 + (float)M_PI/2, 0.0f, tposx, tposy, tposz, 22.0f, &atan, NULL, NULL) == true ){
1494+ if( abs(atan) < (float)M_PI/18*4 ){
1495+ return true;
1496+ }
1497+ }
1498+ }
1499+ }
1500+ return false;
1501+}
1502+
1503+//! @brief パスによる移動
1504+void AIcontrol::MovePath()
1505+{
1506+ if( movemode == AI_NULL ){ //異常なパス
1507+ //
1508+ }
1509+ else if( movemode == AI_GRENADE ){ //手榴弾パス
1510+ if( ThrowGrenade() != 0 ){
1511+ SearchTarget(true);
1512+ }
1513+ }
1514+ else{ //その他パス
1515+ if( CheckTargetPos() == false ){
1516+ MoveTarget();
1517+ }
1518+ else if( (movemode == AI_WAIT)||(movemode == AI_TRACKING) ){
1519+ TurnSeen();
1520+ }
1521+ else if( (movemode == AI_STOP)&&(waitcnt < ((int)GAMEFPS)*5) ){
1522+ if( StopSeen() == true ){
1523+ waitcnt += 1;
1524+ }
1525+ }
1526+ else{
1527+ waitcnt = 0;
1528+ SearchTarget(true);
1529+ }
1530+ }
1531+}
1532+
1533+//! @brief 攻撃メイン処理
1534+//! @return 不変:false 変更:true
1535+bool AIcontrol::ActionMain()
1536+{
1537+ int newbattlemode = AI_ACTION;
1538+
1539+ //攻撃処理
1540+ Action();
1541+
1542+ if( movemode == AI_RUN2 ){ //優先的な走り
1543+ //目標地点へ移動
1544+ if( CheckTargetPos() == true ){
1545+ newbattlemode = AI_NORMAL;
1546+ SearchTarget(true);
1547+ }
1548+ else{
1549+ MoveTarget2();
1550+ }
1551+ }
1552+ else{ //優先的な走り 以外
1553+ //遠距離攻撃中なら、近くの敵を探す
1554+ if( longattack == true ){
1555+ SearchShortEnemy();
1556+ }
1557+ }
1558+
1559+ //攻撃終了判定
1560+ if( ActionCancel() == true ){
1561+ enemyhuman = NULL;
1562+
1563+ if( movemode == AI_RUN2 ){
1564+ newbattlemode = AI_NORMAL;
1565+ }
1566+ else{
1567+ newbattlemode = AI_CAUTION;
1568+ cautioncnt = 160;
1569+ }
1570+ }
1571+
1572+ //設定を判定
1573+ if( battlemode != newbattlemode ){
1574+ battlemode = newbattlemode;
1575+ return true;
1576+ }
1577+ return false;
1578+}
1579+
1580+//! @brief 警戒メイン処理
1581+//! @return 不変:false 変更:true
1582+bool AIcontrol::CautionMain()
1583+{
1584+ int newbattlemode = AI_CAUTION;
1585+
1586+ //座標とチーム番号を取得
1587+ int teamid;
1588+ ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid);
1589+
1590+ //被弾と音の状況を取得
1591+ bool HitFlag = ctrlhuman->CheckHit();
1592+ soundlist soundlist[MAX_SOUNDMGR_LIST];
1593+ int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist);
1594+
1595+ //非戦闘化フラグが有効なら、音は聞こえないことにする
1596+ if( NoFight == true ){
1597+ soundlists = 0;
1598+ }
1599+
1600+ //回転と腕の角度
1601+ TurnSeen();
1602+ ArmAngle();
1603+
1604+ //メイン処理
1605+ if( enemyhuman != NULL ){ //既に敵を見つけていれば
1606+ newbattlemode = AI_ACTION;
1607+ actioncnt = 0;
1608+ }
1609+ else if( SearchEnemy() != 0 ){ //敵が見つかれば
1610+ newbattlemode = AI_ACTION;
1611+ actioncnt = 0;
1612+ }
1613+ else if( (HitFlag == true)||(soundlists > 0) ){ //被弾したか音が聞こえた
1614+ cautioncnt = 160; //警戒を再開
1615+ }
1616+ else if( cautioncnt == 0 ){ //警戒を終了するなら
1617+ if( CheckTargetPos() == false ){ //警戒開始地点より離れているか
1618+ MoveTarget(); //警戒開始地点に近づく
1619+ }
1620+ else{
1621+ newbattlemode = AI_NORMAL;
1622+
1623+ //警戒待ちパスなら次へ進める
1624+ pointdata pdata;
1625+ Points->Getdata(&pdata, target_pointid);
1626+ if( (pdata.p1 == 3)&&(pdata.p2 == 4) ){
1627+ SearchTarget(true);
1628+ }
1629+ }
1630+ }
1631+ else if( cautioncnt < 100 ){ //100フレームを切ったら、ランダムに警戒終了(カウント:0に)
1632+ if( random(50) == 0 ){ cautioncnt = 0; }
1633+ }
1634+ else{ cautioncnt -= 1; }
1635+
1636+ //追尾中で対象から離れすぎたら、ランダムに警戒終了
1637+ if( (movemode == AI_TRACKING)&&(random(3) == 0) ){
1638+ pointdata pdata;
1639+ float x, z;
1640+ float tx, tz;
1641+ Points->Getdata(&pdata, target_pointid);
1642+ SearchHumanPos(pdata.p4, &tx, &tz);
1643+ x = posx - tx;
1644+ z = posz - tz;
1645+ if( (x*x + z*z) > 25.0f*25.0f ){
1646+ cautioncnt = 0;
1647+ }
1648+ }
1649+
1650+ //設定を判定
1651+ if( battlemode != newbattlemode ){
1652+ battlemode = newbattlemode;
1653+ return true;
1654+ }
1655+ return false;
1656+}
1657+
1658+//! @brief 通常メイン処理
1659+//! @return 不変:false 変更:true
1660+bool AIcontrol::NormalMain()
1661+{
1662+ int newbattlemode = AI_NORMAL;
1663+
1664+ if( hold == false ){
1665+ SearchTarget(false);
1666+ }
1667+ enemyhuman = NULL;
1668+
1669+ //座標とチーム番号を取得
1670+ int teamid;
1671+ ctrlhuman->GetParamData(NULL, NULL, NULL, &teamid);
1672+
1673+ //被弾と音の状況を取得
1674+ bool HitFlag = ctrlhuman->CheckHit();
1675+ soundlist soundlist[MAX_SOUNDMGR_LIST];
1676+ int soundlists = GameSound->GetWorldSound(posx, posy + VIEW_HEIGHT, posz, teamid, soundlist);
1677+
1678+ //非戦闘化フラグが有効なら、音は聞こえないことにする
1679+ if( NoFight == true ){
1680+ soundlists = 0;
1681+ }
1682+
1683+ //ランダムパスなら処理実行
1684+ if( movemode == AI_RANDOM ){
1685+ SearchTarget(true);
1686+ }
1687+
1688+ //腕の角度を設定
1689+ if( movemode != AI_GRENADE ){
1690+ ArmAngle();
1691+ }
1692+
1693+ if( movemode == AI_RUN2 ){ //優先的な走りの処理
1694+ //敵を見つけたら攻撃に入る
1695+ if( SearchEnemy() != 0 ){
1696+ newbattlemode = AI_ACTION;
1697+ }
1698+ else{
1699+ MovePath(); //移動実行
1700+ }
1701+ }
1702+ else{ //優先的な走り以外の処理
1703+ //警戒判定に入る処理
1704+ if(
1705+ (SearchEnemy() != 0)|| //敵を見つけた
1706+ (HitFlag == true)||(soundlists > 0)|| //被弾したか音が聞こえた
1707+ (CheckCorpse( random(MAX_HUMAN) ) == true) //死体を見つけた
1708+ ){
1709+ newbattlemode = AI_CAUTION;
1710+ cautioncnt = 160;
1711+ target_posx = posx;
1712+ target_posz = posz;
1713+ }
1714+ else{
1715+ MovePath(); //移動実行
1716+ }
1717+ }
1718+
1719+ //設定を判定
1720+ if( battlemode != newbattlemode ){
1721+ battlemode = newbattlemode;
1722+ return true;
1723+ }
1724+ return false;
1725+}
1726+
1727+//! @brief 初期化系関数
1728+void AIcontrol::Init()
1729+{
1730+ //クラス設定がおかしければ処理しない
1731+ if( ctrlhuman == NULL ){ return; }
1732+ if( blocks == NULL ){ return; }
1733+ if( Points == NULL ){ return; }
1734+ if( CollD == NULL ){ return; }
1735+
1736+ //使用されていない人なら処理しない
1737+ if( ctrlhuman->GetDrawFlag() == false ){ return; }
1738+
1739+ //ステートを初期化
1740+ hold = false;
1741+ NoFight = false;
1742+ battlemode = AI_NORMAL;
1743+ movemode = AI_NULL;
1744+ enemyhuman = NULL;
1745+ waitcnt = 0;
1746+ gotocnt = 0;
1747+ moveturn_mode = 0x00;
1748+ cautioncnt = 0;
1749+ actioncnt = 0;
1750+ longattack = false;
1751+
1752+ //AIレベルと設定値を取得
1753+ int paramid;
1754+ HumanParameter paramdata;
1755+ //target_pointid = in_target_pointid;
1756+ ctrlhuman->GetParamData(&paramid, &target_pointid, NULL, NULL);
1757+ Param->GetHuman(paramid, &paramdata);
1758+ AIlevel = paramdata.AIlevel;
1759+ Param->GetAIlevel(AIlevel, &LevelParam);
1760+
1761+ //次のポイントを検索
1762+ SearchTarget(true);
1763+}
1764+
1765+//! @brief 指定した場所へ待機させる
1766+//! @param px X座標
1767+//! @param pz Z座標
1768+//! @param rx 重視する向き
1769+//! @attention 移動パスに関わらず、指定した座標への待機を強制します。Init()関数を再度実行するまで元に戻せません。
1770+void AIcontrol::SetHoldWait(float px, float pz, float rx)
1771+{
1772+ movemode = AI_WAIT;
1773+ hold = true;
1774+ target_posx = px;
1775+ target_posz = pz;
1776+ target_rx = rx;
1777+}
1778+
1779+//! @brief 指定した人を追尾させる
1780+//! @param id 人のデータ番号
1781+//! @attention 移動パスに関わらず、指定した人への追尾を強制します。Init()関数を再度実行するまで元に戻せません。
1782+void AIcontrol::SetHoldTracking(int id)
1783+{
1784+ movemode = AI_TRACKING;
1785+ hold = false;
1786+ target_pointid = id;
1787+}
1788+
1789+//! @brief 強制的に警戒させる
1790+//! @warning 優先的な走り を実行中の場合、この関数は何もしません。
1791+void AIcontrol::SetCautionMode()
1792+{
1793+ //優先的な走りならば何もしない
1794+ if( movemode == AI_RUN2 ){ return; }
1795+
1796+ if( battlemode == AI_NORMAL ){
1797+ target_posx = posx;
1798+ target_posz = posz;
1799+ }
1800+ battlemode = AI_CAUTION;
1801+ cautioncnt = 160;
1802+}
1803+
1804+//! @brief 非戦闘化フラグを設定
1805+//! @param flag true:戦闘を行わない(非戦闘化) false:戦闘を行う(通常)
1806+//! @attention フラグを有効にすると敵を認識しなくなります。
1807+void AIcontrol::SetNoFightFlag(bool flag)
1808+{
1809+ NoFight = flag;
1810+}
1811+
1812+//! @brief 処理系関数
1813+void AIcontrol::Process()
1814+{
1815+ //クラス設定がおかしければ処理しない
1816+ if( ctrlhuman == NULL ){ return; }
1817+ if( blocks == NULL ){ return; }
1818+ if( Points == NULL ){ return; }
1819+ if( CollD == NULL ){ return; }
1820+
1821+ //無効な人クラスなら処理しない
1822+ if( ctrlhuman->GetDrawFlag() == false ){ return; }
1823+
1824+ //死亡したら
1825+ if( ctrlhuman->GetHP() <= 0 ){
1826+ battlemode = AI_DEAD;
1827+ movemode = AI_DEAD;
1828+ return;
1829+ }
1830+
1831+ //座標と角度を取得
1832+ ctrlhuman->GetPosData(&posx, &posy, &posz, NULL);
1833+ ctrlhuman->GetRxRy(&rx, &ry);
1834+
1835+ //ランダムに動作を止める
1836+ CancelMoveTurn();
1837+
1838+ //攻撃中か警戒中ならば
1839+ if( (battlemode == AI_ACTION)||(battlemode == AI_CAUTION) ){
1840+ //武器を持つ
1841+ HaveWeapon();
1842+ }
1843+
1844+ //主計算実行
1845+ if( battlemode == AI_ACTION ){ //攻撃中
1846+ ActionMain();
1847+ }
1848+ else if( battlemode == AI_CAUTION ){ //警戒中
1849+ CautionMain();
1850+ }
1851+ else{ //平常時
1852+ NormalMain();
1853+ }
1854+
1855+ //移動・方向転換処理
1856+ ControlMoveTurn();
1857+
1858+ //武器を取り扱い
1859+ ControlWeapon();
1860+
1861+ //角度を適用
1862+ ctrlhuman->SetRxRy(rx, ry);
1863+}
\ No newline at end of file
--- tags/v1.010-20150220/objectmanager.cpp (nonexistent)
+++ tags/v1.010-20150220/objectmanager.cpp (revision 45)
@@ -0,0 +1,2260 @@
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+//! @brief コンストラクタ
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+ Human_ShotFlag = new bool[MAX_HUMAN];
49+ Player_HumanID = 0;
50+ AddHumanIndex_TextureID = -1;
51+
52+ GameParamInfo = NULL;
53+ d3dg = NULL;
54+ Resource = NULL;
55+ BlockData = NULL;
56+ PointData = NULL;
57+ CollD = NULL;
58+}
59+
60+//! @brief ディストラクタ
61+ObjectManager::~ObjectManager()
62+{
63+ Cleanup();
64+
65+ if( HumanIndex != NULL ){ delete [] HumanIndex; }
66+ if( WeaponIndex != NULL ){ delete [] WeaponIndex; }
67+ if( SmallObjectIndex != NULL ){ delete [] SmallObjectIndex; }
68+ if( BulletIndex != NULL ){ delete [] BulletIndex; }
69+ if( GrenadeIndex != NULL ){ delete [] GrenadeIndex; }
70+ if( EffectIndex != NULL ){ delete [] EffectIndex; }
71+
72+ if( Human_ontarget != NULL ){ delete [] Human_ontarget; }
73+ if( Human_kill != NULL ){ delete [] Human_kill; }
74+ if( Human_headshot != NULL ){ delete [] Human_headshot; }
75+ if( Human_ShotFlag != NULL ){ delete [] Human_ShotFlag; }
76+}
77+
78+//! @brief 参照するクラスを設定
79+//! @param in_GameParamInfo ゲーム設定データ管理クラス
80+//! @param in_d3dg 描画処理クラス
81+//! @param in_Resource リソース管理クラス
82+//! @param in_BlockData ブロックデータ管理クラス
83+//! @param in_PointData ポイントデータ管理クラス
84+//! @param in_CollD 当たり判定処理クラス
85+//! @param in_GameSound 効果音再生クラス
86+//! @param in_MIFdata MIFコントロールクラス
87+//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。
88+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)
89+{
90+ GameParamInfo = in_GameParamInfo;
91+ d3dg = in_d3dg;
92+ Resource = in_Resource;
93+ BlockData = in_BlockData;
94+ PointData = in_PointData;
95+ CollD = in_CollD;
96+ GameSound = in_GameSound;
97+ MIFdata = in_MIFdata;
98+
99+ for(int i=0; i<MAX_HUMAN; i++){
100+ HumanIndex[i].SetParameterInfoClass(GameParamInfo);
101+ }
102+ for(int i=0; i<MAX_WEAPON; i++){
103+ WeaponIndex[i].SetParameterInfoClass(GameParamInfo);
104+ }
105+ for(int i=0; i<MAX_SMALLOBJECT; i++){
106+ SmallObjectIndex[i].SetParameterInfoClass(GameParamInfo);
107+ SmallObjectIndex[i].SetMIFInterfaceClass(MIFdata);
108+ }
109+ for(int i=0; i<MAX_GRENADE; i++){
110+ GrenadeIndex[i].SetParameterInfoClass(GameParamInfo);
111+ }
112+
113+ int bulletmodel, bullettexture;
114+ Resource->GetBulletModelTexture(&bulletmodel, &bullettexture);
115+ for(int i=0; i<MAX_BULLET; i++){
116+ BulletIndex[i].SetModel(bulletmodel, 1.0f);
117+ BulletIndex[i].SetTexture(bullettexture);
118+ }
119+
120+ int grenademodel, grenadetexture;
121+ float model_size = 1.0f;
122+ WeaponParameter ParamData;
123+
124+ //リソースとモデルサイズを取得
125+ Resource->GetWeaponModelTexture(ID_WEAPON_GRENADE, &grenademodel, &grenadetexture);
126+ if( GameParamInfo->GetWeapon(ID_WEAPON_GRENADE, &ParamData) == 0 ){
127+ model_size = ParamData.size;
128+ }
129+
130+ //適用
131+ for(int i=0; i<MAX_GRENADE; i++){
132+ GrenadeIndex[i].SetModel(grenademodel, model_size);
133+ GrenadeIndex[i].SetTexture(grenadetexture);
134+ }
135+}
136+
137+//! @brief 人追加
138+//! @param data 人のポイントデータ (pointdata構造体)
139+//! @param infodata 参照する人情報のポイントデータ (〃)
140+//! @return 成功:データ番号(0以上) 失敗:-1
141+//! @attention 無効な人の種類番号が指定された場合は 通称:謎人間 が登場します。テクスチャはマップテクスチャ0番が使用され、HPは 0 が指定(=即死)されます。
142+int ObjectManager::AddHumanIndex(pointdata data, pointdata infodata)
143+{
144+ int GetHumanFlag;
145+ HumanParameter HumanParam;
146+ GetHumanFlag = GameParamInfo->GetHuman(infodata.p2, &HumanParam);
147+ int Humanindexid = -1;
148+ int Weaponindexid = -1;
149+ class weapon *Weapon[TOTAL_HAVEWEAPON];
150+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
151+ Weapon[i] = NULL;
152+ }
153+
154+ //人のモデル番号を取得
155+ int upmodel[TOTAL_UPMODE];
156+ int armmodel[TOTAL_ARMMODE];
157+ int legmodel;
158+ int walkmodel[TOTAL_WALKMODE];
159+ int runmodel[TOTAL_RUNMODE];
160+ Resource->GetHumanModel(upmodel, armmodel, &legmodel, walkmodel, runmodel);
161+
162+ for(int j=0; j<MAX_HUMAN; j++){
163+ if( HumanIndex[j].GetDrawFlag() == false ){
164+ //初期化する
165+ HumanIndex[j].SetPosData(data.x, data.y, data.z, data.r);
166+ HumanIndex[j].SetParamData(infodata.p2, data.id, data.p4, infodata.p3, true);
167+ if( GetHumanFlag == 0 ){
168+ int id = Resource->GetHumanTexture(infodata.p2);
169+ if( id == -1 ){
170+ id = AddHumanIndex_TextureID;
171+ }
172+ else{
173+ AddHumanIndex_TextureID = id;
174+ }
175+
176+ HumanIndex[j].SetTexture(id);
177+ HumanIndex[j].SetModel(upmodel[ HumanParam.model ], armmodel, legmodel, walkmodel, runmodel);
178+ }
179+ else{
180+ AddHumanIndex_TextureID = d3dg->GetMapTextureID(0);
181+
182+ HumanIndex[j].SetTexture(AddHumanIndex_TextureID);
183+ HumanIndex[j].SetModel(upmodel[0], armmodel, legmodel, walkmodel, runmodel);
184+ }
185+ HumanIndex[j].SetDrawFlag(true);
186+ Humanindexid = j;
187+ break;
188+ }
189+ }
190+
191+ //初期化できなかったらエラーとして返す
192+ if( Humanindexid == -1 ){
193+ return -1;
194+ }
195+
196+ //人の設定データが正しく読めていれば〜
197+ if( GetHumanFlag == 0 ){
198+ //武器Bを仮想武器として追加
199+ Weaponindexid = AddVisualWeaponIndex(HumanParam.Weapon[0], true);
200+ if( Weaponindexid != -1 ){
201+ //成功すれば配列に記録
202+ Weapon[0] = &WeaponIndex[Weaponindexid];
203+ }
204+ if( data.p1 == 1 ){
205+ //武器Aの仮想武器として追加
206+ Weaponindexid = AddVisualWeaponIndex(HumanParam.Weapon[1], true);
207+ if( Weaponindexid != -1 ){
208+ //成功すれば配列に記録
209+ Weapon[1] = &WeaponIndex[Weaponindexid];
210+ }
211+ }
212+
213+ //人に持たせる
214+ HumanIndex[Humanindexid].SetWeapon(Weapon);
215+ }
216+
217+ //発砲フラグを初期化
218+ Human_ShotFlag[Humanindexid] = false;
219+
220+ //プレイヤーならば、番号を記録
221+ if( ( (data.p1 == 1)||(data.p1 == 6) )&&(data.p4 == 0) ){
222+ Player_HumanID = Humanindexid;
223+ }
224+
225+ return Humanindexid;
226+}
227+
228+//! @brief 人追加(ゲーム中用)
229+//! @param px X座標
230+//! @param py Y座標
231+//! @param pz Z座標
232+//! @param rx X軸向き
233+//! @param paramID 種類番号
234+//! @param TeamID チーム番号
235+//! @param WeaponID 武器種類番号の配列(要素数:TOTAL_HAVEWEAPON)
236+//! @return 成功:データ番号(0以上) 失敗:-1
237+//! @attention 無効な人の種類番号が指定された場合は 通称:謎人間 が登場します。テクスチャはマップテクスチャ0番が使用され、HPは 0 が指定(=即死)されます。
238+int ObjectManager::AddHumanIndex(float px, float py, float pz, float rx, int paramID, int TeamID, int WeaponID[])
239+{
240+ int GetHumanFlag;
241+ HumanParameter HumanParam;
242+ GetHumanFlag = GameParamInfo->GetHuman(paramID, &HumanParam);
243+ int Humanindexid = -1;
244+ int Weaponindexid = -1;
245+ class weapon *Weapon[TOTAL_HAVEWEAPON];
246+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
247+ Weapon[i] = NULL;
248+ }
249+
250+ //人のモデル番号を取得
251+ int upmodel[TOTAL_UPMODE];
252+ int armmodel[TOTAL_ARMMODE];
253+ int legmodel;
254+ int walkmodel[TOTAL_WALKMODE];
255+ int runmodel[TOTAL_RUNMODE];
256+ Resource->GetHumanModel(upmodel, armmodel, &legmodel, walkmodel, runmodel);
257+
258+ for(int i=0; i<MAX_HUMAN; i++){
259+ if( HumanIndex[i].GetDrawFlag() == false ){
260+ //初期化する
261+ HumanIndex[i].SetPosData(px, py, pz, rx);
262+ HumanIndex[i].SetParamData(paramID, -1, 0, TeamID, true);
263+ if( GetHumanFlag == 0 ){
264+ //読み込めなければ、前回読み込んだテクスチャ番号を利用
265+ //読み込めれば、今回読み込むテクスチャ番号を上書き
266+ int id = Resource->GetHumanTexture(paramID);
267+ if( id == -1 ){
268+ id = AddHumanIndex_TextureID;
269+ }
270+ else{
271+ AddHumanIndex_TextureID = id;
272+ }
273+
274+ HumanIndex[i].SetTexture(id);
275+ HumanIndex[i].SetModel(upmodel[ HumanParam.model ], armmodel, legmodel, walkmodel, runmodel);
276+ }
277+ else{
278+ //今回読み込むテクスチャ番号を上書き
279+ AddHumanIndex_TextureID = d3dg->GetMapTextureID(0);
280+
281+ HumanIndex[i].SetTexture(AddHumanIndex_TextureID);
282+ HumanIndex[i].SetModel(upmodel[0], armmodel, legmodel, walkmodel, runmodel);
283+ }
284+ HumanIndex[i].SetDrawFlag(true);
285+ Humanindexid = i;
286+ break;
287+ }
288+ }
289+
290+ //初期化できなかったらエラーとして返す
291+ if( Humanindexid == -1 ){
292+ return -1;
293+ }
294+
295+ if( GetHumanFlag == 0 ){
296+ //仮想武器を追加
297+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
298+ Weaponindexid = AddVisualWeaponIndex(WeaponID[i], true);
299+ if( Weaponindexid != -1 ){
300+ //成功すれば配列に記録
301+ Weapon[i] = &WeaponIndex[Weaponindexid];
302+ }
303+ }
304+
305+ //人に持たせる
306+ HumanIndex[Humanindexid].SetWeapon(Weapon);
307+ }
308+
309+ return Humanindexid;
310+}
311+
312+//! @brief 武器追加
313+//! @param data 武器のポイントデータ (pointdata構造体)
314+//! @return 成功:データ番号(0以上) 失敗:-1
315+int ObjectManager::AddWeaponIndex(pointdata data)
316+{
317+ //武器番号と弾数を仮登録
318+ int WeaponID = data.p2;
319+ int nbs = (unsigned char)data.p3;
320+
321+ //ランダムな武器ならば
322+ if( data.p1 == 7 ){
323+ WeaponParameter WeaponParam;
324+
325+ if( GetRand(2) == 0 ){
326+ if( GameParamInfo->GetWeapon(data.p2, &WeaponParam) == 1 ){ return -1; }
327+ nbs = (int)WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET; //弾数上書き
328+ }
329+ else{
330+ if( GameParamInfo->GetWeapon(data.p3, &WeaponParam) == 1 ){ return -1; }
331+ WeaponID = data.p3; //武器番号上書き
332+ nbs = (int)WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET; //弾数上書き
333+ }
334+ }
335+
336+ //NONEならば失敗
337+ if( WeaponID == ID_WEAPON_NONE ){ return -1; }
338+
339+ //モデルとテクスチャを取得
340+ int model, texture;
341+ if( Resource->GetWeaponModelTexture(WeaponID, &model, &texture) == 1 ){
342+ return -1;
343+ }
344+
345+ //設定値を取得
346+ WeaponParameter WeaponParam;
347+ if( GameParamInfo->GetWeapon(data.p2, &WeaponParam) == 1 ){ return -1; }
348+
349+ for(int i=0; i<MAX_WEAPON; i++){
350+ if( WeaponIndex[i].GetDrawFlag() == false ){
351+ //初期化する
352+ WeaponIndex[i].SetPosData(data.x, data.y, data.z, data.r);
353+ WeaponIndex[i].SetParamData(WeaponID, 0, nbs, true);
354+ WeaponIndex[i].SetModel(model, WeaponParam.size);
355+ WeaponIndex[i].SetTexture(texture);
356+ WeaponIndex[i].SetDrawFlag(true);
357+ WeaponIndex[i].RunReload();
358+ return i;
359+ }
360+ }
361+ return -1;
362+}
363+
364+//! @brief 仮想武器追加
365+//! @param WeaponID 武器の種類番号
366+//! @param loadbullet 弾をロードする
367+//! @return 成功:データ番号(0以上) 失敗:-1
368+//! @attention 人が最初から所持している武器を、武器データ(オブジェクト)として追加処理するための関数です。
369+//! @attention 武器単体として配置する場合は、AddWeaponIndex()関数を使用してください。
370+int ObjectManager::AddVisualWeaponIndex(int WeaponID, bool loadbullet)
371+{
372+ //NONEならば失敗
373+ if( WeaponID == ID_WEAPON_NONE ){ return -1; }
374+
375+ //情報を取得
376+ WeaponParameter WeaponParam;
377+ if( GameParamInfo->GetWeapon(WeaponID, &WeaponParam) == 1 ){ return -1; }
378+
379+ //モデルとテクスチャを取得
380+ int model, texture;
381+ if( Resource->GetWeaponModelTexture(WeaponID, &model, &texture) == 1 ){
382+ return -1;
383+ }
384+
385+ for(int i=0; i<MAX_WEAPON; i++){
386+ if( WeaponIndex[i].GetDrawFlag() == false ){
387+ //初期化
388+ WeaponIndex[i].SetPosData(0.0f, 0.0f, 0.0f, 0.0f);
389+ if( loadbullet == false ){
390+ WeaponIndex[i].SetParamData(WeaponID, 0, 0, true);
391+ }
392+ else{
393+ WeaponIndex[i].SetParamData(WeaponID, WeaponParam.nbsmax, WeaponParam.nbsmax * TOTAL_WEAPON_AUTOBULLET, true);
394+ }
395+ WeaponIndex[i].SetModel(model, WeaponParam.size);
396+ WeaponIndex[i].SetTexture(texture);
397+ WeaponIndex[i].SetDrawFlag(true);
398+ return i;
399+ }
400+ }
401+ return -1;
402+}
403+
404+//! @brief 小物追加
405+//! @param data 小物のポイントデータ (pointdata構造体)
406+//! @return 成功:データ番号(0以上) 失敗:-1
407+int ObjectManager::AddSmallObjectIndex(pointdata data)
408+{
409+ //モデルとテクスチャを取得
410+ int model, texture;
411+ if( Resource->GetSmallObjectModelTexture(data.p2, &model, &texture) == 1 ){
412+ return -1;
413+ }
414+
415+ for(int j=0; j<MAX_SMALLOBJECT; j++){
416+ if( SmallObjectIndex[j].GetDrawFlag() == false ){
417+ //初期化
418+ SmallObjectIndex[j].SetPosData(data.x, data.y, data.z, data.r);
419+ SmallObjectIndex[j].SetParamData(data.p2, data.p4, true);
420+ SmallObjectIndex[j].SetModel(model, 5.0f);
421+ SmallObjectIndex[j].SetTexture(texture);
422+ SmallObjectIndex[j].SetDrawFlag(true);
423+
424+ //位置修正フラグが有効ならば、マップと判定
425+ if( data.p3 !=0 ){
426+ SmallObjectIndex[j].CollisionMap(CollD);
427+ }
428+ return j;
429+ }
430+ }
431+ return -1;
432+}
433+
434+//! @brief 小物追加(ゲーム中用)
435+//! @param px X座標
436+//! @param py Y座標
437+//! @param pz Z座標
438+//! @param rx X軸向き
439+//! @param paramID 種類番号
440+//! @param MapColl 位置修正フラグ
441+//! @return 成功:データ番号(0以上) 失敗:-1
442+int ObjectManager::AddSmallObjectIndex(float px, float py, float pz, float rx, int paramID, bool MapColl)
443+{
444+ //モデルとテクスチャを取得
445+ int model, texture;
446+ if( Resource->GetSmallObjectModelTexture(paramID, &model, &texture) == 1 ){
447+ return -1;
448+ }
449+
450+ for(int j=0; j<MAX_SMALLOBJECT; j++){
451+ if( SmallObjectIndex[j].GetDrawFlag() == false ){
452+ //初期化
453+ SmallObjectIndex[j].SetPosData(px, py, pz, rx);
454+ SmallObjectIndex[j].SetParamData(paramID, 0, true);
455+ SmallObjectIndex[j].SetModel(model, 5.0f);
456+ SmallObjectIndex[j].SetTexture(texture);
457+ SmallObjectIndex[j].SetDrawFlag(true);
458+
459+ //位置修正フラグが有効ならば、マップと判定
460+ if( MapColl == true ){
461+ SmallObjectIndex[j].CollisionMap(CollD);
462+ }
463+ return j;
464+ }
465+ }
466+ return -1;
467+}
468+
469+//! @brief エフェクト追加
470+//! @param pos_x X座標
471+//! @param pos_y Y座標
472+//! @param pos_z Z座標
473+//! @param move_x X軸移動量
474+//! @param move_y Y軸移動量
475+//! @param move_z Z軸移動量
476+//! @param size 表示倍率
477+//! @param rotation 回転角度
478+//! @param count 表示フレーム数
479+//! @param texture テクスチャの認識番号
480+//! @param settype エフェクトの種類 (Effect_Type を組み合せる)
481+//! @return 成功:データ番号(0以上) 失敗:-1
482+int ObjectManager::AddEffect(float pos_x, float pos_y, float pos_z, float move_x, float move_y, float move_z, float size, float rotation, int count, int texture, int settype)
483+{
484+ for(int i=0; i<MAX_EFFECT; i++){
485+ if( EffectIndex[i].GetDrawFlag() == false ){
486+ EffectIndex[i].SetPosData(pos_x, pos_y, pos_z, 0.0f);
487+ EffectIndex[i].SetParamData(move_x, move_y, move_z, size, rotation, count, texture, settype, true);
488+ EffectIndex[i].SetDrawFlag(true);
489+ return i;
490+ }
491+ }
492+
493+ return -1;
494+}
495+
496+//! @brief 出血させる
497+//! @param x X座標
498+//! @param y Y座標
499+//! @param z Z座標
500+void ObjectManager::SetHumanBlood(float x, float y, float z)
501+{
502+ if( GameConfig.GetBloodFlag() == true ){
503+ for(int i=0; i<2; i++){
504+ float rx = (float)M_PI/18*GetRand(36);
505+ AddEffect(x + cos(rx)*1.0f, y + (float)(GetRand(20)-10)/10, z + sin(rx)*1.0f, cos(rx)*0.5f, 0.5f, sin(rx)*0.5f, 10.0f, (float)M_PI/18*GetRand(18), (int)GAMEFPS * 1, Resource->GetEffectBloodTexture(), EFFECT_FALL);
506+ }
507+ }
508+}
509+
510+//! @brief 人同士の当たり判定
511+//! @param in_humanA 対象の人オブジェクトA
512+//! @param in_humanB 対象の人オブジェクトB
513+//! @return 当たっている:true 当たっていない:false
514+//! @warning in_humanAとin_humanBで区別はありません。
515+//! @warning in_humanAとin_humanBでの組み合せは、1フレーム間に1度だけ実行してください。
516+//! @attention 両クラスは自動的にAddPosOrder()を用いて、お互いを押し合います。
517+bool ObjectManager::CollideHuman(human *in_humanA, human *in_humanB)
518+{
519+ float h1_x, h1_y, h1_z;
520+ float h2_x, h2_y, h2_z;
521+ float angle, length;
522+
523+ //初期化されていないか、死亡して入れば判定しない
524+ if( in_humanA->GetDrawFlag() == false ){ return false; }
525+ if( in_humanB->GetDrawFlag() == false ){ return false; }
526+ if( in_humanA->GetHP() <= 0 ){ return false; }
527+ if( in_humanB->GetHP() <= 0 ){ return false; }
528+
529+ //お互いの座標を取得
530+ in_humanA->GetPosData(&h1_x, &h1_y, &h1_z, NULL);
531+ in_humanB->GetPosData(&h2_x, &h2_y, &h2_z, NULL);
532+
533+ //円柱の当たり判定
534+ if( CollideCylinder(h1_x, h1_y, h1_z, 3.0f, HUMAN_HEIGTH-0.5f, h2_x, h2_y, h2_z, 3.0f, HUMAN_HEIGTH-0.5f, &angle, &length) == true ){
535+ //めり込んだ分だけ押し出す
536+ in_humanA->AddPosOrder(angle, 0.0f, length/2);
537+ in_humanB->AddPosOrder(angle + (float)M_PI, 0.0f, length/2);
538+ return true;
539+ }
540+
541+ return false;
542+}
543+
544+//! @brief 弾の当たり判定と処理
545+//! @param in_bullet 対象の弾オブジェクト
546+//! @return 当たった:true 当たっていない:false
547+//! @attention 判定を行う対象は「マップ」「人(頭・上半身・下半身)」「小物」です。
548+//! @attention 判定に限らず、ダメージ計算や効果音再生まで一貫して行います。
549+bool ObjectManager::CollideBullet(bullet *in_bullet)
550+{
551+ //使用されていない弾丸ならば、処理せずに返す。
552+ if( in_bullet->GetDrawFlag() == false ){ return false; }
553+
554+ float bx, by, bz;
555+ float brx, bry;
556+ int attacks;
557+ int penetration;
558+ int speed;
559+ int teamid;
560+ int humanid;
561+ float vx, vy, vz;
562+ int HumanHead_id;
563+ int HumanUp_id;
564+ int HumanLeg_id;
565+ int SmallObject_id;
566+ float map_Dist;
567+ float HumanHead_Dist;
568+ float HumanUp_Dist;
569+ float HumanLeg_Dist;
570+ float SmallObject_Dist;
571+ float CheckDist;
572+ bool CollideFlag;
573+
574+ int id, face;
575+ float Dist;
576+
577+ //弾丸の座標を取得し、ベクトルを算出。
578+ in_bullet->GetPosData(&bx, &by, &bz, &brx, &bry);
579+ in_bullet->GetParamData(&attacks, &penetration, &speed, &teamid, &humanid);
580+ vx = cos(brx)*cos(bry);
581+ vy = sin(bry);
582+ vz = sin(brx)*cos(bry);
583+
584+ CheckDist = 0;
585+ CollideFlag = false;
586+
587+ for(float TotalDist=0.0f; TotalDist<speed; TotalDist+=CheckDist){
588+ CheckDist = speed - TotalDist;
589+
590+ //貫通力が残っていなければ
591+ if( penetration < 0 ){
592+ //弾は無効にする
593+ in_bullet->SetDrawFlag(false);
594+ break;
595+ }
596+
597+ float bvx, bvy, bvz;
598+ bvx = bx + vx*TotalDist;
599+ bvy = by + vy*TotalDist;
600+ bvz = bz + vz*TotalDist;
601+
602+ HumanHead_id = -1;
603+ HumanUp_id = -1;
604+ HumanLeg_id = -1;
605+ SmallObject_id = -1;
606+ map_Dist = (float)speed - TotalDist + 1;
607+ HumanHead_Dist = (float)speed - TotalDist + 1;
608+ HumanUp_Dist = (float)speed - TotalDist + 1;
609+ HumanLeg_Dist = (float)speed - TotalDist + 1;
610+ SmallObject_Dist = (float)speed - TotalDist + 1;
611+
612+ //マップとの当たり判定
613+ if( CollD->CheckALLBlockIntersectRay(bvx, bvy, bvz, vx, vy, vz, &id, &face, &Dist, (float)speed - TotalDist) == true ){
614+ map_Dist = Dist;
615+ }
616+
617+ //人との当たり判定
618+ for(int i=0; i<MAX_HUMAN; i++){
619+ //使用されていないか、死亡していれば処理しない。
620+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
621+ if( HumanIndex[i].GetHP() <= 0 ){ continue; }
622+
623+ //座標を取得
624+ float ox, oy, oz;
625+ int h_teamid;
626+ HumanIndex[i].GetPosData(&ox, &oy, &oz, NULL);
627+ HumanIndex[i].GetParamData(NULL, NULL, NULL, &h_teamid);
628+
629+ //同じチーム番号(味方)なら処理しない
630+ if( h_teamid == teamid ){ continue; }
631+
632+ //人全体の当たり判定
633+ 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 ){
634+
635+ //頭の当たり判定
636+ 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 ){
637+ if( Dist < HumanHead_Dist ){
638+ HumanHead_id = i;
639+ HumanHead_Dist = Dist;
640+ }
641+ }
642+
643+ //上半身と当たり判定
644+ 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 ){
645+ if( Dist < HumanUp_Dist ){
646+ HumanUp_id = i;
647+ HumanUp_Dist = Dist;
648+ }
649+ }
650+
651+ //足と当たり判定
652+ 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 ){
653+ if( Dist < HumanLeg_Dist ){
654+ HumanLeg_id = i;
655+ HumanLeg_Dist = Dist;
656+ }
657+ }
658+
659+ }
660+ }
661+
662+ //小物との当たり判定
663+ for(int i=0; i<MAX_SMALLOBJECT; i++){
664+ //使用されていなければ処理しない
665+ if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; }
666+
667+ //座標を取得
668+ float ox, oy, oz;
669+ int id;
670+ float decide;
671+ SmallObjectIndex[i].GetPosData(&ox, &oy, &oz, NULL);
672+ SmallObjectIndex[i].GetParamData(&id, NULL);
673+
674+ //当たり判定の大きさを取得
675+ if( id == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
676+ decide = (float)MIFdata->GetAddSmallobjectDecide()*SMALLOBJECT_SCALE;
677+ }
678+ else{
679+ SmallObjectParameter Param;
680+ GameParamInfo->GetSmallObject(id, &Param);
681+ decide = (float)Param.decide*SMALLOBJECT_SCALE;
682+ }
683+
684+ //当たり判定
685+ if( CollideSphereRay(ox, oy, oz, decide, bvx, bvy, bvz, vx, vy, vz, &Dist, (float)speed - TotalDist) == true ){
686+ if( Dist < SmallObject_Dist ){
687+ SmallObject_id = i;
688+ SmallObject_Dist = Dist;
689+ }
690+ }
691+ }
692+
693+ //マップとの衝突距離が最短ならば〜
694+ if( (map_Dist <= speed)&&(map_Dist < HumanHead_Dist)&&(map_Dist < HumanUp_Dist)&&(map_Dist < HumanLeg_Dist)&&(map_Dist < SmallObject_Dist) ){
695+ //弾がマップに当たった処理
696+ HitBulletMap(bx + vx*(map_Dist+TotalDist), by + vy*(map_Dist+TotalDist), bz + vz*(map_Dist+TotalDist));
697+
698+ int Penetration_Dist;
699+
700+ //マップにめり込んでいる量を調べる
701+ //  最終地点がマップにめり込んでいるならば
702+ 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 ){
703+ //発射地点と最終地点、それぞれからの激突点から貫通距離を求める
704+ Penetration_Dist = (int)( ((float)speed - map_Dist+TotalDist - Dist) / 2 );
705+ }
706+ else{
707+ //衝突点から最終地点まで移動距離
708+ Penetration_Dist = (int)( ((float)speed - map_Dist+TotalDist) / 2 );
709+ }
710+
711+ //攻撃力と貫通力を計算
712+ for(int i=0; i<Penetration_Dist; i++){
713+ attacks = (int)((float)attacks * 0.6f);
714+ }
715+ penetration -= Penetration_Dist;
716+
717+ CheckDist = map_Dist + 1.0f;
718+ }
719+
720+ //人の頭との衝突距離が最短ならば〜
721+ if( (HumanHead_Dist <= speed)&&(HumanHead_Dist < map_Dist)&&(HumanHead_Dist < HumanUp_Dist)&&(HumanHead_Dist < HumanLeg_Dist)&&(HumanHead_Dist < SmallObject_Dist) ){
722+ //人に当たった処理
723+ HitBulletHuman(HumanHead_id, 0, bx + vx*(HumanHead_Dist+TotalDist), by + vy*(HumanHead_Dist+TotalDist), bz + vz*(HumanHead_Dist+TotalDist), brx, attacks, humanid);
724+
725+ //攻撃力と貫通力を計算
726+ attacks = (int)((float)attacks * 0.6f);
727+ penetration -= 1;
728+
729+ CheckDist = HumanHead_Dist + 1.0f;
730+ }
731+
732+ //人の上半身との衝突距離が最短ならば〜
733+ if( (HumanUp_Dist <= speed)&&(HumanUp_Dist < map_Dist)&&(HumanUp_Dist < HumanHead_Dist)&&(HumanUp_Dist < HumanLeg_Dist)&&(HumanUp_Dist < SmallObject_Dist) ){
734+ //人に当たった処理
735+ HitBulletHuman(HumanUp_id, 1, bx + vx*(HumanUp_Dist+TotalDist), by + vy*(HumanUp_Dist+TotalDist), bz + vz*(HumanUp_Dist+TotalDist), brx, attacks, humanid);
736+
737+ //攻撃力と貫通力を計算
738+ attacks = (int)((float)attacks * 0.6f);
739+ penetration -= 1;
740+
741+ CheckDist = HumanUp_Dist + 1.0f;
742+ }
743+
744+ //人の足との衝突距離が最短ならば〜
745+ if( (HumanLeg_Dist <= speed)&&(HumanLeg_Dist < map_Dist)&&(HumanLeg_Dist < HumanHead_Dist)&&(HumanLeg_Dist < HumanUp_Dist)&&(HumanLeg_Dist < SmallObject_Dist) ){
746+ //人に当たった処理
747+ HitBulletHuman(HumanLeg_id, 2, bx + vx*(HumanLeg_Dist+TotalDist), by + vy*(HumanLeg_Dist+TotalDist), bz + vz*(HumanLeg_Dist+TotalDist), brx, attacks, humanid);
748+
749+ //攻撃力と貫通力を計算
750+ attacks = (int)((float)attacks * 0.7f);
751+ penetration -= 1;
752+
753+ CheckDist = HumanLeg_Dist + 1.0f;
754+ }
755+
756+ //小物との衝突距離が最短ならば〜
757+ if( (SmallObject_Dist <= speed)&&(SmallObject_Dist < map_Dist)&&(SmallObject_Dist < HumanHead_Dist)&&(SmallObject_Dist < HumanUp_Dist)&&(SmallObject_Dist < HumanLeg_Dist) ){
758+ //小物に当たった処理
759+ HitBulletSmallObject(SmallObject_id, bx + vx*(SmallObject_Dist+TotalDist), by + vy*(SmallObject_Dist+TotalDist), bz + vz*(SmallObject_Dist+TotalDist), attacks);
760+
761+ //小物の種類番号を取得
762+ int id;
763+ int decide;
764+ SmallObjectIndex[SmallObject_id].GetParamData(&id, NULL);
765+
766+ //小物の設定値を取得
767+ SmallObjectParameter Param;
768+ GameParamInfo->GetSmallObject(id, &Param);
769+ decide = (int)( (float)Param.decide*SMALLOBJECT_SCALE );
770+
771+ //貫通力を計算
772+ for(int i=0; i<decide; i++){
773+ attacks = (int)((float)attacks * 0.7f);
774+ }
775+
776+ CheckDist = SmallObject_Dist + 1.0f;
777+ }
778+
779+ //設定を適用(特に攻撃力・貫通力)
780+ in_bullet->SetParamData(attacks, penetration, speed, teamid, humanid, false);
781+ }
782+
783+ return CollideFlag;
784+}
785+
786+//! @brief 弾がマップに当たった処理
787+//! @param x 着弾X座標
788+//! @param y 着弾Y座標
789+//! @param z 着弾Z座標
790+void ObjectManager::HitBulletMap(float x, float y, float z)
791+{
792+ //エフェクト(煙)を表示
793+ AddEffect(x, y, z, 0.0f, 0.05f, 0.0f, 5.0f, (float)M_PI/18*GetRand(18), (int)(GAMEFPS * 0.5f), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY);
794+
795+ //効果音を再生
796+ GameSound->HitMap(x, y, z);
797+}
798+
799+//! @brief 弾が人に当たった処理
800+//! @param HitHuman_id 人の番号
801+//! @param Hit_id 被弾箇所(頭:0 胴体:1 足:2)
802+//! @param x 被弾X座標
803+//! @param y 被弾Y座標
804+//! @param z 被弾Z座標
805+//! @param brx 水平角度
806+//! @param attacks 攻撃力
807+//! @param Shothuman_id 発射した人の番号
808+void ObjectManager::HitBulletHuman(int HitHuman_id, int Hit_id, float x, float y, float z, float brx, int attacks, int Shothuman_id)
809+{
810+ //使用されていないか、死亡していれば処理しない。
811+ if( HumanIndex[HitHuman_id].GetDrawFlag() == false ){ return; }
812+ if( HumanIndex[HitHuman_id].GetHP() <= 0 ){ return; }
813+
814+ //人にダメージと衝撃を与える
815+ if( Hit_id == 0 ){ HumanIndex[HitHuman_id].HitBulletHead(attacks); }
816+ if( Hit_id == 1 ){ HumanIndex[HitHuman_id].HitBulletUp(attacks); }
817+ if( Hit_id == 2 ){ HumanIndex[HitHuman_id].HitBulletLeg(attacks); }
818+ HumanIndex[HitHuman_id].AddPosOrder(brx, 0.0f, 1.0f);
819+
820+ //エフェクト(血)を表示
821+ SetHumanBlood(x, y, z);
822+
823+ //効果音を再生
824+ GameSound->HitHuman(x, y, z);
825+
826+ //弾を発射した人の成果に加算
827+ Human_ontarget[Shothuman_id] += 1;
828+ if( Hit_id == 0 ){ Human_headshot[Shothuman_id] += 1; }
829+ if( HumanIndex[HitHuman_id].GetHP() <= 0 ){
830+ Human_kill[Shothuman_id] += 1;
831+ }
832+}
833+
834+//! @brief 弾が小物に当たった処理
835+//! @param HitSmallObject_id 小物の番号
836+//! @param x 着弾X座標
837+//! @param y 着弾Y座標
838+//! @param z 着弾Z座標
839+//! @param attacks 攻撃力
840+void ObjectManager::HitBulletSmallObject(int HitSmallObject_id, float x, float y, float z, int attacks)
841+{
842+ int hp;
843+
844+ //使用されていなければ処理しない。
845+ if( SmallObjectIndex[HitSmallObject_id].GetDrawFlag() == false ){ return; }
846+
847+ //体力がなければ処理しない
848+ hp = SmallObjectIndex[HitSmallObject_id].GetHP();
849+ if( hp <= 0 ){ return; }
850+
851+ //小物にダメージを与える
852+ SmallObjectIndex[HitSmallObject_id].HitBullet(attacks);
853+
854+ //エフェクト(煙)を表示
855+ AddEffect(x, y, z, 0.0f, 0.05f, 0.0f, 5.0f, (float)M_PI/18*GetRand(18), (int)(GAMEFPS * 0.5f), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY);
856+
857+ //効果音を再生
858+ int id;
859+ SmallObjectIndex[HitSmallObject_id].GetParamData(&id, NULL);
860+ GameSound->HitSmallObject(x, y, z, id);
861+}
862+
863+//! @brief 手榴弾のダメージ判定と処理
864+//! @param in_grenade 対象の手榴弾オブジェクト
865+//! @return 当たった:true 当たっていない:false
866+//! @attention 判定を行う対象は「人」と「小物」です。
867+//! @attention ダメージ判定に限らず、ダメージ計算や効果音再生まで一貫して行います。
868+bool ObjectManager::GrenadeExplosion(grenade *in_grenade)
869+{
870+ bool returnflag = false;
871+
872+ //座標を取得
873+ float gx, gy, gz;
874+ int humanid;
875+ in_grenade->GetPosData(&gx, &gy, &gz, NULL, NULL);
876+ in_grenade->GetParamData(NULL, NULL, NULL, NULL, &humanid);
877+
878+ //人に爆風の当たり判定
879+ for(int i=0; i<MAX_HUMAN; i++){
880+ //初期化されていないか、死亡していれば処理しない。
881+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
882+ if( HumanIndex[i].GetHP() <= 0 ){ continue; }
883+
884+ float hx, hy, hz;
885+ float x, y, z, r;
886+
887+ //人の座標を取得し、距離を計算
888+ HumanIndex[i].GetPosData(&hx, &hy, &hz, NULL);
889+ x = hx - gx;
890+ y = hy - gy;
891+ z = hz - gz;
892+ r = sqrt(x*x + y*y + z*z);
893+
894+ //100.0より遠ければ計算しない
895+ if( r > MAX_DAMAGE_GRENADE_DISTANCE + HUMAN_HEIGTH ){ continue; }
896+
897+ float dummy = 0.0f;
898+ int total_damage = 0;
899+ int damage;
900+
901+ //足元に当たり判定
902+ y = hy + 2.0f - gy;
903+ r = sqrt(x*x + y*y + z*z);
904+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
905+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
906+ //ダメージ量を計算
907+ damage = HUMAN_DAMAGE_GRENADE_LEG - (int)((float)HUMAN_DAMAGE_GRENADE_LEG/MAX_DAMAGE_GRENADE_DISTANCE * r);
908+ if( damage > 0 ){
909+ total_damage += damage;
910+ }
911+ }
912+
913+ //頭に当たり判定
914+ y = hy + 18.0f - gy;
915+ r = sqrt(x*x + y*y + z*z);
916+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
917+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
918+ //ダメージ量を計算
919+ damage = HUMAN_DAMAGE_GRENADE_HEAD - (int)((float)HUMAN_DAMAGE_GRENADE_HEAD/MAX_DAMAGE_GRENADE_DISTANCE * r);
920+ if( damage > 0 ){
921+ total_damage += damage;
922+ }
923+ }
924+
925+ if( total_damage > 0 ){
926+ //ダメージを反映
927+ HumanIndex[i].HitGrenadeExplosion(total_damage);
928+
929+ float y2;
930+ float arx, ary;
931+
932+ //倒していれば、発射した人の成果に加算
933+ if( HumanIndex[i].GetHP() <= 0 ){
934+ Human_kill[humanid] += 1;
935+ }
936+
937+ //エフェクト(血)を表示
938+ SetHumanBlood(hx, hy+15.0f, hz);
939+
940+ //人と手榴弾の距離を算出
941+ x = gx - hx;
942+ y = gy - (hy + 1.0f);
943+ z = gz - hz;
944+
945+ //角度を求める
946+ arx = atan2(z, x);
947+
948+ if( sin(atan2(y, sqrt(x*x + z*z))) < 0.0f ){ //上方向に飛ぶなら、角度を計算
949+ y2 = gy - (hy + HUMAN_HEIGTH);
950+ ary = atan2(y2, sqrt(x*x + z*z)) + (float)M_PI;
951+ }
952+ else{ //下方向に飛ぶなら、垂直角度は無効。(爆風で地面にめり込むのを防止)
953+ ary = 0.0f;
954+ }
955+
956+ //爆風による風圧
957+ HumanIndex[i].AddPosOrder(arx, ary, 2.2f/MAX_DAMAGE_GRENADE_DISTANCE * (MAX_DAMAGE_GRENADE_DISTANCE - sqrt(x*x + y*y + z*z)));
958+
959+ returnflag = true;
960+ }
961+ }
962+
963+ //小物に爆風の当たり判定
964+ for(int i=0; i<MAX_SMALLOBJECT; i++){
965+ //使用されていれば処理しない
966+ if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; }
967+
968+ float sx, sy, sz;
969+ float x, y, z, r;
970+
971+ //小物の座標を取得し、距離を計算
972+ SmallObjectIndex[i].GetPosData(&sx, &sy, &sz, NULL);
973+ x = sx - gx;
974+ y = sy - gy;
975+ z = sz - gz;
976+ r = sqrt(x*x + y*y + z*z);
977+
978+ //100.0より遠ければ計算しない
979+ if( r > MAX_DAMAGE_GRENADE_DISTANCE ){ continue; }
980+
981+ float dummy = 0.0f;
982+
983+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
984+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
985+ int id, damage;
986+ SmallObjectIndex[i].GetParamData(&id, NULL);
987+
988+ //ダメージ量を計算し、反映
989+ damage = SMALLOBJECT_DAMAGE_GRENADE - (int)((float)SMALLOBJECT_DAMAGE_GRENADE/MAX_DAMAGE_GRENADE_DISTANCE * r);
990+ SmallObjectIndex[i].HitGrenadeExplosion(damage);
991+
992+ //小物から効果音を発する
993+ GameSound->HitSmallObject(sx, sy, sz, id);
994+
995+ returnflag = true;
996+ }
997+ }
998+
999+ //エフェクト(フラッシュ)の表示
1000+ AddEffect(gx, gy, gz, 0.0f, 0.0f, 0.0f, 30.0f, 0.0f, 2, Resource->GetEffectMflashTexture(), EFFECT_NORMAL);
1001+
1002+ //エフェクト(煙)の表示
1003+ float rnd = (float)M_PI/18*GetRand(18);
1004+ AddEffect(gx+1.0f, gy+1.0f, gz+1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1005+ AddEffect(gx-1.0f, gy-1.0f, gz-1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1006+ AddEffect(gx-1.0f, gy-1.0f, gz+1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1007+ AddEffect(gx+1.0f, gy+1.0f, gz-1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1008+
1009+ //効果音を再生
1010+ GameSound->GrenadeExplosion(gx, gy, gz);
1011+
1012+ return returnflag;
1013+}
1014+
1015+//! @brief 倒れた際のエフェクト設定
1016+//! @param in_human 対象の人オブジェクト
1017+void ObjectManager::DeadEffect(human *in_human)
1018+{
1019+ if( in_human == NULL ){ return; }
1020+
1021+ int paramid;
1022+ float hx, hy, hz, hrx, hry;
1023+ HumanParameter data;
1024+
1025+ //各種パラメーターを取得
1026+ in_human->GetParamData(&paramid, NULL, NULL, NULL);
1027+ in_human->GetPosData(&hx, &hy, &hz, &hrx);
1028+ hry = in_human->GetDeadRy();
1029+
1030+ //設定値を取得
1031+ if( GameParamInfo->GetHuman(paramid, &data) != 0 ){ return; }
1032+
1033+ //もしロボットならば
1034+ if( data.type == 1 ){
1035+
1036+ //腰辺りの座標を算出
1037+ hx += cos(hrx*-1 - (float)M_PI/2) * sin(hry) * HUMAN_HEIGTH/2;
1038+ hz += sin(hrx*-1 - (float)M_PI/2) * sin(hry) * HUMAN_HEIGTH/2;
1039+
1040+ //エフェクト(煙)の表示
1041+ float rnd = (float)M_PI/18*GetRand(18);
1042+ AddEffect(hx+1.0f, hy+1.0f, hz+1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1043+ AddEffect(hx-1.0f, hy-1.0f, hz-1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1044+ AddEffect(hx-1.0f, hy-1.0f, hz+1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1045+ AddEffect(hx+1.0f, hy+1.0f, hz-1.0f, 0.0f, 0.05f, 0.0f, 10.0f, rnd*-1, (int)GAMEFPS * 3, Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1046+ }
1047+}
1048+
1049+//! @brief 武器を拾う
1050+//! @param in_human 対象の人オブジェクト
1051+//! @param in_weapon 対象の武器オブジェクト
1052+void ObjectManager::PickupWeapon(human *in_human, weapon *in_weapon)
1053+{
1054+ //無効な人ならば処理しない
1055+ if( in_human->GetDrawFlag() == false ){ return; }
1056+ if( in_human->GetHP() <= 0 ){ return; }
1057+
1058+ //初期化されている武器で、かつ誰も使っていない武器ならば〜
1059+ if( (in_weapon->GetDrawFlag() == true)&&(in_weapon->GetUsingFlag() == false) ){
1060+ float human_x, human_y, human_z;
1061+ float weapon_x, weapon_y, weapon_z;
1062+ float x, z;
1063+ float r;
1064+
1065+ //人と武器の座標を取得
1066+ in_human->GetPosData(&human_x, &human_y, &human_z, NULL);
1067+ in_weapon->GetPosData(&weapon_x, &weapon_y, &weapon_z, NULL);
1068+
1069+ //高さが範囲内ならば
1070+ if( (human_y-2.0f <= weapon_y)&&(human_y+16.0f > weapon_y) ){
1071+ //距離を計算
1072+ x = human_x - weapon_x;
1073+ z = human_z - weapon_z;
1074+ r = x*x + z*z;
1075+ //距離も範囲内ならば、拾わせる。
1076+ if( r < (5.0f * 5.0f) ){
1077+ in_human->PickupWeapon(in_weapon);
1078+ }
1079+ }
1080+ }
1081+}
1082+
1083+//! @brief オブジェクトを解放
1084+void ObjectManager::CleanupPointDataToObject()
1085+{
1086+ for(int i=0; i<MAX_HUMAN; i++){
1087+ HumanIndex[i].SetDrawFlag(false);
1088+ }
1089+
1090+ for(int i=0; i<MAX_WEAPON; i++){
1091+ WeaponIndex[i].SetDrawFlag(false);
1092+ }
1093+
1094+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1095+ SmallObjectIndex[i].SetDrawFlag(false);
1096+ }
1097+
1098+ for(int i=0; i<MAX_BULLET; i++){
1099+ BulletIndex[i].SetDrawFlag(false);
1100+ }
1101+
1102+ for(int i=0; i<MAX_GRENADE; i++){
1103+ GrenadeIndex[i].SetDrawFlag(false);
1104+ }
1105+
1106+ for(int i=0; i<MAX_EFFECT; i++){
1107+ EffectIndex[i].SetDrawFlag(false);
1108+ }
1109+
1110+
1111+ if( Resource != NULL ){
1112+ Resource->CleanupHumanTexture();
1113+ }
1114+}
1115+
1116+//! @brief ポイントデータを元にオブジェクトを配置
1117+void ObjectManager::LoadPointData()
1118+{
1119+ Player_HumanID = 0;
1120+
1121+ /*
1122+ //人情報ポイントを探す
1123+ for(int i=0; i<PointData->GetTotaldatas(); i++){
1124+ pointdata data;
1125+ PointData->Getdata(&data, i);
1126+
1127+ if( data.p1 == 4 ){
1128+ //人のテクスチャを登録
1129+ Resource->AddHumanTexture(data.p2);
1130+ }
1131+ }
1132+ */
1133+
1134+ //人・武器・小物を探す
1135+ for(int i=0; i<PointData->GetTotaldatas(); i++){
1136+ pointdata data;
1137+ PointData->Getdata(&data, i);
1138+
1139+ //人ならば
1140+ if( (data.p1 == 1)||(data.p1 == 6) ){
1141+ pointdata humaninfodata;
1142+
1143+ //人情報ポイントを探す
1144+ if( PointData->SearchPointdata(&humaninfodata, 0x01 + 0x08, 4, 0, 0, data.p2, 0) == 0 ){
1145+ //continue;
1146+
1147+ //人情報ポイントが見つからなかったら、とりあえず「特殊 黒 A」として追加。(バグの再現)
1148+
1149+ HumanParameter HumanParam;
1150+ int Weapon[TOTAL_HAVEWEAPON];
1151+ GameParamInfo->GetHuman(0, &HumanParam);
1152+ for(int j=0; j<TOTAL_HAVEWEAPON; j++){
1153+ Weapon[j] = HumanParam.Weapon[j];
1154+ }
1155+
1156+ //人のテクスチャを登録
1157+ Resource->AddHumanTexture(0);
1158+
1159+ //人を追加
1160+ if( data.p1 == 6 ){
1161+ Weapon[1] = ID_WEAPON_NONE;
1162+ }
1163+
1164+ //プレイヤーならば、番号を記録
1165+ if( (data.p4 == 0)&&(Player_HumanID == 0) ){
1166+ Player_HumanID = AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon);
1167+ }
1168+ else{
1169+ AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon);
1170+ }
1171+ }
1172+ else{
1173+ //人のテクスチャを登録
1174+ Resource->AddHumanTexture(humaninfodata.p2);
1175+
1176+ //人として追加
1177+ AddHumanIndex(data, humaninfodata);
1178+ }
1179+ }
1180+
1181+ //武器ならば
1182+ if( (data.p1 == 2)||(data.p1 == 7) ){
1183+ AddWeaponIndex(data);
1184+ }
1185+
1186+ //小物ならば
1187+ if( data.p1 == 5 ){
1188+ AddSmallObjectIndex(data);
1189+ }
1190+ }
1191+}
1192+
1193+//! @brief プレイヤー番号を取得
1194+//! @return プレイヤーのデータ番号
1195+int ObjectManager::GetPlayerID()
1196+{
1197+ return Player_HumanID;
1198+}
1199+
1200+//! @brief プレイヤー番号を設定
1201+//! @param id プレイヤーのデータ番号
1202+void ObjectManager::SetPlayerID(int id)
1203+{
1204+ Player_HumanID = id;
1205+}
1206+
1207+//! @brief 指定したデータ番号のhumanクラスを取得
1208+//! @param id データ番号
1209+//! @return 人オブジェクトのポインタ (無効なデータ番号で NULL)
1210+human* ObjectManager::GeHumanObject(int id)
1211+{
1212+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return NULL; }
1213+ return &(HumanIndex[id]);
1214+}
1215+
1216+//! @brief プレイヤーのhumanクラスを取得
1217+//! @return 人オブジェクト(プレイヤー)のポインタ
1218+human* ObjectManager::GetPlayerHumanObject()
1219+{
1220+ return GeHumanObject(Player_HumanID);
1221+}
1222+
1223+//! @brief 指定したデータ番号のweaponクラスを取得
1224+//! @param id データ番号
1225+//! @return 武器オブジェクトのポインタ (無効なデータ番号で NULL)
1226+weapon* ObjectManager::GetWeaponObject(int id)
1227+{
1228+ if( (id < 0)||(MAX_WEAPON-1 < id) ){ return NULL; }
1229+ return &(WeaponIndex[id]);
1230+}
1231+
1232+//! @brief 指定したデータ番号のsmallobjectクラスを取得
1233+//! @param id データ番号
1234+//! @return 小物オブジェクトのポインタ (無効なデータ番号で NULL)
1235+smallobject* ObjectManager::GetSmallObject(int id)
1236+{
1237+ if( (id < 0)||(MAX_SMALLOBJECT-1 < id) ){ return NULL; }
1238+ return &(SmallObjectIndex[id]);
1239+}
1240+
1241+//! @brief 指定したデータ番号のbulletクラスを取得
1242+//! @param id データ番号
1243+//! @return 弾オブジェクトのポインタ (無効なデータ番号で NULL)
1244+bullet* ObjectManager::GetBulletObject(int id)
1245+{
1246+ if( (id < 0)||(MAX_BULLET-1 < id) ){ return NULL; }
1247+ return &(BulletIndex[id]);
1248+}
1249+
1250+//! @brief 使用されていないbulletクラスを取得
1251+//! @return 現在未使用の弾オブジェクトのポインタ (失敗すると NULL)
1252+bullet* ObjectManager::GetNewBulletObject()
1253+{
1254+ for(int i=0; i<MAX_BULLET; i++){
1255+ if( BulletIndex[i].GetDrawFlag() == false ){
1256+ return &(BulletIndex[i]);
1257+ }
1258+ }
1259+ return NULL;
1260+}
1261+
1262+//! @brief 使用されていないgrenadeクラスを取得
1263+//! @return 現在未使用の手榴弾オブジェクトのポインタ (失敗すると NULL)
1264+grenade* ObjectManager::GetNewGrenadeObject()
1265+{
1266+ for(int i=0; i<MAX_GRENADE; i++){
1267+ if( GrenadeIndex[i].GetDrawFlag() == false ){
1268+ return &(GrenadeIndex[i]);
1269+ }
1270+ }
1271+ return NULL;
1272+}
1273+
1274+//! @brief 人を検索
1275+//! @param p4 検索対象の認識番号
1276+//! @return 該当したhumanクラスのポインタ (見つからない場合はNULL)
1277+//! @attention 複数該当する場合、最初に該当したデータを返します。
1278+human* ObjectManager::SearchHuman(signed char p4)
1279+{
1280+ signed char humanp4;
1281+
1282+ for(int i=0; i<MAX_HUMAN; i++){
1283+ //使われていない人ならば処理しない
1284+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
1285+
1286+ //第4パラメータを取得
1287+ HumanIndex[i].GetParamData(NULL, NULL, &humanp4, NULL);
1288+
1289+ //指定されたp4と一致すれば返す
1290+ if( humanp4 == p4 ){
1291+ return &(HumanIndex[i]);
1292+ }
1293+ }
1294+ return NULL;
1295+}
1296+
1297+//! @brief 小物を検索
1298+//! @param p4 検索対象の認識番号
1299+//! @return 該当したsmallobjectクラスのポインタ (見つからない場合はNULL)
1300+//! @attention 複数該当する場合、最初に該当したデータを返します。
1301+smallobject* ObjectManager::SearchSmallobject(signed char p4)
1302+{
1303+ signed char smallobjectp4;
1304+
1305+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1306+ //使われていない人ならば処理しない
1307+ // 【破壊積みのオブジェクトも判定するため、無効】
1308+ //if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; }
1309+
1310+ //第4パラメータを取得
1311+ SmallObjectIndex[i].GetParamData(NULL, &smallobjectp4);
1312+
1313+ //指定されたp4と一致すれば返す
1314+ if( smallobjectp4 == p4 ){
1315+ return &(SmallObjectIndex[i]);
1316+ }
1317+ }
1318+ return NULL;
1319+}
1320+
1321+//! @brief 前進(走り)を実行
1322+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1323+void ObjectManager::MoveForward(int human_id)
1324+{
1325+ //値の範囲をチェック
1326+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1327+
1328+ //オブジェクトにフラグを設定
1329+ HumanIndex[human_id].SetMoveForward();
1330+
1331+ //走る足音追加
1332+ float posx, posy, posz;
1333+ int teamid;
1334+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1335+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1336+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1337+}
1338+
1339+//! @brief 後退を実行
1340+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1341+void ObjectManager::MoveBack(int human_id)
1342+{
1343+ //値の範囲をチェック
1344+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1345+
1346+ //オブジェクトにフラグを設定
1347+ HumanIndex[human_id].SetMoveBack();
1348+
1349+ //走る足音追加
1350+ float posx, posy, posz;
1351+ int teamid;
1352+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1353+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1354+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1355+}
1356+
1357+//! @brief 左走りを実行
1358+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1359+void ObjectManager::MoveLeft(int human_id)
1360+{
1361+ //値の範囲をチェック
1362+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1363+
1364+ //オブジェクトにフラグを設定
1365+ HumanIndex[human_id].SetMoveLeft();
1366+
1367+ //走る足音追加
1368+ float posx, posy, posz;
1369+ int teamid;
1370+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1371+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1372+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1373+}
1374+
1375+//! @brief 右走りを実行
1376+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1377+void ObjectManager::MoveRight(int human_id)
1378+{
1379+ //値の範囲をチェック
1380+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1381+
1382+ //オブジェクトにフラグを設定
1383+ HumanIndex[human_id].SetMoveRight();
1384+
1385+ //走る足音追加
1386+ float posx, posy, posz;
1387+ int teamid;
1388+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1389+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1390+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1391+}
1392+
1393+//! @brief 歩きを実行
1394+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1395+void ObjectManager::MoveWalk(int human_id)
1396+{
1397+ //値の範囲をチェック
1398+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1399+
1400+ //オブジェクトにフラグを設定
1401+ HumanIndex[human_id].SetMoveWalk();
1402+}
1403+
1404+//! @brief ジャンプ
1405+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1406+void ObjectManager::MoveJump(int human_id)
1407+{
1408+ //値の範囲をチェック
1409+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1410+
1411+ HumanIndex[human_id].Jump();
1412+}
1413+
1414+//! @brief 発砲
1415+//! @param human_id 発砲する人番号
1416+//! @return 通常弾発射:1 手榴弾発射:2 失敗:0
1417+int ObjectManager::ShotWeapon(int human_id)
1418+{
1419+ //値の範囲をチェック
1420+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return 0; }
1421+
1422+ human *MyHuman = &(HumanIndex[human_id]);
1423+
1424+ float pos_x, pos_y, pos_z;
1425+ int teamid;
1426+ float rotation_x, armrotation_y;
1427+ int weapon_paramid;
1428+ int GunsightErrorRange;
1429+ WeaponParameter ParamData;
1430+ bool playerflag;
1431+ bool grenadeflag;
1432+
1433+ //人の座標と角度を取得
1434+ MyHuman->GetPosData(&pos_x, &pos_y, &pos_z, NULL);
1435+ MyHuman->GetParamData(NULL, NULL, NULL, &teamid);
1436+ MyHuman->GetRxRy(&rotation_x, &armrotation_y);
1437+
1438+ //対象者がプレイヤー自身か判定
1439+ if( MyHuman == &(HumanIndex[Player_HumanID]) ){
1440+ playerflag = true;
1441+ }
1442+ else{
1443+ playerflag = false;
1444+ }
1445+
1446+ //弾の発射を要求
1447+ if( MyHuman->ShotWeapon(&weapon_paramid, &GunsightErrorRange) == false ){ return 0; }
1448+
1449+ //武器の情報を取得
1450+ if( GameParamInfo->GetWeapon(weapon_paramid, &ParamData) != 0 ){ return 0; }
1451+
1452+ //誤差の範囲を計算
1453+ int ErrorRange;
1454+ ErrorRange = GunsightErrorRange;
1455+ if( ErrorRange < ParamData.ErrorRangeMIN ){ ErrorRange = ParamData.ErrorRangeMIN; }
1456+
1457+ //手榴弾か判定
1458+ if( weapon_paramid == ID_WEAPON_GRENADE ){ grenadeflag = true; }
1459+ else{ grenadeflag = false; }
1460+
1461+ class bullet* newbullet;
1462+ class grenade* newgrenade;
1463+
1464+ //(ショットガンなど)発射する弾の数分繰り返す
1465+ for(int i=0; i<ParamData.burst; i++){
1466+ //発射角度を決定
1467+ float rx, ry;
1468+ rx = rotation_x*-1 + (float)M_PI/2;
1469+ ry = armrotation_y;
1470+
1471+ //誤差分 加算する
1472+ float a;
1473+ a = (float)M_PI/180 * GetRand(360);
1474+ rx += cos(a)*ErrorRange * ((float)M_PI/180*0.15f);
1475+ ry += sin(a)*ErrorRange * ((float)M_PI/180*0.15f);
1476+
1477+ //手榴弾でなければ
1478+ if( grenadeflag == false ){
1479+ int attacks;
1480+
1481+ //(ショットガンなど)発射する弾が複数あれば
1482+ if( ParamData.burst > 1 ){
1483+ //1個の弾当たりの攻撃力を算出
1484+ //  全弾合わせて、攻撃力の2倍になるようにする。
1485+ attacks = (int)( (float)ParamData.attacks / ((float)ParamData.burst/2) );
1486+ }
1487+ else{
1488+ //そのまま攻撃力へ反映
1489+ attacks = ParamData.attacks;
1490+ }
1491+
1492+ //発射する未使用のオブジェクトを取得
1493+ newbullet = GetNewBulletObject();
1494+ if( newbullet == NULL ){ break; }
1495+
1496+ //銃弾を発射
1497+ newbullet->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry);
1498+ newbullet->SetParamData(attacks, ParamData.penetration, ParamData.speed * BULLET_SPEEDSCALE, teamid, human_id, true);
1499+ newbullet->SetDrawFlag(true);
1500+ }
1501+ else{
1502+ //発射する未使用のオブジェクトを取得
1503+ newgrenade = GetNewGrenadeObject();
1504+ if( newgrenade == NULL ){ break; }
1505+
1506+ //手榴弾発射
1507+ newgrenade->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry);
1508+ newgrenade->SetParamData(8.0f, human_id, true);
1509+ newgrenade->SetDrawFlag(true);
1510+ }
1511+
1512+ //誤差を加算(ショットガン用)
1513+ ErrorRange += ParamData.ErrorRangeMIN;
1514+ }
1515+
1516+ //手榴弾でなければ
1517+ if( grenadeflag == false ){
1518+ //発砲フラグを設定
1519+ Human_ShotFlag[human_id] = true;
1520+ }
1521+
1522+ if( ParamData.soundvolume > 0 ){
1523+ //銃声を再生
1524+ GameSound->ShotWeapon(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, weapon_paramid, teamid, playerflag);
1525+ }
1526+
1527+ if( grenadeflag == true ){
1528+ return 2;
1529+ }
1530+ return 1;
1531+}
1532+
1533+//! @brief マズルフラッシュを設定
1534+//! @param humanid 人の番号
1535+//! @attention この関数の呼び出しタイミングを誤ると、銃口に対してマズルフラッシュが合いません。
1536+void ObjectManager::ShotWeaponEffect(int humanid)
1537+{
1538+ float pos_x, pos_y, pos_z;
1539+ float rotation_x, armrotation_y;
1540+ int weapon_paramid;
1541+ WeaponParameter ParamData;
1542+ float x, y, z;
1543+ float flashsize, smokesize, yakkyousize;
1544+ float rx, mx, my, mz;
1545+
1546+ //人の座標と角度を取得
1547+ HumanIndex[humanid].GetPosData(&pos_x, &pos_y, &pos_z, NULL);
1548+ HumanIndex[humanid].GetRxRy(&rotation_x, &armrotation_y);
1549+
1550+ //武器の情報を取得
1551+ weapon_paramid = HumanIndex[humanid].GetMainWeaponTypeNO();
1552+ if( GameParamInfo->GetWeapon(weapon_paramid, &ParamData) != 0 ){ return; }
1553+
1554+ //マズルフラッシュと煙のサイズを決定
1555+ flashsize = 0.06f * ParamData.attacks;
1556+ smokesize = flashsize;
1557+ yakkyousize = 0.01f * ParamData.attacks;
1558+ if( ParamData.silencer == true ){
1559+ flashsize /= 2;
1560+ }
1561+
1562+ //薬莢の移動量を決定
1563+ rx = rotation_x*-1 + (float)M_PI/2;
1564+ mx = cos(rx - (float)M_PI/2) * ParamData.yakkyou_sx /10;
1565+ my = (ParamData.yakkyou_sy + (GetRand(3)-1)) /10;
1566+ mz = sin(rx - (float)M_PI/2) * ParamData.yakkyou_sx /10;
1567+
1568+ //行列でエフェクト座標を計算
1569+ 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);
1570+ d3dg->GetWorldTransformPos(&x, &y, &z);
1571+ d3dg->ResetWorldTransform();
1572+
1573+ //マズルフラッシュ描画
1574+ AddEffect(x, y, z, 0.0f, 0.0f, 0.0f, flashsize, (float)M_PI/18*GetRand(18), 1, Resource->GetEffectMflashTexture(), EFFECT_NORMAL);
1575+
1576+ //行列でエフェクト座標を計算
1577+ d3dg->SetWorldTransformHumanWeapon(pos_x, pos_y + 16.0f, pos_z, ParamData.flashx/10, ParamData.flashy/10, ParamData.flashz/10 - 0.1f, rotation_x, armrotation_y*-1, 1.0f);
1578+ d3dg->GetWorldTransformPos(&x, &y, &z);
1579+ d3dg->ResetWorldTransform();
1580+
1581+ //エフェクト(煙)の表示
1582+ AddEffect(x, y, z, 0.0f, 0.05f, 0.0f, smokesize, (float)M_PI/18*GetRand(18), (int)(GAMEFPS/3), Resource->GetEffectSmokeTexture(), EFFECT_DISAPPEAR | EFFECT_MAGNIFY | EFFECT_ROTATION);
1583+
1584+ //行列でエフェクト座標を計算
1585+ 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);
1586+ d3dg->GetWorldTransformPos(&x, &y, &z);
1587+ d3dg->ResetWorldTransform();
1588+
1589+ //薬莢描画
1590+ AddEffect(x, y, z, mx, my, mz, yakkyousize, (float)M_PI/18*GetRand(18), (int)(GAMEFPS/2), Resource->GetEffectYakkyouTexture(), EFFECT_ROTATION | EFFECT_FALL);
1591+}
1592+
1593+//! @brief 武器をリロード
1594+//! @param human_id 対象の人番号
1595+void ObjectManager::ReloadWeapon(int human_id)
1596+{
1597+ //値の範囲をチェック
1598+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1599+
1600+ //無効な人ならば処理しない
1601+ if( HumanIndex[human_id].GetDrawFlag() == false ){ return; }
1602+ if( HumanIndex[human_id].GetHP() <= 0 ){ return; }
1603+
1604+ //リロードを実行
1605+ if( HumanIndex[human_id].ReloadWeapon() == true ){
1606+ float x, y, z;
1607+ int id;
1608+
1609+ //人の座標とチーム番号を取得
1610+ HumanIndex[human_id].GetPosData(&x, &y, &z, NULL);
1611+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &id);
1612+ y += 16.0f;
1613+
1614+ //音源を配置
1615+ GameSound->ReloadWeapon(x, y, z, id);
1616+ }
1617+}
1618+
1619+//! @brief 武器を切り替える(持ち替える)
1620+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1621+//! @param id 持ち替える武器 (-1 で次の武器)
1622+void ObjectManager::ChangeWeapon(int human_id, int id)
1623+{
1624+ //値の範囲をチェック
1625+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1626+
1627+ HumanIndex[human_id].ChangeWeapon(id);
1628+}
1629+
1630+//! @brief 武器を捨てる
1631+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1632+//! @return 成功:true 失敗:false
1633+bool ObjectManager::DumpWeapon(int human_id)
1634+{
1635+ //値の範囲をチェック
1636+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1637+
1638+ return HumanIndex[human_id].DumpWeapon();
1639+}
1640+
1641+//! @brief スコープモードを切り替え
1642+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1643+void ObjectManager::ChangeScopeMode(int human_id)
1644+{
1645+ //値の範囲をチェック
1646+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1647+
1648+ if( HumanIndex[human_id].GetScopeMode() == 0 ){ //スコープを使用していなければ、スコープを設定
1649+ HumanIndex[human_id].SetEnableScope();
1650+ }
1651+ else{ //使用中なら、解除
1652+ HumanIndex[human_id].SetDisableScope();
1653+ }
1654+}
1655+
1656+//! @brief 武器のショットモード切り替え
1657+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1658+//! @return 成功:0 失敗:1
1659+int ObjectManager::ChangeShotMode(int human_id)
1660+{
1661+ //値の範囲をチェック
1662+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return 1; }
1663+
1664+ return HumanIndex[human_id].ChangeShotMode();
1665+}
1666+
1667+//! @brief 裏技・所持している武器の弾を追加
1668+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1669+//! @return 成功:true 失敗:false
1670+bool ObjectManager::CheatAddBullet(int human_id)
1671+{
1672+ //値の範囲をチェック
1673+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1674+
1675+ int selectweapon;
1676+ weapon *weapon[TOTAL_HAVEWEAPON];
1677+ int id_param, lnbs, nbs;
1678+ WeaponParameter ParamData;
1679+
1680+ //所持している武器を取得
1681+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1682+ weapon[i] = NULL;
1683+ }
1684+ HumanIndex[human_id].GetWeapon(&selectweapon, weapon);
1685+
1686+ //何かしらの武器を持っていれば
1687+ if( weapon[selectweapon] != NULL ){
1688+ //武器の種類と弾数、武器の設定値を取得
1689+ weapon[selectweapon]->GetParamData(&id_param, &lnbs, &nbs);
1690+ if( GameParamInfo->GetWeapon(id_param, &ParamData) == 0 ){
1691+ //最大弾数分加算し、適用
1692+ nbs += ParamData.nbsmax;
1693+ weapon[selectweapon]->ResetWeaponParam(Resource, id_param, lnbs, nbs);
1694+ return true;
1695+ }
1696+ }
1697+
1698+ return false;
1699+}
1700+
1701+//! @brief 裏技・所持している武器を変更
1702+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1703+//! @param new_weaponID 新たに設定する武器の種類番号
1704+//! @return 成功:true 失敗:false
1705+bool ObjectManager::CheatNewWeapon(int human_id, int new_weaponID)
1706+{
1707+ //値の範囲をチェック
1708+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1709+ if( (new_weaponID < 0)||(TOTAL_PARAMETERINFO_WEAPON <= new_weaponID) ){ return false; }
1710+
1711+ human *myHuman = &(HumanIndex[human_id]);
1712+
1713+ int selectweapon;
1714+ weapon *weapon[TOTAL_HAVEWEAPON];
1715+ int lnbs, nbs;
1716+
1717+ //所持している武器を取得
1718+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1719+ weapon[i] = NULL;
1720+ }
1721+ myHuman->GetWeapon(&selectweapon, weapon);
1722+
1723+ //現在武器を所有しておらず、新たに持たせる武器もないなら
1724+ if( (weapon[selectweapon] == NULL)&&(new_weaponID == ID_WEAPON_NONE) ){
1725+ return false; //処理自体が無意味
1726+ }
1727+
1728+ if( weapon[selectweapon] == NULL ){ //武器を所有していなければ
1729+ int dataid = -1;
1730+
1731+ //新しい武器を配置
1732+ dataid = AddVisualWeaponIndex(new_weaponID, false);
1733+
1734+ //武器が配置できれば、武器を持たせる
1735+ if( dataid != -1 ){
1736+ weapon[selectweapon] = &(WeaponIndex[dataid]);
1737+ myHuman->SetWeapon(weapon);
1738+ return true;
1739+ }
1740+ }
1741+ else{ //武器を所有していれば
1742+ if( new_weaponID == ID_WEAPON_NONE ){ //武器を消すなら
1743+ //一度武器を捨てた上で、その武器を削除
1744+ if( myHuman->DumpWeapon() == true ){
1745+ weapon[selectweapon]->SetDrawFlag(false);
1746+ return true;
1747+ }
1748+ }
1749+ else{ //武器を変更するなら
1750+ //武器設定を取得(弾数設定を引き継ぐため)
1751+ weapon[selectweapon]->GetParamData(NULL, &lnbs, &nbs);
1752+
1753+ //武器設定を適用
1754+ weapon[selectweapon]->ResetWeaponParam(Resource, new_weaponID, lnbs, nbs);
1755+
1756+ return true;
1757+ }
1758+ }
1759+
1760+ return false;
1761+}
1762+
1763+//! @brief ゾンビの攻撃を受けるか判定
1764+//! @param MyHuman 攻撃する人オブジェクト(ゾンビ側)のポインタ
1765+//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ
1766+//! @return 成立:true 不成立:false
1767+//! @warning MyHuman はゾンビ以外も指定できます。<b>ゾンビかどうかは判定しない</b>ため、ゾンビであるか予め確認しておく必要があります。
1768+//! @attention 判定のみを実施します。この判定が成立したら HitZombieAttack()関数 を呼び出してください。
1769+bool ObjectManager::CheckZombieAttack(human* MyHuman, human* EnemyHuman)
1770+{
1771+ if( MyHuman == NULL ){ return false; }
1772+ if( EnemyHuman == NULL ){ return false; }
1773+
1774+ //使用されていないか、死亡していれば処理しない。
1775+ if( MyHuman->GetDrawFlag() == false ){ return false; }
1776+ if( MyHuman->GetHP() <= 0 ){ return false; }
1777+ if( EnemyHuman->GetDrawFlag() == false ){ return false; }
1778+ if( EnemyHuman->GetHP() <= 0 ){ return false; }
1779+
1780+ float mx, my, mz, mrx, tx, ty, tz;
1781+ int mteam, tteam;
1782+ float AttackPoint_x, AttackPoint_y, AttackPoint_z;
1783+ float ax, az;
1784+
1785+ MyHuman->GetPosData(&mx, &my, &mz, &mrx);
1786+ MyHuman->GetParamData(NULL, NULL, NULL, &mteam);
1787+ my += VIEW_HEIGHT;
1788+ EnemyHuman->GetPosData(&tx, &ty, &tz, NULL);
1789+ EnemyHuman->GetParamData(NULL, NULL, NULL, &tteam);
1790+ ty += VIEW_HEIGHT;
1791+
1792+ //味方ならば処理しない
1793+ if( mteam == tteam ){ return false; }
1794+
1795+ //攻撃ポイント(腕の先端)を求める
1796+ AttackPoint_x = mx + cos(mrx*-1 + (float)M_PI/2) * 2.0f;
1797+ AttackPoint_y = my + VIEW_HEIGHT - 0.5f;
1798+ AttackPoint_z = mz + sin(mrx*-1 + (float)M_PI/2) * 2.0f;
1799+ ax = AttackPoint_x - tx;
1800+ az = AttackPoint_z - tz;
1801+
1802+ //敵(攻撃対象)が攻撃ポイントに触れていれば、当たっている
1803+ if( (ax*ax + az*az) < 3.3f*3.3f ){
1804+ if( (AttackPoint_y >= ty)&&(AttackPoint_y <= (ty + HUMAN_HEIGTH)) ){
1805+ return true;
1806+ }
1807+ }
1808+
1809+ return false;
1810+}
1811+
1812+//! @brief ゾンビの攻撃を受けた処理
1813+//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ
1814+void ObjectManager::HitZombieAttack(human* EnemyHuman)
1815+{
1816+ if( EnemyHuman == NULL ){ return; }
1817+
1818+ //使用されていないか、死亡していれば処理しない。
1819+ if( EnemyHuman->GetDrawFlag() == false ){ return; }
1820+ if( EnemyHuman->GetHP() <= 0 ){ return; }
1821+
1822+ float tx, ty, tz;
1823+
1824+ EnemyHuman->GetPosData(&tx, &ty, &tz, NULL);
1825+ ty += VIEW_HEIGHT;
1826+
1827+ //ダメージなどを計算
1828+ EnemyHuman->HitZombieAttack();
1829+
1830+ //エフェクト(血)を表示
1831+ SetHumanBlood(tx, ty, tz);
1832+
1833+ //効果音を再生
1834+ GameSound->HitHuman(tx, ty, tz);
1835+}
1836+
1837+//! @brief 死者を蘇生する
1838+//! @param id 人の番号(0〜MAX_HUMAN-1)
1839+//! @return true:成功 false:失敗
1840+//! @warning 手ぶらのまま蘇生します
1841+//! @attention 無効な人番号が指定された場合や、指定した人が生存していた場合、あるいは謎人間に対して実行した場合、この関数は失敗します。
1842+bool ObjectManager::HumanResuscitation(int id)
1843+{
1844+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return false; }
1845+
1846+ //使用されていないか、生存していれば処理しない。
1847+ if( HumanIndex[id].GetDrawFlag() == false ){ return false; }
1848+ if( HumanIndex[id].GetDeadFlag() == false ){ return false; }
1849+
1850+ int id_param, dataid, team;
1851+ signed char p4;
1852+ HumanIndex[id].GetParamData(&id_param, &dataid, &p4, &team);
1853+ if( (id_param < 0)||( TOTAL_PARAMETERINFO_HUMAN-1 < id_param) ){ return false; } //謎人間なら処理しない
1854+ HumanIndex[id].SetParamData(id_param, dataid, p4, team, true);
1855+
1856+ return true;
1857+}
1858+
1859+//! @brief ゲームクリアー・ゲームオーバーの判定
1860+//! @return ゲームクリアー:1 ゲームオーバー:2 判定なし:0
1861+//! @attention ゲームクリア―とゲームオーバーが同時に成立する条件では、本家XOPSと同様に「ゲームクリアー」と判定されます。
1862+int ObjectManager::CheckGameOverorComplete()
1863+{
1864+ //メモ:
1865+ //
1866+ // 本来は、ゲームオーバー判定を先に行い、次にゲームクリアー判定を実装した方が効率的です。
1867+ // プレイヤーのHPが 0 ならば即ゲームオーバーとして判定し、敵の中でHPが残っている者を見つけた時点で 判定なし、
1868+ // 2つの条件に当てはまらなければ、自動的にゲームクリアーとなります。
1869+ //
1870+ // しかし、本家XOPSはゲームクリアーの判定を優先するため、先にゲームクリアーの判定を行っています。
1871+ // 生きている敵の数を(総HPとして)数え、敵の数(総HP)が 0 ならば、ゲームクリアーと判定します。
1872+ // まぁこのように1つの関数で処理しようとせずに、ゲームクリアーとゲームオーバーで関数自体を分けても良いのですがね・・。
1873+
1874+ //ゲームクリアー判定
1875+ int MyTeamid, teamid;
1876+ int TotalEnemyHP = 0;
1877+ HumanIndex[Player_HumanID].GetParamData(NULL, NULL, NULL, &MyTeamid); //プレイヤーのチーム番号を取得
1878+ for(int i=0; i<MAX_HUMAN; i++){
1879+ //初期化されていなければ処理しない
1880+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
1881+
1882+ //調べる対象のチーム番号を取得
1883+ HumanIndex[i].GetParamData(NULL, NULL, NULL, &teamid);
1884+
1885+ //異なるチーム番号(=敵)ならば
1886+ if( teamid != MyTeamid ){
1887+ //生きていれば、敵のHPとして加算
1888+ //if( HumanIndex[i].GetHP() > 0 ){
1889+ if( HumanIndex[i].GetDeadFlag() == false ){
1890+ TotalEnemyHP += HumanIndex[i].GetHP();
1891+ }
1892+ }
1893+ }
1894+ if( TotalEnemyHP == 0 ){ //全敵のHPが 0 ならば
1895+ return 1;
1896+ }
1897+
1898+
1899+ //ゲームオーバー判定
1900+ if( HumanIndex[Player_HumanID].GetDrawFlag() == true ){ //操作対象が有効ならば (注:裏技による変更対策)
1901+ if( HumanIndex[Player_HumanID].GetDeadFlag() == true ){ //プレイヤーが死亡していれば
1902+ return 2;
1903+ }
1904+ }
1905+
1906+ return 0;
1907+}
1908+
1909+//! @brief オブジェクトの情報を取得
1910+//! @param camera_x カメラのX座標
1911+//! @param camera_y カメラのY座標
1912+//! @param camera_z カメラのZ座標
1913+//! @param camera_rx カメラの横軸角度
1914+//! @param camera_ry カメラの縦軸角度
1915+//! @param color 色を取得するポインタ
1916+//! @param infostr 文字を取得するポインタ
1917+//! @return 表示情報あり:true 表示情報なし:false
1918+bool ObjectManager::GetObjectInfoTag(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, int *color, char *infostr)
1919+{
1920+ float dist = 50.0f;
1921+ float px, py, pz;
1922+ float rx, ry;
1923+ float r;
1924+ int Player_teamID;
1925+
1926+ //文字を初期化
1927+ infostr[0] = NULL;
1928+
1929+ //プレイヤーのチーム番号を取得
1930+ HumanIndex[Player_HumanID].GetParamData(NULL, NULL, NULL, &Player_teamID);
1931+
1932+ //人
1933+ for(int i=0; i<MAX_HUMAN; i++){
1934+ //プレイヤー自身なら処理しない
1935+ if( i == Player_HumanID ){ continue; }
1936+
1937+ if( HumanIndex[i].GetDrawFlag() == true ){
1938+ HumanIndex[i].GetPosData(&px, &py, &pz, NULL);
1939+
1940+ //視点を基準に対象までの角度を算出
1941+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, 0.0f, px, py, pz, dist, &rx, NULL, &r) == true ){
1942+ int team;
1943+
1944+ //角度上、視界に入っていれば
1945+ if( abs(rx) < (float)M_PI/18 ){
1946+ HumanIndex[i].GetParamData(NULL, NULL, NULL, &team);
1947+ if( team == Player_teamID ){
1948+ *color = d3dg->GetColorCode(0.0f,0.0f,1.0f,1.0f);
1949+ sprintf(infostr, "Human[%d] HP %d : Friend", i, HumanIndex[i].GetHP());
1950+ }
1951+ else{
1952+ *color = d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f);
1953+ sprintf(infostr, "Human[%d] HP %d : Enemy", i, HumanIndex[i].GetHP());
1954+ }
1955+ dist = sqrt(r);
1956+ }
1957+ }
1958+ }
1959+ }
1960+
1961+ //武器
1962+ for(int i=0; i<MAX_WEAPON; i++){
1963+ if( (WeaponIndex[i].GetDrawFlag() == true)&&(WeaponIndex[i].GetUsingFlag() == false) ){
1964+ int lnbs, nbs;
1965+
1966+ WeaponIndex[i].GetPosData(&px, &py, &pz, NULL);
1967+ WeaponIndex[i].GetParamData(NULL, &lnbs, &nbs);
1968+
1969+ //視点を基準に対象までの角度を算出
1970+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, camera_ry, px, py, pz, dist, &rx, &ry, &r) == true ){
1971+ //角度上、視界に入っていれば
1972+ if( (abs(rx) < (float)M_PI/18)&&(abs(ry) < (float)M_PI/18) ){
1973+ *color = d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f);
1974+ sprintf(infostr, "Weapon[%d] %d:%d", i, lnbs, (nbs - lnbs));
1975+ dist = sqrt(r);
1976+ }
1977+ }
1978+ }
1979+ }
1980+
1981+ //小物
1982+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1983+ if( SmallObjectIndex[i].GetDrawFlag() == true ){
1984+ SmallObjectIndex[i].GetPosData(&px, &py, &pz, NULL);
1985+
1986+ //視点を基準に対象までの角度を算出
1987+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, camera_ry, px, py, pz, dist, &rx, &ry, &r) == true ){
1988+ //角度上、視界に入っていれば
1989+ if( (abs(rx) < (float)M_PI/18)&&(abs(ry) < (float)M_PI/18) ){
1990+ *color = d3dg->GetColorCode(1.0f,1.0f,0.0f,1.0f);
1991+ sprintf(infostr, "SmallObject[%d] HP %d", i, SmallObjectIndex[i].GetHP());
1992+ dist = sqrt(r);
1993+ }
1994+ }
1995+ }
1996+ }
1997+
1998+ //文字が設定されているかどうかで、有効な処理がされたか判定。
1999+ if( infostr[0] == NULL ){
2000+ return false;
2001+ }
2002+ return true;
2003+}
2004+
2005+//! @brief オブジェクトの主計算処理
2006+//! @param cmdF5id 上昇機能(F5裏技)させる人データ番号(-1で機能無効)
2007+//! @param camera_rx カメラの横軸角度
2008+//! @param camera_ry カメラの縦軸角度
2009+//! @return 常に 0
2010+//! @attention 一般的に cmdF5id は、F5裏技使用中はプレイヤー番号(GetPlayerID()関数で取得)、未使用時は -1 を指定します。
2011+int ObjectManager::Process(int cmdF5id, float camera_rx, float camera_ry)
2012+{
2013+ //このフレームの戦歴を初期化
2014+ for(int i=0; i<MAX_HUMAN; i++){
2015+ Human_ontarget[i] = 0;
2016+ Human_kill[i] = 0;
2017+ Human_headshot[i] = 0;
2018+ }
2019+
2020+ //人オブジェクトの処理
2021+ for(int i=0; i<MAX_HUMAN; i++){
2022+ bool cmdF5;
2023+
2024+ if( i == cmdF5id ){
2025+ cmdF5 = true;
2026+ }
2027+ else{
2028+ cmdF5 = false;
2029+ }
2030+
2031+ if( HumanIndex[i].RunFrame(CollD, BlockData, cmdF5) == 2 ){
2032+ //死亡時のエフェクト
2033+ DeadEffect(&(HumanIndex[i]));
2034+ }
2035+ }
2036+
2037+ //武器オブジェクトの処理
2038+ for(int i=0; i<MAX_WEAPON; i++){
2039+ WeaponIndex[i].RunFrame(CollD);
2040+ }
2041+
2042+ //小物オブジェクトの処理
2043+ for(int i=0; i<MAX_SMALLOBJECT; i++){
2044+ SmallObjectIndex[i].RunFrame();
2045+ }
2046+
2047+ //弾オブジェクトの処理
2048+ for(int i=0; i<MAX_BULLET; i++){
2049+ float bx, by, bz, brx, bry;
2050+ int speed;
2051+ float mx, my, mz;
2052+
2053+ CollideBullet(&BulletIndex[i]); //当たり判定を実行
2054+ BulletIndex[i].RunFrame(); //主計算
2055+
2056+ if( BulletIndex[i].GetDrawFlag() == true ){
2057+ //弾の座標と角度を取得
2058+ BulletIndex[i].GetParamData(NULL, NULL, &speed, NULL, NULL);
2059+ BulletIndex[i].GetPosData(&bx, &by, &bz, &brx, &bry);
2060+ mx = cos(brx)*cos(bry)*speed;
2061+ my = sin(bry)*speed;
2062+ mz = sin(brx)*cos(bry)*speed;
2063+ GameSound->PassingBullet(bx, by, bz, mx, my, mz);
2064+ }
2065+ }
2066+
2067+ //武器を発砲した際のエフェクトを出す
2068+ for(int i=0; i<MAX_HUMAN; i++){
2069+ if( Human_ShotFlag[i] == true ){
2070+ ShotWeaponEffect(i);
2071+ Human_ShotFlag[i] = false;
2072+ }
2073+ }
2074+
2075+ //エフェクトオブジェクトの処理
2076+ for(int i=0; i<MAX_EFFECT; i++){
2077+ EffectIndex[i].RunFrame(camera_rx, camera_ry);
2078+ }
2079+
2080+ //手榴弾の処理
2081+ for(int i=0; i<MAX_GRENADE; i++){
2082+ float speed = GrenadeIndex[i].GetSpeed();
2083+
2084+ //主計算
2085+ int rcr = GrenadeIndex[i].RunFrame(CollD, BlockData);
2086+
2087+ //バウンド・跳ね返ったならば
2088+ if( rcr == 1 ){
2089+ if( speed > 3.4f ){
2090+ //座標を取得し、効果音再生
2091+ float x, y, z;
2092+ GrenadeIndex[i].GetPosData(&x, &y, &z, NULL, NULL);
2093+ GameSound->GrenadeBound(x, y, z);
2094+ }
2095+ }
2096+
2097+ //爆発したなら
2098+ if( rcr == 2 ){
2099+ GrenadeExplosion(&(GrenadeIndex[i]));
2100+ }
2101+ }
2102+
2103+
2104+ //武器を拾う処理
2105+ for(int i=0; i<MAX_HUMAN; i++){
2106+ //武器を拾うだけで毎フレーム総当たりで処理する意味はないので、各武器2フレームに1回処理にケチってます (^^;
2107+ //フレーム数が偶数目の時は、データ番号が偶数の武器。奇数の時は、奇数の武器を処理。
2108+ for(int j=(framecnt%2); j<MAX_WEAPON; j+=2){
2109+ PickupWeapon(&HumanIndex[i], &WeaponIndex[j]);
2110+ }
2111+ }
2112+
2113+ for(int i=0; i<MAX_HUMAN; i++){
2114+ for(int j=i+1; j<MAX_HUMAN; j++){
2115+ //人同士の当たり判定(押し合い)
2116+ CollideHuman(&HumanIndex[i], &HumanIndex[j]);
2117+ }
2118+ }
2119+
2120+ framecnt += 1;
2121+
2122+ return 0;
2123+}
2124+
2125+//! @brief 現フレームの 命中率・倒した敵の数・ヘットショット数 の取得
2126+//! @param id 取得する人のデータ番号
2127+//! @param ontarget 命中数を受け取るポインタ
2128+//! @param kill 倒した敵の数を受け取るポインタ
2129+//! @param headshot 敵の頭部に命中した数を受け取るポインタ
2130+//! @return 成功:true 失敗:false
2131+bool ObjectManager::GetHumanShotInfo(int id, int *ontarget, int *kill, int *headshot)
2132+{
2133+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return false; }
2134+ *ontarget = Human_ontarget[id];
2135+ *kill = Human_kill[id];
2136+ *headshot = Human_headshot[id];
2137+ return true;
2138+}
2139+
2140+//! @brief エフェクトをソートする
2141+//! @param camera_x カメラのX座標
2142+//! @param camera_y カメラのY座標
2143+//! @param camera_z カメラのZ座標
2144+//! @param data 結果を受け取る effectdata構造体 (要素数:MAX_EFFECT)
2145+//! @return 有効なエフェクトの数
2146+int ObjectManager::SortEffect(float camera_x, float camera_y, float camera_z, effectdata data[])
2147+{
2148+ int cnt = 0;
2149+
2150+ //カメラからの距離を求めつつ、総数を数える。
2151+ for(int i=0; i<MAX_EFFECT; i++){
2152+ if( EffectIndex[i].GetDrawFlag() == true ){
2153+ float ex, ey, ez;
2154+ float x, y, z;
2155+
2156+ //座標を取得し、距離を計算、データに登録。
2157+ EffectIndex[i].GetPosData(&ex, &ey, &ez, NULL);
2158+ x = ex - camera_x;
2159+ y = ey - camera_y;
2160+ z = ez - camera_z;
2161+ data[cnt].id = i;
2162+ data[cnt].dist = x*x + y*y + z*z;
2163+
2164+ //カウントを加算
2165+ cnt += 1;
2166+ }
2167+ }
2168+
2169+ //単純挿入ソート
2170+ effectdata temp;
2171+ for(int i=1; i<cnt; i++) {
2172+ int j;
2173+ temp = data[i];
2174+ for(j=i; j>0 && data[j-1].dist<temp.dist; j--){
2175+ data[j] = data[j-1];
2176+ }
2177+ data[j] = temp;
2178+ }
2179+
2180+ return cnt;
2181+}
2182+
2183+//! @brief オブジェクトの描画処理
2184+//! @param camera_x カメラのX座標
2185+//! @param camera_y カメラのY座標
2186+//! @param camera_z カメラのZ座標
2187+//! @param HidePlayer プレイヤーの非表示設定 (表示:0 非表示:1 腕と武器のみ表示:2)
2188+void ObjectManager::Render(float camera_x, float camera_y, float camera_z, int HidePlayer)
2189+{
2190+ //ワールド座標を原点へ
2191+ d3dg->ResetWorldTransform();
2192+
2193+ //人描画
2194+ for(int i=0; i<MAX_HUMAN; i++){
2195+ bool DrawArm, player;
2196+
2197+ //腕の表示
2198+ if( HidePlayer == 0 ){
2199+ DrawArm = false;
2200+ }
2201+ else if( Player_HumanID != i ){ // HidePlayer != 0
2202+ DrawArm = false;
2203+ }
2204+ else if( HidePlayer == 2 ){ // Player_HumanID == i
2205+ DrawArm = true;
2206+ }
2207+ else{ // Player_HumanID == i && HidePlayer == 1
2208+ continue; //プレイヤー自身を表示しないならスキップ
2209+ }
2210+
2211+ //プレイヤーかどうか判定
2212+ if( Player_HumanID == i ){
2213+ player = true;
2214+ }
2215+ else{
2216+ player = false;
2217+ }
2218+
2219+ HumanIndex[i].Render(d3dg, Resource, DrawArm, player);
2220+ }
2221+
2222+ //武器描画
2223+ for(int i=0; i<MAX_WEAPON; i++){
2224+ WeaponIndex[i].Render(d3dg);
2225+ }
2226+
2227+ //小物描画
2228+ for(int i=0; i<MAX_SMALLOBJECT; i++){
2229+ SmallObjectIndex[i].Render(d3dg);
2230+ }
2231+
2232+ //弾描画
2233+ for(int i=0; i<MAX_BULLET; i++){
2234+ BulletIndex[i].Render(d3dg);
2235+ }
2236+
2237+ //手榴弾描画
2238+ for(int i=0; i<MAX_GRENADE; i++){
2239+ GrenadeIndex[i].Render(d3dg);
2240+ }
2241+
2242+ //エフェクト描画
2243+ /*
2244+ for(int i=0; i<MAX_EFFECT; i++){
2245+ EffectIndex[i].Render(d3dg);
2246+ }
2247+ */
2248+ effectdata data[MAX_EFFECT];
2249+ int cnt = SortEffect(camera_x, camera_y, camera_z, data);
2250+ for(int i=0; i<cnt; i++) {
2251+ EffectIndex[ data[i].id ].Render(d3dg);
2252+ }
2253+}
2254+
2255+//! @brief データの解放
2256+void ObjectManager::Cleanup()
2257+{
2258+ //ポイントデータ解放
2259+ CleanupPointDataToObject();
2260+}
\ No newline at end of file
--- tags/v1.010-20150220/d3dgraphics.cpp (nonexistent)
+++ tags/v1.010-20150220/d3dgraphics.cpp (revision 45)
@@ -0,0 +1,1508 @@
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+//! @brief コンストラクタ
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+}
59+
60+//! @brief ディストラクタ
61+D3DGraphics::~D3DGraphics()
62+{
63+ //リソース解放
64+ CleanupD3Dresource();
65+
66+ if( pd3dDevice != NULL ) pd3dDevice->Release();
67+ if( pD3D != NULL ) pD3D->Release();
68+}
69+
70+//! @brief 初期化@n
71+//! (DirectX 9)
72+//! @param hWnd ウィンドウハンドル
73+//! @param TextureFontFilename 使用するテクスチャフォントのファイル名
74+//! @param fullscreen false:ウィンドウ表示 true:フルスクリーン用表示
75+//! @return 成功:0 失敗:1
76+int D3DGraphics::InitD3D(HWND hWnd, char *TextureFontFilename, bool fullscreen)
77+{
78+ D3DPRESENT_PARAMETERS d3dpp;
79+ RECT rec;
80+
81+ GetClientRect( hWnd, &rec);
82+
83+ fullscreenflag = fullscreen;
84+
85+ //D3D9の作成
86+ pD3D = Direct3DCreate9(D3D_SDK_VERSION);
87+ if( pD3D == NULL ){
88+ return 1;
89+ }
90+
91+ //D3Dデバイスの作成
92+ ZeroMemory(&d3dpp, sizeof(d3dpp));
93+ if( fullscreenflag == false ){
94+ d3dpp.Windowed = TRUE;
95+ d3dpp.BackBufferWidth = rec.right;
96+ d3dpp.BackBufferHeight = rec.bottom;
97+ d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
98+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
99+ d3dpp.EnableAutoDepthStencil = TRUE;
100+ d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
101+ d3dpp.FullScreen_RefreshRateInHz = 0;
102+ }
103+ else{
104+ D3DDISPLAYMODE dispmode;
105+ pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispmode);
106+
107+ d3dpp.Windowed = FALSE;
108+ d3dpp.BackBufferWidth = rec.right;
109+ d3dpp.BackBufferHeight = rec.bottom;
110+ d3dpp.BackBufferFormat = dispmode.Format;
111+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
112+ d3dpp.EnableAutoDepthStencil = TRUE;
113+ d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
114+ d3dpp.FullScreen_RefreshRateInHz = dispmode.RefreshRate;
115+ }
116+
117+ if( FAILED( pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice) ) ){
118+ if( FAILED( pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pd3dDevice) ) ){
119+ return 1;
120+ }
121+ }
122+
123+ //テクスチャフォント用画像のファイル名を設定
124+ strcpy(TextureFontFname, TextureFontFilename);
125+
126+ //描画関係の詳細な設定
127+ if( InitSubset() != 0){
128+ return 1;
129+ }
130+
131+
132+ //アスペクト比を設定
133+ aspect = (float)rec.right / (float)rec.bottom;
134+
135+ //マウスカーソルを消す
136+ //ShowCursor(FALSE);
137+
138+
139+ float aspecth, prx, pry, r;
140+ aspecth = (float)SCREEN_WIDTH/SCREEN_HEIGHT;
141+
142+ //HUD_myweapon [奥行き, 縦, 横]
143+
144+ //HUD_A 現在持っている武器を表示する座標
145+ prx = (float)M_PI/180*-39 * aspecth /2;
146+ pry = (float)M_PI/180*-55 /2;
147+ r = 7.5f;
148+ HUD_myweapon_x[0] = cos(pry)*r;
149+ HUD_myweapon_y[0] = sin(pry)*r;
150+ HUD_myweapon_z[0] = sin(prx)*r;
151+
152+ //HUD_A 予備の武器を表示する座標
153+ prx = (float)M_PI/180*-52 * aspecth /2;
154+ pry = (float)M_PI/180*-60 /2;
155+ r = 16.0f;
156+ HUD_myweapon_x[1] = cos(pry)*r;
157+ HUD_myweapon_y[1] = sin(pry)*r;
158+ HUD_myweapon_z[1] = sin(prx)*r;
159+
160+ return 0;
161+}
162+
163+//! @brief リセット@n
164+//! (ウィンドウ最小化からの復帰 など)
165+//! @param hWnd ウィンドウハンドル
166+//! @return 成功:0 待ち:1 失敗:2
167+int D3DGraphics::ResetD3D(HWND hWnd)
168+{
169+ //フォーカスを失っているなら待たせる
170+ if( pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICELOST ){
171+ return 1;
172+ }
173+
174+ //リソース解放
175+ CleanupD3Dresource();
176+
177+ D3DPRESENT_PARAMETERS d3dpp;
178+ RECT rec;
179+
180+ GetClientRect( hWnd, &rec);
181+
182+ //D3Dデバイスの作成
183+ ZeroMemory(&d3dpp, sizeof(d3dpp));
184+ if( fullscreenflag == false ){
185+ d3dpp.Windowed = TRUE;
186+ d3dpp.BackBufferWidth = rec.right;
187+ d3dpp.BackBufferHeight = rec.bottom;
188+ d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
189+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
190+ d3dpp.EnableAutoDepthStencil = TRUE;
191+ d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
192+ d3dpp.FullScreen_RefreshRateInHz = 0;
193+ }
194+ else{
195+ D3DDISPLAYMODE dispmode;
196+ pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &dispmode);
197+
198+ d3dpp.Windowed = FALSE;
199+ d3dpp.BackBufferWidth = rec.right;
200+ d3dpp.BackBufferHeight = rec.bottom;
201+ d3dpp.BackBufferFormat = dispmode.Format;
202+ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
203+ d3dpp.EnableAutoDepthStencil = TRUE;
204+ d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
205+ d3dpp.FullScreen_RefreshRateInHz = dispmode.RefreshRate;
206+ }
207+
208+ if( FAILED( pd3dDevice->Reset(&d3dpp) ) ){
209+ return 2;
210+ }
211+
212+ //描画関係の詳細な設定
213+ if( InitSubset() != 0){
214+ return 2;
215+ }
216+
217+ return 0;
218+}
219+
220+//! @brief 描画関係の細部設定
221+//! @attention 初期化時に1度だけ実行してください。
222+int D3DGraphics::InitSubset()
223+{
224+ //ライト
225+ //pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0,255,255,255) );
226+ pd3dDevice->LightEnable(0, FALSE);
227+ pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
228+
229+ //フォグ
230+ float fog_st = 100;
231+ float fog_end = 800;
232+ pd3dDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
233+ pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, D3DCOLOR_RGBA(0, 0, 0, 0));
234+ pd3dDevice->SetRenderState(D3DRS_FOGTABLEMODE, D3DFOG_LINEAR);
235+ pd3dDevice->SetRenderState(D3DRS_FOGVERTEXMODE, D3DFOG_NONE);
236+ pd3dDevice->SetRenderState(D3DRS_FOGSTART,*(DWORD*)(&fog_st));
237+ pd3dDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&fog_end));
238+
239+ // テクスチャフィルタを使う
240+ pd3dDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
241+ pd3dDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
242+ pd3dDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
243+
244+ //ミップマップの詳細レベル (LOD) バイアスを指定する。
245+ float LODBias = -0.2f;
246+ pd3dDevice->SetSamplerState(0, D3DSAMP_MIPMAPLODBIAS, *((LPDWORD)(&LODBias)) );
247+
248+ //アルファ・ブレンディングを行う
249+ pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
250+
251+ //透過処理を行う
252+ pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
253+ pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
254+
255+ //アルファテストに対応しているかチェック
256+ D3DCAPS9 Caps;
257+ pd3dDevice->GetDeviceCaps(&Caps);
258+ if( Caps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL ){
259+ //アルファテスト設定
260+ // 完全に透明なピクセルは描画しない
261+ pd3dDevice->SetRenderState(D3DRS_ALPHAREF, (DWORD)0x00000001);
262+ pd3dDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
263+ pd3dDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
264+ }
265+
266+ //深度バッファ比較関数
267+ pd3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
268+ pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
269+
270+ //ポリゴンの裏・表
271+ pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
272+
273+
274+ //テキストスプライト初期化
275+ if( FAILED( D3DXCreateSprite( pd3dDevice, &ptextsprite ) ) ){
276+ return 1;
277+ }
278+ //フォント名:MS ゴシック サイズ:18
279+ HRESULT hr = D3DXCreateFont( pd3dDevice, -18, 0, FW_NORMAL, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
280+ DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "MS ゴシック", &pxmsfont);
281+ if( FAILED(hr) ) return 1;
282+
283+ //テクスチャフォント用画像を取得
284+ TextureFont = LoadTexture(TextureFontFname, true, false);
285+ return 0;
286+}
287+
288+//! @brief デバイスのリソースを解放
289+void D3DGraphics::CleanupD3Dresource()
290+{
291+ if( TextureFont != -1 ){ CleanupTexture(TextureFont); }
292+ if( pxmsfont != NULL ){
293+ pxmsfont->Release();
294+ pxmsfont = NULL;
295+ }
296+ if( ptextsprite != NULL ){ ptextsprite->Release(); }
297+
298+ CleanupMapdata();
299+
300+ for(int i=0; i<MAX_MODEL; i++){
301+ CleanupModel(i);
302+ }
303+ for(int i=0; i<MAX_TEXTURE; i++){
304+ CleanupTexture(i);
305+ }
306+}
307+
308+//! @brief モデルファイルを読み込む(.x)
309+//! @param filename ファイル名
310+//! @return 成功:モデル認識番号(0以上) 失敗:-1
311+int D3DGraphics::LoadModel(char* filename)
312+{
313+ int id = -1;
314+
315+ //空いている要素を探す
316+ for(int i=0; i<MAX_MODEL; i++){
317+ if( pmesh[i] == NULL ){
318+ id = i;
319+ break;
320+ }
321+ }
322+ if( id == -1 ){ return -1; }
323+
324+ LPD3DXBUFFER pD3DXMtrlBuffer;
325+
326+ //.xファイルをバッファーに読み込む
327+ if( FAILED( D3DXLoadMeshFromX( filename, D3DXMESH_SYSTEMMEM, pd3dDevice, NULL,
328+ &pD3DXMtrlBuffer, NULL, &nummaterials[id], &pmesh[id] ) ) ) {
329+ return -1;
330+ }
331+
332+ //マテリアル情報を取得
333+ D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
334+ int num = nummaterials[id];
335+ pmaterials[id] = new D3DMATERIAL9[num];
336+ if( pmaterials[id] == NULL ) return -3;
337+
338+ //構造体に代入
339+ for( int i=0; i<num; i=i+1 ){
340+ pmaterials[id][i] = d3dxMaterials[i].MatD3D;
341+ pmaterials[id][i].Ambient = pmaterials[id][i].Diffuse;
342+ }
343+
344+ //バッファを開放
345+ pD3DXMtrlBuffer->Release();
346+
347+ return id;
348+}
349+
350+//! @brief モデルファイルの中間データを作成(モーフィング)
351+//! @param idA モデルAの認識番号
352+//! @param idB モデルBの認識番号
353+//! @return 成功:新しいモデル認識番号(0以上) 失敗:-1
354+//! @attention モデルAとモデルBは、頂点数・ポリゴン数・インデックスが同じである必要があります。
355+//! @attention それぞれのモデルデータが正しくないか 頂点数が異なる場合、実行に失敗します。
356+int D3DGraphics::MorphingModel(int idA, int idB)
357+{
358+ //データが正しいか調べる
359+ if( (idA < 0)||((MAX_MODEL -1) < idA) ){ return -1; }
360+ if( pmesh[idA] == NULL ){ return -1; }
361+ if( (idB < 0)||((MAX_MODEL -1) < idB) ){ return -1; }
362+ if( pmesh[idB] == NULL ){ return -1; }
363+
364+ int idN = -1;
365+ int numvA, numvB;
366+ LPDIRECT3DVERTEXBUFFER9 pvbA, pvbB, pvbN;
367+ D3DXVECTOR3 *pVerticesA, *pVerticesB, *pVerticesN;
368+ int FVFsize;
369+
370+ //空いている要素を探す
371+ for(int i=0; i<MAX_MODEL; i++){
372+ if( pmesh[i] == NULL ){
373+ idN = i;
374+ break;
375+ }
376+ }
377+ if( idN == -1 ){ return -1; }
378+
379+ //頂点数を取得
380+ numvA = pmesh[idA]->GetNumVertices();
381+ numvB = pmesh[idB]->GetNumVertices();
382+
383+ //頂点数が同じかどうか調べる
384+ if( numvA != numvB ){ return -1; }
385+
386+ //頂点データをコピー(実質的に領域確保用のダミー)
387+ if( pmesh[idA]->CloneMeshFVF(pmesh[idA]->GetOptions(), pmesh[idA]->GetFVF(), pd3dDevice, &pmesh[idN]) != D3D_OK ){
388+ return -1;
389+ }
390+
391+ //マテリアル情報をコピー
392+ int num = nummaterials[idA];
393+ nummaterials[idN] = nummaterials[idA];
394+ pmaterials[idN] = new D3DMATERIAL9[num];
395+ if( pmaterials[idN] == NULL ) return -1;
396+ for( int i=0; i<num; i=i+1 ){
397+ pmaterials[idN][i] = pmaterials[idA][i];
398+ }
399+
400+ //バッファーを取得
401+ pmesh[idA]->GetVertexBuffer(&pvbA);
402+ pmesh[idB]->GetVertexBuffer(&pvbB);
403+ pmesh[idN]->GetVertexBuffer(&pvbN);
404+
405+ //1頂点当たりのバイト数取得
406+ FVFsize = D3DXGetFVFVertexSize(pmesh[idN]->GetFVF());
407+
408+ //各頂点を読み出し計算
409+ for(int i=0; i<numvA; i++){
410+ pvbA->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesA, D3DLOCK_READONLY);
411+ pvbB->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesB, D3DLOCK_READONLY);
412+ pvbN->Lock(i*FVFsize, sizeof(D3DXVECTOR3), (void**)&pVerticesN, 0);
413+
414+ //平均化
415+ pVerticesN->x = (pVerticesA->x + pVerticesB->x)/2;
416+ pVerticesN->y = (pVerticesA->y + pVerticesB->y)/2;
417+ pVerticesN->z = (pVerticesA->z + pVerticesB->z)/2;
418+
419+ pvbA->Unlock();
420+ pvbB->Unlock();
421+ pvbN->Unlock();
422+ }
423+
424+ return idN;
425+}
426+
427+//! @brief モデルファイルを解放
428+//! @param id モデル認識番号
429+void D3DGraphics::CleanupModel(int id)
430+{
431+ if( (id < 0)||((MAX_MODEL -1) < id) ){ return; }
432+ if( pmesh[id] != NULL ){
433+ delete [] pmaterials[id];
434+
435+ pmesh[id]->Release();
436+ pmesh[id] = NULL;
437+ }
438+}
439+
440+//! @brief テクスチャを読み込む
441+//! @param filename ファイル名
442+//! @param texturefont テクスチャフォントフラグ
443+//! @param BlackTransparent 黒を透過する
444+//! @return 成功:テクスチャ認識番号(0以上) 失敗:-1
445+int D3DGraphics::LoadTexture(char* filename, bool texturefont, bool BlackTransparent)
446+{
447+ int id = -1;
448+ int MipLevels;
449+
450+ //空いている認識番号を探す
451+ for(int i=0; i<MAX_TEXTURE; i++){
452+ if( ptextures[i] == NULL ){
453+ id = i;
454+ break;
455+ }
456+ }
457+ if( id == -1 ){ return -1; }
458+
459+ //ミップマップレベルを設定
460+ if( texturefont == true ){
461+ MipLevels = 1;
462+ }
463+ else{
464+ MipLevels = 4;//D3DX_DEFAULT;
465+ }
466+
467+ //テクスチャを読み込む
468+ if( BlackTransparent == false ){
469+ if( FAILED( D3DXCreateTextureFromFileEx(pd3dDevice, filename, D3DX_DEFAULT, D3DX_DEFAULT, MipLevels, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, 0x00000000, NULL, NULL, &ptextures[id]) ) ) {
470+ return -1;
471+ }
472+ }
473+ else{
474+ 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]) ) ) {
475+ return -1;
476+ }
477+ }
478+ return id;
479+}
480+
481+//! @brief テクスチャのサイズを取得
482+//! @param id テクスチャ認識番号
483+//! @param width 幅を受け取るポインタ
484+//! @param height 高さを受け取るポインタ
485+//! @return 成功:0 失敗:1
486+//! @attention サーフェイスのサイズを取得します。GPUにロードされたサイズであり、テクスチャ(現物)と異なる場合があります。
487+int D3DGraphics::GetTextureSize(int id, int *width, int *height)
488+{
489+ //無効な認識番号が指定されていたら、処理せず返す。
490+ if( id == -1 ){ return 1; }
491+ if( ptextures[id] == NULL ){ return 1; }
492+
493+ IDirect3DSurface9 *surface;
494+ D3DSURFACE_DESC desc;
495+
496+ //サーフェイスを取得
497+ ptextures[id]->GetSurfaceLevel(0, &surface);
498+
499+ //幅と高さを取得
500+ surface->GetDesc(&desc);
501+ *width = desc.Width;
502+ *height = desc.Height;
503+
504+ //サーフェイスを開放
505+ surface->Release();
506+
507+ return 0;
508+}
509+
510+//! @brief テクスチャを解放
511+//! @param id テクスチャ認識番号
512+void D3DGraphics::CleanupTexture(int id)
513+{
514+ if( (id < 0)||((MAX_TEXTURE -1) < id) ){ return; }
515+ if( ptextures[id] != NULL ){
516+ ptextures[id]->Release();
517+ ptextures[id] = NULL;
518+ }
519+}
520+
521+//! @brief 全ての描画処理を開始
522+//! @return 成功:0 失敗:1
523+//! @attention 描画処理の最初に呼び出す必要があります。
524+int D3DGraphics::StartRender()
525+{
526+ if( StartRenderFlag == true ){ return 1; }
527+
528+ //領域を初期化
529+ pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
530+
531+ if( SUCCEEDED( pd3dDevice->BeginScene() ) ){
532+ //Zバッファ初期化
533+ pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
534+
535+ //座標ゼロ地点にワールド変換行列
536+ ResetWorldTransform();
537+
538+ //描画中のフラグを立てる
539+ StartRenderFlag = true;
540+ return 0;
541+ }
542+
543+ return 1;
544+}
545+
546+//! @brief 全ての描画処理を終了
547+//! @return 成功:false 失敗:true
548+//! @attention 描画処理の最後に呼び出す必要があります。
549+bool D3DGraphics::EndRender()
550+{
551+ //描画中なら終了
552+ if( StartRenderFlag == true ){
553+ pd3dDevice->EndScene();
554+ }
555+
556+ HRESULT hr = pd3dDevice->Present(NULL, NULL, NULL, NULL);
557+
558+ //フラグを false に
559+ StartRenderFlag = false;
560+
561+ if( hr == D3DERR_DEVICELOST ){
562+ return true;
563+ }
564+ return false;
565+}
566+
567+//! @brief Zバッファをリセット
568+void D3DGraphics::ResetZbuffer()
569+{
570+ //Zバッファを一度無効にし、初期化後、再度有効に
571+ pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
572+ pd3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
573+ pd3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
574+}
575+
576+//! @brief ワールド空間を原点(0,0,0)に戻す など
577+void D3DGraphics::ResetWorldTransform()
578+{
579+ D3DXMATRIX matWorld;
580+ D3DXMatrixIdentity(&matWorld);
581+ pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
582+}
583+
584+//! @brief ワールド空間の座標・角度・拡大率を設定
585+//! @param x X座標
586+//! @param y Y座標
587+//! @param z Z座標
588+//! @param rx 横軸角度
589+//! @param ry 縦軸角度
590+//! @param size 拡大率
591+void D3DGraphics::SetWorldTransform(float x, float y, float z, float rx, float ry, float size)
592+{
593+ SetWorldTransform(x, y, z, rx, ry, 0.0f, size);
594+}
595+
596+//! @brief ワールド空間の座標・角度・拡大率を設定
597+//! @param x X座標
598+//! @param y Y座標
599+//! @param z Z座標
600+//! @param rx 横軸角度
601+//! @param ry1 縦軸角度
602+//! @param ry2 縦軸角度
603+//! @param size 拡大率
604+void D3DGraphics::SetWorldTransform(float x, float y, float z, float rx, float ry1, float ry2, float size)
605+{
606+ D3DXMATRIX matWorld;
607+ D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5;
608+
609+ //行列を作成
610+ D3DXMatrixTranslation(&matWorld1, x, y, z);
611+ D3DXMatrixRotationY(&matWorld2, rx);
612+ D3DXMatrixRotationX(&matWorld3, ry1);
613+ D3DXMatrixRotationZ(&matWorld4, ry2);
614+ D3DXMatrixScaling(&matWorld5, size, size, size);
615+
616+ //計算
617+ matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1;
618+
619+ //適用
620+ pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
621+}
622+
623+//! @brief ワールド空間の座標・角度・拡大率を設定(エフェクト用)
624+//! @param x X座標
625+//! @param y Y座標
626+//! @param z Z座標
627+//! @param rx 横軸角度
628+//! @param ry 縦軸角度
629+//! @param rt 回転角度
630+//! @param size 拡大率
631+void D3DGraphics::SetWorldTransformEffect(float x, float y, float z, float rx, float ry, float rt, float size)
632+{
633+ D3DXMATRIX matWorld;
634+ D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5;
635+
636+ //行列を作成
637+ D3DXMatrixTranslation(&matWorld1, x, y, z);
638+ D3DXMatrixRotationY(&matWorld2, rx);
639+ D3DXMatrixRotationZ(&matWorld3, ry);
640+ D3DXMatrixRotationX(&matWorld4, rt);
641+ D3DXMatrixScaling(&matWorld5, size, size, size);
642+
643+ //計算
644+ matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1;
645+
646+ //適用
647+ pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
648+}
649+
650+//! @brief ワールド空間を人が武器を持つ場所に設定
651+//! @param x X座標
652+//! @param y Y座標
653+//! @param z Z座標
654+//! @param mx 手元を原点にした モデルのX座標
655+//! @param my 手元を原点にした モデルのY座標
656+//! @param mz 手元を原点にした モデルのZ座標
657+//! @param rx 横軸角度
658+//! @param ry 縦軸角度
659+//! @param size 拡大率
660+void D3DGraphics::SetWorldTransformHumanWeapon(float x, float y, float z, float mx, float my, float mz, float rx, float ry, float size)
661+{
662+ D3DXMATRIX matWorld;
663+ D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5;
664+
665+ //行列を作成
666+ D3DXMatrixTranslation(&matWorld1, x, y, z);
667+ D3DXMatrixRotationY(&matWorld2, rx);
668+ D3DXMatrixRotationX(&matWorld3, ry);
669+ D3DXMatrixTranslation(&matWorld4, mx, my, mz);
670+ D3DXMatrixScaling(&matWorld5, size, size, size);
671+
672+ //計算
673+ matWorld = matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1;
674+
675+ //適用
676+ pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
677+}
678+
679+//! @brief ワールド空間を所持している武器を表示する場所に設定
680+//! @param rotation 武器を回転させる
681+//! @param camera_x カメラのX座標
682+//! @param camera_y カメラのY座標
683+//! @param camera_z カメラのZ座標
684+//! @param camera_rx カメラの横軸角度
685+//! @param camera_ry カメラの縦軸角度
686+//! @param rx 武器のの縦軸角度
687+//! @param size 表示サイズ
688+//! @note rotation・・ true:現在持っている武器です。 false:予備の武器です。(rx は無視されます)
689+//! @todo 位置やサイズの微調整
690+void D3DGraphics::SetWorldTransformPlayerWeapon(bool rotation, float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float rx, float size)
691+{
692+ D3DXMATRIX matWorld;
693+ D3DXMATRIX matWorld1, matWorld2, matWorld3, matWorld4, matWorld5, matWorld6;
694+
695+ size = size * 0.3f;
696+
697+ //行列を作成
698+ D3DXMatrixTranslation(&matWorld1, camera_x, camera_y, camera_z);
699+ D3DXMatrixRotationY(&matWorld2, camera_rx *-1);
700+ D3DXMatrixRotationZ(&matWorld3, camera_ry);
701+ // matWorld4 = [奥行き, 縦, 横]
702+ if( rotation == true ){
703+ D3DXMatrixTranslation(&matWorld4, HUD_myweapon_x[0], HUD_myweapon_y[0], HUD_myweapon_z[0]);
704+ D3DXMatrixRotationY(&matWorld5, rx);
705+ }
706+ else{
707+ D3DXMatrixTranslation(&matWorld4, HUD_myweapon_x[1], HUD_myweapon_y[1], HUD_myweapon_z[1]);
708+ D3DXMatrixRotationY(&matWorld5, D3DX_PI);
709+ }
710+ D3DXMatrixScaling(&matWorld6, size, size, size);
711+
712+ //計算
713+ matWorld = matWorld6 * matWorld5 * matWorld4 * matWorld3 * matWorld2 * matWorld1;
714+
715+ //適用
716+ pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
717+}
718+
719+//! @brief ワールド空間の座標を取得
720+//! @param *x x軸を受け取るポインタ
721+//! @param *y y軸を受け取るポインタ
722+//! @param *z z軸を受け取るポインタ
723+void D3DGraphics::GetWorldTransformPos(float *x, float *y, float *z)
724+{
725+ D3DXMATRIX matWorld;
726+ pd3dDevice->GetTransform( D3DTS_WORLD, &matWorld );
727+ *x = matWorld._41;
728+ *y = matWorld._42;
729+ *z = matWorld._43;
730+}
731+
732+//! @brief フォグを設定
733+//! @param skynumber 空の番号
734+void D3DGraphics::SetFog(int skynumber)
735+{
736+ D3DCOLOR skycolor;
737+
738+ //空の番号により色を決定
739+ switch(skynumber){
740+ case 1: skycolor = D3DCOLOR_RGBA(64, 64+16, 64, 0); break;
741+ case 2: skycolor = D3DCOLOR_RGBA(16, 16, 16, 0); break;
742+ case 3: skycolor = D3DCOLOR_RGBA(0, 16, 32, 0); break;
743+ case 4: skycolor = D3DCOLOR_RGBA(32, 16, 16, 0); break;
744+ case 5: skycolor = D3DCOLOR_RGBA(64, 32, 32, 0); break;
745+ default: skycolor = D3DCOLOR_RGBA(0, 0, 0, 0); break;
746+ }
747+
748+ //フォグを設定
749+ pd3dDevice->SetRenderState(D3DRS_FOGCOLOR, skycolor);
750+}
751+
752+//! @brief カメラ(視点)を設定
753+//! @param camera_x カメラのX座標
754+//! @param camera_y カメラのY座標
755+//! @param camera_z カメラのZ座標
756+//! @param camera_rx カメラの横軸角度
757+//! @param camera_ry カメラの縦軸角度
758+//! @param viewangle 視野角
759+void D3DGraphics::SetCamera(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float viewangle)
760+{
761+ float vUpVecF;
762+ D3DXMATRIX matWorld;
763+ D3DXMATRIXA16 matView;
764+
765+ //camera_ryを -PI〜PI の間に正規化
766+ for(; camera_ry>D3DX_PI; camera_ry -= D3DX_PI*2){}
767+ for(; camera_ry<D3DX_PI*-1; camera_ry += D3DX_PI*2){}
768+
769+ //カメラの向きを決定
770+ if( abs(camera_ry) < D3DX_PI/2 ){
771+ vUpVecF = 1.0f;
772+ }
773+ else{
774+ vUpVecF = -1.0f;
775+ }
776+
777+ D3DXMatrixIdentity(&matWorld);
778+ pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
779+
780+ //カメラ座標
781+ D3DXVECTOR3 vEyePt( camera_x, camera_y, camera_z );
782+ D3DXVECTOR3 vLookatPt( cos(camera_rx)*cos(camera_ry) + camera_x, sin(camera_ry) + camera_y, sin(camera_rx)*cos(camera_ry) + camera_z );
783+ D3DXVECTOR3 vUpVec( 0.0f, vUpVecF, 0.0f );
784+ D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
785+ pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
786+
787+ //カメラ設定(射影変換行列)viewangle
788+ D3DXMATRIXA16 matProj;
789+ D3DXMatrixPerspectiveFovLH( &matProj, viewangle, aspect, CLIPPINGPLANE_NEAR, CLIPPINGPLANE_FAR);
790+ pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
791+}
792+
793+//! @brief マップデータを取り込む
794+//! @param in_blockdata ブロックデータ
795+//! @param directory ブロックデータが存在するディレクトリ
796+void D3DGraphics::LoadMapdata(BlockDataInterface* in_blockdata, char *directory)
797+{
798+ //ブロックデータが指定されていなければ、処理しない。
799+ if( in_blockdata == NULL ){ return; }
800+
801+ char fname[MAX_PATH];
802+ char fnamefull[MAX_PATH];
803+ //int bs;
804+ struct blockdata data;
805+ int vID[4];
806+ int uvID[4];
807+
808+ //クラスを設定
809+ blockdata = in_blockdata;
810+
811+ //テクスチャ読み込み
812+ for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){
813+ //テクスチャ名を取得
814+ blockdata->GetTexture(fname, i);
815+
816+ if( strcmp(fname, "") == 0 ){ //指定されていなければ、処理しない
817+ mapTextureID[i] = -1;
818+ }
819+ else{
820+ //「ディレクトリ+ファイル名」を生成し、読み込む
821+ strcpy(fnamefull, directory);
822+ strcat(fnamefull, fname);
823+ mapTextureID[i] = LoadTexture(fnamefull, false, false);
824+ }
825+ }
826+
827+#ifdef BLOCKDATA_GPUMEMORY
828+ VERTEXTXTA* pVertices;
829+
830+ //ブロック数を取得
831+ bs = blockdata->GetTotaldatas();
832+
833+ //ブロック数分のバッファーを作成
834+ pd3dDevice->CreateVertexBuffer(bs*6*4*sizeof(VERTEXTXTA),0,D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1,D3DPOOL_DEFAULT,&g_pVB,NULL);
835+
836+ for(int i=0; i<bs; i++){
837+ //データを取得
838+ blockdata->Getdata(&data, i);
839+
840+ for(int j=0; j<6; j++){
841+ //面の頂点データの関連付けを取得
842+ blockdataface(j, &vID[0], &uvID[0]);
843+
844+ //GPUをロック(1面分)
845+ g_pVB->Lock((i*6+j)*4*sizeof(VERTEXTXTA), 4*sizeof(VERTEXTXTA), (void**)&pVertices, 0);
846+
847+ //頂点座標・UV座標・色を設定
848+ pVertices[0].position = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] );
849+ pVertices[0].tu = data.material[j].u[ uvID[1] ];
850+ pVertices[0].tv = data.material[j].v[ uvID[1] ];
851+ pVertices[1].position = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] );
852+ pVertices[1].tu = data.material[j].u[ uvID[2] ];
853+ pVertices[1].tv = data.material[j].v[ uvID[2] ];
854+ pVertices[2].position = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] );
855+ pVertices[2].tu = data.material[j].u[ uvID[0] ];
856+ pVertices[2].tv = data.material[j].v[ uvID[0] ];
857+ pVertices[3].position = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] );
858+ pVertices[3].tu = data.material[j].u[ uvID[3] ];
859+ pVertices[3].tv = data.material[j].v[ uvID[3] ];
860+ for(int k=0; k<4; k++){
861+ pVertices[k].color = D3DCOLOR_COLORVALUE(data.material[j].shadow, data.material[j].shadow, data.material[j].shadow, 1.0f);
862+ }
863+
864+ //GPUのロックを解除
865+ g_pVB->Unlock();
866+ }
867+ }
868+#else
869+ //ブロック数を取得
870+ bs = blockdata->GetTotaldatas();
871+
872+ for(int i=0; i<bs; i++){
873+ //データを取得
874+ blockdata->Getdata(&data, i);
875+
876+ for(int j=0; j<6; j++){
877+ //面の頂点データの関連付けを取得
878+ blockdataface(j, vID, uvID);
879+
880+ //頂点座標・UV座標・色を設定
881+ g_pVertices[i][j][0].position = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] );
882+ g_pVertices[i][j][0].tu = data.material[j].u[ uvID[1] ];
883+ g_pVertices[i][j][0].tv = data.material[j].v[ uvID[1] ];
884+ g_pVertices[i][j][1].position = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] );
885+ g_pVertices[i][j][1].tu = data.material[j].u[ uvID[2] ];
886+ g_pVertices[i][j][1].tv = data.material[j].v[ uvID[2] ];
887+ g_pVertices[i][j][2].position = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] );
888+ g_pVertices[i][j][2].tu = data.material[j].u[ uvID[0] ];
889+ g_pVertices[i][j][2].tv = data.material[j].v[ uvID[0] ];
890+ g_pVertices[i][j][3].position = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] );
891+ g_pVertices[i][j][3].tu = data.material[j].u[ uvID[3] ];
892+ g_pVertices[i][j][3].tv = data.material[j].v[ uvID[3] ];
893+ for(int k=0; k<4; k++){
894+ g_pVertices[i][j][k].color = D3DCOLOR_COLORVALUE(data.material[j].shadow, data.material[j].shadow, data.material[j].shadow, 1.0f);
895+ }
896+ }
897+ }
898+#endif
899+}
900+
901+//! @brief マップデータを描画
902+//! @param wireframe ワイヤーフレーム表示
903+void D3DGraphics::DrawMapdata(bool wireframe)
904+{
905+ //ブロックデータが読み込まれていなければ、処理しない。
906+ if( blockdata == NULL ){ return; }
907+
908+ struct blockdata data;
909+ int textureID;
910+
911+ if( wireframe == true ){
912+ //ワイヤーフレーム表示
913+ for(int i=0; i<bs; i++){
914+ blockdata->Getdata(&data, i);
915+ Drawline(data.x[0], data.y[0], data.z[0], data.x[1], data.y[1], data.z[1]);
916+ Drawline(data.x[1], data.y[1], data.z[1], data.x[2], data.y[2], data.z[2]);
917+ Drawline(data.x[2], data.y[2], data.z[2], data.x[3], data.y[3], data.z[3]);
918+ Drawline(data.x[3], data.y[3], data.z[3], data.x[0], data.y[0], data.z[0]);
919+ Drawline(data.x[4], data.y[4], data.z[4], data.x[5], data.y[5], data.z[5]);
920+ Drawline(data.x[5], data.y[5], data.z[5], data.x[6], data.y[6], data.z[6]);
921+ Drawline(data.x[6], data.y[6], data.z[6], data.x[7], data.y[7], data.z[7]);
922+ Drawline(data.x[7], data.y[7], data.z[7], data.x[4], data.y[4], data.z[4]);
923+ Drawline(data.x[0], data.y[0], data.z[0], data.x[4], data.y[4], data.z[4]);
924+ Drawline(data.x[1], data.y[1], data.z[1], data.x[5], data.y[5], data.z[5]);
925+ Drawline(data.x[2], data.y[2], data.z[2], data.x[6], data.y[6], data.z[6]);
926+ Drawline(data.x[3], data.y[3], data.z[3], data.x[7], data.y[7], data.z[7]);
927+ }
928+ return;
929+ }
930+
931+ //深度バッファ比較関数を設定
932+ //pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
933+
934+
935+#ifdef BLOCKDATA_GPUMEMORY
936+ //データ設定
937+ pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(VERTEXTXTA));
938+
939+ for(textureID=0; textureID<TOTAL_BLOCKTEXTURE; textureID++){
940+ //テクスチャが正常に読み込めていなければ設定
941+ if( mapTextureID[textureID] == -1 ){
942+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
943+ pd3dDevice->SetTexture(0, NULL);
944+ }
945+ else{
946+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
947+ pd3dDevice->SetTexture(0, ptextures[mapTextureID[textureID]] );
948+ }
949+
950+ for(int i=0; i<bs; i++){
951+ //データ取得
952+ blockdata->Getdata(&data, i);
953+
954+ for(int j=0; j<6; j++){
955+ //テクスチャ認識番号を取得
956+ int ID = data.material[j].textureID;
957+
958+ if( textureID == ID ){
959+ //面を描画
960+ pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, (i*6+j)*4, 2);
961+ }
962+ }
963+ }
964+ }
965+#else
966+ //データを設定
967+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
968+
969+ for(textureID=0; textureID<TOTAL_BLOCKTEXTURE; textureID++){
970+ //テクスチャが正常に読み込めていなければ設定
971+ if( mapTextureID[textureID] == -1 ){
972+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE);
973+ pd3dDevice->SetTexture(0, NULL);
974+ }
975+ else{
976+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
977+ pd3dDevice->SetTexture(0, ptextures[mapTextureID[textureID]] );
978+ }
979+
980+ for(int i=0; i<bs; i++){
981+ //データ取得
982+ blockdata->Getdata(&data, i);
983+
984+ for(int j=0; j<6; j++){
985+ //テクスチャ認識番号を取得
986+ int ID = data.material[j].textureID;
987+
988+ if( textureID == ID ){
989+ //面を描画
990+ pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, g_pVertices[i][j], sizeof(VERTEXTXTA));
991+ }
992+ }
993+ }
994+ }
995+#endif
996+
997+ //深度バッファ比較関数を元に戻す
998+ //pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
999+}
1000+
1001+//! @brief マップテクスチャを取得
1002+//! @param id テクスチャ番号
1003+//! @return テクスチャ認識番号(失敗:-1)
1004+int D3DGraphics::GetMapTextureID(int id)
1005+{
1006+ if( (id < 0)||((TOTAL_BLOCKTEXTURE -1) < id ) ){ return -1; }
1007+ return mapTextureID[id];
1008+}
1009+
1010+//! @brief マップデータを解放
1011+void D3DGraphics::CleanupMapdata()
1012+{
1013+ //テクスチャを開放
1014+ for(int i=0; i<TOTAL_BLOCKTEXTURE; i++){
1015+ CleanupTexture(mapTextureID[i]);
1016+ }
1017+
1018+#ifdef BLOCKDATA_GPUMEMORY
1019+ //頂点データ解放
1020+ if( g_pVB != NULL ){
1021+ g_pVB->Release();
1022+ g_pVB = NULL;
1023+ }
1024+#endif
1025+ bs = 0;
1026+
1027+ blockdata = NULL;
1028+}
1029+
1030+//! @brief モデルファイルを描画
1031+//! @param id_model モデル認識番号
1032+//! @param id_texture テクスチャ認識番号
1033+void D3DGraphics::RenderModel(int id_model, int id_texture)
1034+{
1035+ //無効な引数が設定されていれば失敗
1036+ if( id_model == -1 ){ return; }
1037+ if( id_texture == -1 ){ return; }
1038+
1039+ //指定したモデルが初期化されていなければ失敗
1040+ if( pmesh[id_model] == NULL) return;
1041+
1042+ //描画
1043+ for(int i=0; i<(signed)nummaterials[id_model]; i=i+1){
1044+ pd3dDevice->SetMaterial( &pmaterials[id_model][i] );
1045+ if( ptextures[id_texture] == NULL ){
1046+ pd3dDevice->SetTexture(0, NULL);
1047+ }
1048+ else{
1049+ pd3dDevice->SetTexture( 0, ptextures[id_texture] );
1050+ }
1051+ pmesh[id_model]->DrawSubset(i);
1052+ }
1053+}
1054+
1055+//! @brief 板を描画
1056+//! @param id_texture テクスチャ認識番号
1057+//! @param alpha 透明度 (0.0〜1.0 0.0:完全透明)
1058+void D3DGraphics::RenderBoard(int id_texture, float alpha)
1059+{
1060+ //テクスチャが設定されていなければ、処理しない。
1061+ if( id_texture == -1 ){ return; }
1062+
1063+ VERTEXTXTA BoardVertices[4];
1064+
1065+ //頂点座標・UV座標・色/透明度を設定
1066+ BoardVertices[0].position = D3DXVECTOR3(0.0f, 0.5f, -0.5f);
1067+ BoardVertices[0].tu = 1.0f;
1068+ BoardVertices[0].tv = 0.0f;
1069+ BoardVertices[1].position = D3DXVECTOR3(0.0f, -0.5f, -0.5f);
1070+ BoardVertices[1].tu = 1.0f;
1071+ BoardVertices[1].tv = 1.0f;
1072+ BoardVertices[2].position = D3DXVECTOR3(0.0f, 0.5f, 0.5f);
1073+ BoardVertices[2].tu = 0.0f;
1074+ BoardVertices[2].tv = 0.0f;
1075+ BoardVertices[3].position = D3DXVECTOR3(0.0f, -0.5f, 0.5f);
1076+ BoardVertices[3].tu = 0.0f;
1077+ BoardVertices[3].tv = 1.0f;
1078+ for(int i=0; i<4; i++){
1079+ BoardVertices[i].color = D3DCOLOR_COLORVALUE(1.0f, 1.0f, 1.0f, alpha);
1080+ }
1081+
1082+ //アルファブレンドを設定
1083+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
1084+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
1085+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
1086+
1087+ //テクスチャとデータ形式を設定し描画
1088+ pd3dDevice->SetTexture(0, ptextures[id_texture]);
1089+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
1090+ pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, BoardVertices, sizeof(VERTEXTXTA));
1091+
1092+ //アルファブレンドを元に戻す
1093+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
1094+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
1095+}
1096+
1097+//! @brief 画面の明るさを設定
1098+//! @param Width 幅
1099+//! @param Height 高さ
1100+//! @param Brightness 画面の明るさ (0 で不変、1 以上で明るさの度合い)
1101+void D3DGraphics::ScreenBrightness(int Width, int Height, int Brightness)
1102+{
1103+ //明るさ不変なら処理しない(軽量化)
1104+ if( Brightness == 0 ){ return; }
1105+
1106+ //透明度を設定し、描画
1107+ float alpha = 0.02f * Brightness;
1108+ Draw2DBox(0, 0, Width, Height, D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,alpha));
1109+}
1110+
1111+//! @brief 【デバック用】中心線描画
1112+void D3DGraphics::Centerline()
1113+{
1114+ ResetWorldTransform();
1115+ Drawline(100.0f, 0.0f, 0.0f, -100.0f, 0.0f, 0.0f);
1116+ Drawline(0.0f, 100.0f, 0.0f, 0.0f, -100.0f, 0.0f);
1117+ Drawline(0.0f, 0.0f, 100.0f, 0.0f, 0.0f, -100.0f);
1118+}
1119+
1120+//! @brief 【デバック用】緑線描画
1121+void D3DGraphics::Drawline(float x1, float y1, float z1, float x2, float y2, float z2)
1122+{
1123+ VERTEXTXTA mv[2];
1124+
1125+ mv[0].position = D3DXVECTOR3(x1, y1, z1);
1126+ mv[1].position = D3DXVECTOR3(x2, y2, z2);
1127+ for(int i=0; i<2; i++){
1128+ mv[i].color = 0xFF00FF00;
1129+ mv[i].tu = 0.0f;
1130+ mv[i].tv = 0.0f;
1131+ }
1132+
1133+ pd3dDevice->SetFVF(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1);
1134+ pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, mv, sizeof(VERTEXTXTA));
1135+}
1136+
1137+//! @brief 2D システムフォントによるテキスト描画を開始
1138+//! @attention DirectXの ID3DXSprite を初期化しています。
1139+void D3DGraphics::Start2DMSFontTextRender()
1140+{
1141+ ptextsprite->Begin(D3DXSPRITE_ALPHABLEND);
1142+}
1143+
1144+//! @brief 文字を描画(システムフォント使用)
1145+//! @param x x座標
1146+//! @param y y座標
1147+//! @param str 文字列 (改行コード:可)
1148+//! @param color 色
1149+//! @warning <b>描画は非常に低速です。</b>画面内で何度も呼び出すとパフォーマンスに影響します。
1150+//! @warning「改行コードを活用し一度に描画する」「日本語が必要ない文字はテクスチャフォントを活用する」などの対応を講じてください。
1151+//! @attention DirectXの ID3DXSprite を使用し、システムフォントで描画ています。
1152+//! @attention フォントの種類やサイズは固定です。 文字を二重に重ねて立体感を出さないと見にくくなります。
1153+void D3DGraphics::Draw2DMSFontText(int x, int y, char *str, int color)
1154+{
1155+ //if( ptextsprite == NULL ){ return; }
1156+
1157+ //テキストスプライト初期化
1158+ Start2DMSFontTextRender();
1159+
1160+ //基準座標を設定
1161+ D3DXMATRIX matWorld;
1162+ D3DXMatrixIdentity(&matWorld);
1163+ ptextsprite->SetTransform(&matWorld);
1164+
1165+ //文字をを描画
1166+ RECT rc = {x, y, 0, 0};
1167+ pxmsfont->DrawText(ptextsprite, str, -1, &rc, DT_NOCLIP, color);
1168+
1169+ //テキストスプライト解放
1170+ End2DMSFontTextRender();
1171+}
1172+
1173+//! @brief 文字を中央揃えで描画(システムフォント使用)
1174+//! @param x x座標
1175+//! @param y y座標
1176+//! @param w 横の大きさ
1177+//! @param h 縦の大きさ
1178+//! @param str 文字列 (改行コード:可)
1179+//! @param color 色
1180+//! @warning <b>描画は非常に低速です。</b>画面内で何度も呼び出すとパフォーマンスに影響します。
1181+//! @warning「改行コードを活用し一度に描画する」「日本語が必要ない文字はテクスチャフォントを活用する」などの対応を講じてください。
1182+//! @attention DirectXの ID3DXSprite を使用し、システムフォントで描画ています。
1183+//! @attention フォントの種類やサイズは固定です。 文字を二重に重ねて立体感を出さないと見にくくなります。
1184+void D3DGraphics::Draw2DMSFontTextCenter(int x, int y, int w, int h, char *str, int color)
1185+{
1186+ //if( ptextsprite == NULL ){ return; }
1187+
1188+ //テキストスプライト初期化
1189+ Start2DMSFontTextRender();
1190+
1191+ //基準座標を設定
1192+ D3DXMATRIX matWorld;
1193+ D3DXMatrixIdentity(&matWorld);
1194+ ptextsprite->SetTransform(&matWorld);
1195+
1196+ //文字をを描画
1197+ RECT rc = {x, y, x+w, y+h};
1198+ pxmsfont->DrawText(ptextsprite, str, -1, &rc, DT_CENTER, color);
1199+
1200+ //テキストスプライト解放
1201+ End2DMSFontTextRender();
1202+}
1203+
1204+//! @brief 2D システムフォントによるテキスト描画を終了
1205+//! @attention DirectXの ID3DXSprite を解放しています。
1206+void D3DGraphics::End2DMSFontTextRender()
1207+{
1208+ ptextsprite->End();
1209+}
1210+
1211+//! @brief 2D描画用設定
1212+void D3DGraphics::Start2DRender()
1213+{
1214+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
1215+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
1216+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
1217+
1218+ //深度バッファ比較関数を設定
1219+ pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
1220+}
1221+
1222+//! @brief 文字を描画(テクスチャフォント使用)
1223+//! @param x x座標
1224+//! @param y y座標
1225+//! @param str 文字列 (改行コード:<b>不可</b>)
1226+//! @param color 色
1227+//! @param fontwidth 一文字の幅
1228+//! @param fontheight 一文字の高さ
1229+//! @attention 文字を二重に重ねて立体感を出さないと見にくくなります。
1230+void D3DGraphics::Draw2DTextureFontText(int x, int y, char *str, int color, int fontwidth, int fontheight)
1231+{
1232+ //テクスチャフォントの取得に失敗していれば、処理しない
1233+ if( TextureFont == -1 ){ return; }
1234+
1235+ //2D描画用設定を適用
1236+ Start2DRender();
1237+
1238+ int w;
1239+ float font_u, font_v;
1240+ float t_u, t_v;
1241+ TLVERTX pBoxVertices[4];
1242+
1243+ //1文字のUV座標を計算
1244+ font_u = 1.0f / 16;
1245+ font_v = 1.0f / 16;
1246+
1247+ //ワールド座標を原点に戻す
1248+ ResetWorldTransform();
1249+
1250+ //テクスチャをフォントテクスチャに設定
1251+ pd3dDevice->SetTexture( 0, ptextures[TextureFont] );
1252+
1253+ //データ形式を設定
1254+ pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1255+
1256+ // 与えられた文字数分ループ
1257+ for(int i=0; i<(int)strlen(str); i++){
1258+ //UV座標を計算
1259+ w = str[i];
1260+ if( w < 0 ){ w += 256; }
1261+ t_u = (w % 16) * font_u;
1262+ t_v = (w / 16) * font_v;
1263+
1264+ //頂点座標・UV座標・色を設定
1265+ pBoxVertices[0].x = (float)x + i*fontwidth;
1266+ pBoxVertices[0].y = (float)y;
1267+ pBoxVertices[0].tu = t_u;
1268+ pBoxVertices[0].tv = t_v;
1269+ pBoxVertices[1].x = (float)x + fontwidth + i*fontwidth;
1270+ pBoxVertices[1].y = (float)y;
1271+ pBoxVertices[1].tu = t_u + font_u;
1272+ pBoxVertices[1].tv = t_v;
1273+ pBoxVertices[2].x = (float)x + i*fontwidth;
1274+ pBoxVertices[2].y = (float)y + fontheight;
1275+ pBoxVertices[2].tu = t_u;
1276+ pBoxVertices[2].tv = t_v + font_v;
1277+ pBoxVertices[3].x = (float)x + fontwidth + i*fontwidth;
1278+ pBoxVertices[3].y = (float)y + fontheight;
1279+ pBoxVertices[3].tu = t_u + font_u;
1280+ pBoxVertices[3].tv = t_v + font_v;
1281+ for(int j=0; j<4; j++){
1282+ pBoxVertices[j].z = 0.0f;
1283+ pBoxVertices[j].rhw = 1.0f;
1284+ pBoxVertices[j].color = color;
1285+ }
1286+
1287+ //描画
1288+ pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX));
1289+ }
1290+
1291+ //2D描画用設定を解除
1292+ End2DRender();
1293+}
1294+
1295+//! @brief 線を描画
1296+//! @param x1 始点の x座標
1297+//! @param y1 始点の y座標
1298+//! @param x2 終点の x座標
1299+//! @param y2 終点の y座標
1300+//! @param color 色
1301+void D3DGraphics::Draw2DLine(int x1, int y1, int x2, int y2, int color)
1302+{
1303+ TLVERTX pLineVertices[2];
1304+
1305+ //2D描画用設定を適用
1306+ Start2DRender();
1307+
1308+ //ワールド座標を原点に戻す
1309+ ResetWorldTransform();
1310+
1311+ //頂点座標と色などを設定
1312+ pLineVertices[0].x = (float)x1;
1313+ pLineVertices[0].y = (float)y1;
1314+ pLineVertices[1].x = (float)x2;
1315+ pLineVertices[1].y = (float)y2;
1316+ for(int i=0; i<2; i++){
1317+ pLineVertices[i].z = 0.0f;
1318+ pLineVertices[i].rhw = 1.0f;
1319+ pLineVertices[i].color = color;
1320+ pLineVertices[i].tu = 0.0f;
1321+ pLineVertices[i].tv = 0.0f;
1322+ }
1323+
1324+ pd3dDevice->SetTexture(0, NULL);
1325+
1326+ //データ形式を設定し、描画。
1327+ pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1328+ pd3dDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, pLineVertices, sizeof(TLVERTX));
1329+
1330+ //2D描画用設定を解除
1331+ End2DRender();
1332+}
1333+
1334+//! @brief 円(16角形)を描画
1335+//! @param x 中心の x座標
1336+//! @param y 中心の y座標
1337+//! @param r 半径
1338+//! @param color 色
1339+void D3DGraphics::Draw2DCycle(int x, int y, int r, int color)
1340+{
1341+ TLVERTX pLineVertices[16+1];
1342+
1343+ //2D描画用設定を適用
1344+ Start2DRender();
1345+
1346+ //ワールド座標を原点に戻す
1347+ ResetWorldTransform();
1348+
1349+ //頂点座標と色などを設定
1350+ for(int i=0; i<16+1; i++){
1351+ pLineVertices[i].x = (float)x + cos((float)M_PI*2/16 * i) * r;
1352+ pLineVertices[i].y = (float)y + sin((float)M_PI*2/16 * i) * r;
1353+
1354+ pLineVertices[i].z = 0.0f;
1355+ pLineVertices[i].rhw = 1.0f;
1356+ pLineVertices[i].color = color;
1357+ pLineVertices[i].tu = 0.0f;
1358+ pLineVertices[i].tv = 0.0f;
1359+ }
1360+
1361+ pd3dDevice->SetTexture(0, NULL);
1362+
1363+ //データ形式を設定し、描画。
1364+ pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1365+ pd3dDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, 16, pLineVertices, sizeof(TLVERTX));
1366+
1367+ //2D描画用設定を解除
1368+ End2DRender();
1369+}
1370+
1371+//! @brief 四角形を描画
1372+//! @param x1 左上の x座標
1373+//! @param y1 左上の y座標
1374+//! @param x2 右下の x座標
1375+//! @param y2 右下の y座標
1376+//! @param color 色
1377+void D3DGraphics::Draw2DBox(int x1, int y1, int x2, int y2, int color)
1378+{
1379+ TLVERTX pBoxVertices[4];
1380+
1381+ //2D描画用設定を適用
1382+ Start2DRender();
1383+
1384+ //ワールド座標を原点に戻す
1385+ ResetWorldTransform();
1386+
1387+ //頂点座標と色などを設定
1388+ pBoxVertices[0].x = (float)x1;
1389+ pBoxVertices[0].y = (float)y1;
1390+ pBoxVertices[1].x = (float)x2;
1391+ pBoxVertices[1].y = (float)y1;
1392+ pBoxVertices[2].x = (float)x1;
1393+ pBoxVertices[2].y = (float)y2;
1394+ pBoxVertices[3].x = (float)x2;
1395+ pBoxVertices[3].y = (float)y2;
1396+ for(int i=0; i<4; i++){
1397+ pBoxVertices[i].z = 0.0f;
1398+ pBoxVertices[i].rhw = 1.0f;
1399+ pBoxVertices[i].color = color;
1400+ pBoxVertices[i].tu = 0.0f;
1401+ pBoxVertices[i].tv = 0.0f;
1402+ }
1403+
1404+ pd3dDevice->SetTexture(0, NULL);
1405+
1406+ //データ形式を設定し、描画。
1407+ pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1408+ pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX));
1409+
1410+ //2D描画用設定を解除
1411+ End2DRender();
1412+}
1413+
1414+//! @brief 画像を描画
1415+//! @param x x座標
1416+//! @param y y座標
1417+//! @param id テクスチャ認識番号
1418+//! @param width 幅
1419+//! @param height 高さ
1420+//! @param alpha 透明度(0.0〜1.0)
1421+void D3DGraphics::Draw2DTexture(int x, int y, int id, int width, int height, float alpha)
1422+{
1423+ //無効なテクスチャ番号を指定されていれば処理しない
1424+ if( id == -1 ){ return; }
1425+
1426+ TLVERTX pBoxVertices[4];
1427+
1428+ //2D描画用設定を適用
1429+ Start2DRender();
1430+
1431+ //ワールド座標を原点に戻す
1432+ ResetWorldTransform();
1433+
1434+ //頂点座標・UV座標・色を設定
1435+ pBoxVertices[0].x = (float)x;
1436+ pBoxVertices[0].y = (float)y;
1437+ pBoxVertices[0].tu = 0.0f;
1438+ pBoxVertices[0].tv = 0.0f;
1439+ pBoxVertices[1].x = (float)x + width;
1440+ pBoxVertices[1].y = (float)y;
1441+ pBoxVertices[1].tu = 1.0f;
1442+ pBoxVertices[1].tv = 0.0f;
1443+ pBoxVertices[2].x = (float)x;
1444+ pBoxVertices[2].y = (float)y + height;
1445+ pBoxVertices[2].tu = 0.0f;
1446+ pBoxVertices[2].tv = 1.0f;
1447+ pBoxVertices[3].x = (float)x + width;
1448+ pBoxVertices[3].y = (float)y + height;
1449+ pBoxVertices[3].tu = 1.0f;
1450+ pBoxVertices[3].tv = 1.0f;
1451+ for(int i=0; i<4; i++){
1452+ pBoxVertices[i].z = 0.0f;
1453+ pBoxVertices[i].rhw = 1.0f;
1454+ pBoxVertices[i].color = D3DCOLOR_COLORVALUE(1.0f,1.0f,1.0f,alpha);
1455+ }
1456+
1457+ //テクスチャとデータ形式を設定し、描画
1458+ pd3dDevice->SetTexture( 0, ptextures[id] );
1459+ pd3dDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
1460+ pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pBoxVertices, sizeof(TLVERTX));
1461+
1462+ //2D描画用設定を解除
1463+ End2DRender();
1464+}
1465+
1466+//! @brief 2D描画用設定を解除
1467+void D3DGraphics::End2DRender()
1468+{
1469+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
1470+ pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
1471+
1472+ //深度バッファ比較関数を元に戻す
1473+ pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
1474+}
1475+
1476+//! @brief 画面のスクリーンショットを保存
1477+//! @param filename ファイル名
1478+//! @return 成功:true 失敗:false
1479+bool D3DGraphics::SaveScreenShot(char* filename)
1480+{
1481+ LPDIRECT3DSURFACE9 pSurface = NULL;
1482+ HRESULT hr;
1483+
1484+ //サーフェースを作成し、画面を取得
1485+ pd3dDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurface);
1486+
1487+ //サーフェイスを画像に出力
1488+ hr = D3DXSaveSurfaceToFile(filename, D3DXIFF_BMP, pSurface, NULL, NULL);
1489+
1490+ //解放
1491+ pSurface->Release();
1492+
1493+ if( hr == D3D_OK ){
1494+ return true;
1495+ }
1496+ return false;
1497+}
1498+
1499+//! @brief カラーコードを取得
1500+//! @param red 赤(0.0f〜1.0f)
1501+//! @param green 緑(0.0f〜1.0f)
1502+//! @param blue 青(0.0f〜1.0f)
1503+//! @param alpha 透明度(0.0f〜1.0f)
1504+//! @return カラーコード
1505+int D3DGraphics::GetColorCode(float red, float green, float blue, float alpha)
1506+{
1507+ return D3DCOLOR_COLORVALUE(red, green, blue, alpha);
1508+}
\ No newline at end of file
--- tags/v1.010-20150220/d3dgraphics.h (nonexistent)
+++ tags/v1.010-20150220/d3dgraphics.h (revision 45)
@@ -0,0 +1,160 @@
1+//! @file d3dgraphics.h
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+#ifndef DIRECTX_H
33+#define DIRECTX_H
34+
35+#define MAX_MODEL 96 //!< 最大モデル数
36+#define MAX_TEXTURE 64 //!< 最大テクスチャ数
37+
38+#define CLIPPINGPLANE_NEAR 1.0f //!< 近クリップ面(≒描画する最小距離)
39+#define CLIPPINGPLANE_FAR 800.0f //!< 遠クリップ面(≒描画する最大距離)
40+
41+#ifndef H_LAYERLEVEL
42+ #define H_LAYERLEVEL 1 //!< Select include file.
43+#endif
44+#include "main.h"
45+
46+#define BLOCKDATA_GPUMEMORY //!< @brief ブロックデータを格納するメモリーを選択 @details 定数宣言有効:GPUメモリー 定数宣言無効(コメント化):メインメモリー
47+
48+#pragma warning(disable:4819) //VC++警告防止
49+#include <d3dx9.h>
50+#pragma warning(default:4819)
51+
52+#pragma comment(lib, "d3d9.lib")
53+#pragma comment(lib, "d3dx9.lib")
54+
55+//! 3Dポリゴン描画用構造体
56+struct VERTEXTXTA
57+{
58+ D3DXVECTOR3 position; //!< The position
59+ DWORD color; //!< The color
60+ FLOAT tu; //!< The texture coordinates
61+ FLOAT tv; //!< The texture coordinates
62+};
63+
64+//! 2Dポリゴン描画用構造体
65+struct TLVERTX {
66+ FLOAT x; //!< position
67+ FLOAT y; //!< position
68+ FLOAT z; //!< position
69+ FLOAT rhw; //!< vector
70+ D3DCOLOR color; //!< color
71+ FLOAT tu; //!< texture coordinates
72+ FLOAT tv; //!< texture coordinates
73+};
74+
75+//! @brief 画面描画を行うクラス
76+//! @details 画面の描画機能やそれに直接関連する処理を行います。
77+//! @details 具体的に、3D描画・2D描画・モデルファイルやテクスチャ管理 を行う機能があります。
78+//! @details 内部ではDirectX 9を使用しています。
79+class D3DGraphics
80+{
81+ LPDIRECT3D9 pD3D; //!< DIRECT3D9のポインタ
82+ LPDIRECT3DDEVICE9 pd3dDevice; //!< DIRECT3DDEVICE9のポインタ
83+ float aspect; //!< 画面のアスペクト比
84+ bool fullscreenflag; //!< フルスクリーン表示
85+ LPD3DXMESH pmesh[MAX_MODEL]; //!< (Xファイル用)D3DXMESHのポインタ
86+ D3DMATERIAL9* pmaterials[MAX_MODEL]; //!< (Xファイル用)D3DMATERIAL9のポインタ
87+ DWORD nummaterials[MAX_MODEL]; //!< (Xファイル用)マテリアル数
88+ LPDIRECT3DTEXTURE9 ptextures[MAX_TEXTURE]; //!< テクスチャを格納
89+
90+ class BlockDataInterface* blockdata; //!< 読み込んだブロックデータを格納するクラスへのポインタ
91+ int bs; //!< ブロック数
92+ int mapTextureID[TOTAL_BLOCKTEXTURE]; //!< テクスチャ番号
93+#ifdef BLOCKDATA_GPUMEMORY
94+ LPDIRECT3DVERTEXBUFFER9 g_pVB; //!< 頂点情報(GPU管理)
95+#else
96+ VERTEXTXTA g_pVertices[MAX_BLOCKS][6][4]; //!< 頂点情報(CPU管理)
97+#endif
98+
99+ float HUD_myweapon_x[TOTAL_HAVEWEAPON]; //!< HUD_Aの武器表示 X座標
100+ float HUD_myweapon_y[TOTAL_HAVEWEAPON]; //!< HUD_Aの武器表示 Y座標
101+ float HUD_myweapon_z[TOTAL_HAVEWEAPON]; //!< HUD_Aの武器表示 Z座標
102+
103+ bool StartRenderFlag; //!< StartRender()関数 実行中を表すフラグ
104+
105+ LPD3DXSPRITE ptextsprite; //!< 2Dテクスチャスプライト
106+ LPD3DXFONT pxmsfont; //!< システムフォント
107+ char TextureFontFname[_MAX_PATH]; //!< テクスチャフォントのファイル名
108+ int TextureFont; //!< テクスチャフォントのテクスチャID
109+
110+ int InitSubset();
111+ void CleanupD3Dresource();
112+ void Start2DMSFontTextRender();
113+ void End2DMSFontTextRender();
114+ void Start2DRender();
115+ void End2DRender();
116+
117+public:
118+ D3DGraphics();
119+ ~D3DGraphics();
120+ int InitD3D(HWND hWnd, char *TextureFontFilename, bool fullscreen);
121+ int ResetD3D(HWND hWnd);
122+ int LoadModel(char* filename);
123+ int MorphingModel(int idA, int idB);
124+ void CleanupModel(int id);
125+ int LoadTexture(char* filename, bool texturefont, bool BlackTransparent);
126+ int GetTextureSize(int id, int *width, int *height);
127+ void CleanupTexture(int id);
128+ int StartRender();
129+ bool EndRender();
130+ void ResetZbuffer();
131+ void ResetWorldTransform();
132+ void SetWorldTransform(float x, float y, float z, float rx, float ry, float size);
133+ void SetWorldTransform(float x, float y, float z, float rx, float ry1, float ry2, float size);
134+ void SetWorldTransformEffect(float x, float y, float z, float rx, float ry, float rt, float size);
135+ void SetWorldTransformHumanWeapon(float x, float y, float z, float mx, float my, float mz, float rx, float ry, float size);
136+ void SetWorldTransformPlayerWeapon(bool rotation, float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float rx, float size);
137+ void GetWorldTransformPos(float *x, float *y, float *z);
138+ void SetFog(int skynumber);
139+ void SetCamera(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, float viewangle);
140+ void LoadMapdata(class BlockDataInterface* in_blockdata, char *directory);
141+ void DrawMapdata(bool wireframe);
142+ int GetMapTextureID(int id);
143+ void CleanupMapdata();
144+ void RenderModel(int id_model, int id_texture);
145+ void RenderBoard(int id_texture, float alpha);
146+ void ScreenBrightness(int Width, int Height, int Brightness);
147+ void Centerline();
148+ void Drawline(float x1, float y1, float z1, float x2, float y2, float z2);
149+ void Draw2DMSFontText(int x, int y, char *str, int color);
150+ void Draw2DMSFontTextCenter(int x, int y, int w, int h, char *str, int color);
151+ void Draw2DTextureFontText(int x, int y, char *str, int color, int fontwidth, int fontheight);
152+ void Draw2DLine(int x1, int y1, int x2, int y2, int color);
153+ void Draw2DCycle(int x, int y, int r, int color);
154+ void Draw2DBox(int x1, int y1, int x2, int y2, int color);
155+ void Draw2DTexture(int x, int y, int id, int width, int height, float alpha);
156+ bool SaveScreenShot(char *fname);
157+ int GetColorCode(float red, float green, float blue, float alpha);
158+};
159+
160+#endif
\ No newline at end of file
--- tags/v1.010-20150220/scene.cpp (nonexistent)
+++ tags/v1.010-20150220/scene.cpp (revision 45)
@@ -0,0 +1,250 @@
1+//! @file scene.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 "scene.h"
33+
34+//! @brief コンストラクタ
35+scene::scene()
36+{
37+ d3dg = NULL;
38+ inputCtrl = NULL;
39+ framecnt = 0;
40+}
41+
42+//! @brief ディストラクタ
43+scene::~scene()
44+{}
45+
46+//! @brief クラスを設定
47+void scene::SetClass(StateMachine *in_GameState, D3DGraphics *in_d3dg, InputControl *in_inputCtrl)
48+{
49+ GameState = in_GameState;
50+ d3dg = in_d3dg;
51+ inputCtrl = in_inputCtrl;
52+}
53+
54+//! @brief シーン作成
55+int scene::Create()
56+{
57+ inputCtrl->MoveMouseCenter();
58+ framecnt = 0;
59+
60+ GameState->NextState();
61+ return 0;
62+}
63+
64+//! @brief シーン入力処理
65+void scene::Input()
66+{
67+ inputCtrl->GetInputState(false);
68+
69+ if( inputCtrl->CheckKeyDown(GetEscKeycode()) ){
70+ GameState->PushBackSpaceKey();
71+ }
72+
73+ if( inputCtrl->CheckMouseButtonUpL() ){
74+ GameState->PushMouseButton();
75+ }
76+}
77+
78+//! @brief シーン計算処理
79+void scene::Process()
80+{
81+ framecnt += 1;
82+}
83+
84+//! @brief シーン描画処理
85+//! @return 成功:false 失敗:true
86+//! @attention 失敗した場合、D3DGraphicsクラスのResetD3D()関数を呼び出してください。
87+bool scene::RenderMain()
88+{
89+ if( d3dg->StartRender() ){ return true; }
90+
91+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
92+ d3dg->Draw2DTextureFontText(10, 10, "hello world !", d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
93+
94+ d3dg->ScreenBrightness(SCREEN_WIDTH, SCREEN_HEIGHT, GameConfig.GetBrightness());
95+
96+ return d3dg->EndRender();
97+}
98+
99+//! @brief シーン解放処理
100+void scene::Destroy()
101+{
102+ GameState->NextState();
103+}
104+
105+//! @brief フレームカウントを元にアルファ値・透明度を設定(1回)
106+//! @param tframecnt 対象とするカウント値
107+//! @param MaxAlpha 最大アルファ値
108+//! @param timingsec 間隔・秒数
109+//! @param offsetsec オフセット・秒数
110+//! @param reversal 反転フラグ(false:フィールドイン true:フィールドアウト)
111+//! @return アルファ値
112+float scene::GetEffectAlpha(unsigned int tframecnt, float MaxAlpha, float timingsec, float offsetsec, bool reversal)
113+{
114+ float alpha;
115+ unsigned int frametiming;
116+ unsigned int frameoffset;
117+
118+ frametiming = (unsigned int)(timingsec*GAMEFPS);
119+ frameoffset = (unsigned int)(offsetsec*GAMEFPS);
120+ alpha = MaxAlpha/frametiming * (tframecnt - frameoffset);
121+
122+ if( alpha < 0.0f ){ alpha = 0.0f; }
123+ if( alpha > 1.0f ){ alpha = 1.0f; }
124+
125+ if( reversal == true ){
126+ return 1.0f - alpha;
127+ }
128+ return alpha;
129+}
130+
131+//! @brief フレームカウントを元にアルファ値・透明度を設定(ループ)
132+//! @param tframecnt 対象とするカウント値
133+//! @param MaxAlpha 最大アルファ値
134+//! @param timingsec 間隔・秒数
135+//! @param reversal 反転フラグ(false:フィールドイン true:フィールドアウト)
136+//! @return アルファ値
137+float scene::GetEffectAlphaLoop(unsigned int tframecnt, float MaxAlpha, float timingsec, bool reversal)
138+{
139+ float alpha;
140+ unsigned int frametiming;
141+
142+ frametiming = (unsigned int)(timingsec*GAMEFPS);
143+ alpha = MaxAlpha/frametiming * (tframecnt%frametiming);
144+
145+ if( reversal == true ){
146+ return 1.0f - alpha;
147+ }
148+ return alpha;
149+}
150+
151+//! @brief コンストラクタ
152+D2Dscene::D2Dscene()
153+{}
154+
155+//! @brief ディストラクタ
156+D2Dscene::~D2Dscene()
157+{}
158+
159+//! @brief 2Dシーン初期化
160+int D2Dscene::Create()
161+{
162+ gametitle = d3dg->LoadTexture("data\\title.dds", false, false);
163+ GameState->NextState();
164+ if( gametitle == -1 ){ return 1; }
165+ return 0;
166+}
167+
168+//! @brief 2Dシーン描画処理(2D)
169+void D2Dscene::Render2D()
170+{
171+ d3dg->Draw2DTextureFontText(10, 10, "hello world !", d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
172+}
173+
174+//! @brief 2Dシーン描画処理(メイン)
175+//! @return 成功:false 失敗:true
176+//! @attention 失敗した場合、D3DGraphicsクラスのResetD3D()関数を呼び出してください。
177+bool D2Dscene::RenderMain()
178+{
179+ if( d3dg->StartRender() ){ return true; }
180+
181+ d3dg->Draw2DTexture(0, 0, gametitle, SCREEN_WIDTH, SCREEN_HEIGHT, 0.4f);
182+ d3dg->Draw2DBox(11, 11, SCREEN_WIDTH - 10, SCREEN_HEIGHT - 10, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.75f));
183+
184+ Render2D();
185+
186+ d3dg->ScreenBrightness(SCREEN_WIDTH, SCREEN_HEIGHT, GameConfig.GetBrightness());
187+
188+ return d3dg->EndRender();
189+}
190+
191+//! @brief 2Dシーン解放
192+void D2Dscene::Destroy()
193+{
194+ d3dg->CleanupTexture(gametitle);
195+ GameState->NextState();
196+}
197+
198+
199+//! @brief コンストラクタ
200+D3Dscene::D3Dscene()
201+{}
202+
203+//! @brief ディストラクタ
204+D3Dscene::~D3Dscene()
205+{}
206+
207+//! @brief 3Dシーンクラスを設定
208+void D3Dscene::SetClass(StateMachine *in_GameState, D3DGraphics *in_d3dg, InputControl *in_inputCtrl, SoundManager *in_GameSound)
209+{
210+ GameState = in_GameState;
211+ d3dg = in_d3dg;
212+ inputCtrl = in_inputCtrl;
213+ GameSound = in_GameSound;
214+}
215+
216+//! @brief 3Dシーン主計算処理
217+void D3Dscene::Process()
218+{
219+ GameSound->PlayWorldSound(camera_x, camera_y, camera_z, camera_rx);
220+}
221+
222+//! @brief 3Dシーンサウンド再生処理
223+void D3Dscene::Sound()
224+{
225+ //サウンドを再生
226+ GameSound->PlayWorldSound(camera_x, camera_y, camera_z, camera_rx);
227+}
228+
229+//! @brief 3Dシーン描画処理(3D)
230+void D3Dscene::Render3D()
231+{}
232+
233+//! @brief 3Dシーン描画処理(2D)
234+void D3Dscene::Render2D()
235+{}
236+
237+//! @brief 3Dシーン描画処理(メイン)
238+//! @return 成功:false 失敗:true
239+//! @attention 失敗した場合、D3DGraphicsクラスのResetD3D()関数を呼び出してください。
240+bool D3Dscene::RenderMain()
241+{
242+ if( d3dg->StartRender() ){ return true; }
243+
244+ Render3D();
245+ Render2D();
246+
247+ d3dg->ScreenBrightness(SCREEN_WIDTH, SCREEN_HEIGHT, GameConfig.GetBrightness());
248+
249+ return d3dg->EndRender();
250+}
\ No newline at end of file
--- tags/v1.010-20150220/gamemain.cpp (nonexistent)
+++ tags/v1.010-20150220/gamemain.cpp (revision 45)
@@ -0,0 +1,3100 @@
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+//! @brief 基本的な初期化処理
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+ //効果音初期化
100+ float volume;
101+ if( GameConfig.GetSoundFlag() == false ){
102+ volume = 0.0f;
103+ }
104+ else{
105+ volume = 1.0f;
106+ }
107+ GameSound.SetClass(&SoundCtrl, &Resource, &GameParamInfo);
108+ SoundCtrl.SetVolume(volume);
109+
110+ //オブジェクトマネージャー初期化
111+ ObjMgr.SetClass(&GameParamInfo, &d3dg, &Resource, &BlockData, &PointData, &CollD, &GameSound, &MIFdata);
112+
113+ //addonリスト作成
114+ GameAddon.LoadFiledata("addon\\");
115+
116+ GameInfoData.selectaddon = false;
117+
118+ return 0;
119+}
120+
121+//! @brief DirectXをリセットする
122+//! @return 失敗:1 それ以外:0
123+//! @attention 通常は、描画処理に失敗した場合に限り呼び出してください。
124+int ResetGame(HWND hWnd)
125+{
126+ int rtn = d3dg.ResetD3D(hWnd);
127+
128+ if( rtn == 0 ){
129+ //リソースを初期化
130+ Resource.LoadHumanModel();
131+ Resource.LoadWeaponModelTexture();
132+ Resource.LoadSmallObjectModelTexture();
133+ Resource.LoadScopeTexture();
134+ Resource.LoadBulletModelTexture();
135+ Resource.LoadEffectTexture();
136+
137+ //現在の画面を再スタートさせる
138+ GameState.PushF12Key();
139+ }
140+ if( rtn == 1 ){
141+ //
142+ }
143+ if( rtn == 2 ){
144+ MessageBox(hWnd, "Resetに失敗しました", "ERROR", MB_OK);
145+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
146+ return 1;
147+ }
148+ return 0;
149+}
150+
151+//! @brief コンストラクタ
152+opening::opening()
153+{}
154+
155+//! @brief ディストラクタ
156+opening::~opening()
157+{}
158+
159+int opening::Create()
160+{
161+ //ブロックデータ読み込み
162+ if( BlockData.LoadFiledata("data\\map10\\temp.bd1") ){
163+ //block data open failed
164+ return 1;
165+ }
166+ BlockData.CalculationBlockdata(false);
167+ d3dg->LoadMapdata(&BlockData, "data\\map10\\");
168+ CollD.InitCollision(&BlockData);
169+
170+ //ポイントデータ読み込み
171+ if( PointData.LoadFiledata("data\\map10\\op.pd1") ){
172+ //point data open failed
173+ return 1;
174+ }
175+ ObjMgr.LoadPointData();
176+ ObjMgr.SetPlayerID(MAX_HUMAN-1); //実在しない人をプレイヤーに(銃声のサウンド再生対策)
177+
178+ //AI設定
179+ for(int i=0; i<MAX_HUMAN; i++){
180+ HumanAI[i].SetClass(&ObjMgr, i, &BlockData, &PointData, &GameParamInfo, &CollD, GameSound);
181+ HumanAI[i].Init();
182+ }
183+
184+ //背景空読み込み
185+ Resource.LoadSkyModelTexture(1);
186+
187+ //opening_banner = d3dg->LoadTexture("banner.png", true, false);
188+
189+ //サウンド初期化
190+ GameSound->InitWorldSound();
191+
192+ //マウスカーソルを中央へ移動
193+ inputCtrl->MoveMouseCenter();
194+ framecnt = 0;
195+
196+ GameState->NextState();
197+ return 0;
198+}
199+
200+//! @todo カメラの移動を滑らかにする
201+void opening::Process()
202+{
203+ //オブジェクトマネージャーを実行
204+ ObjMgr.Process(-1, camera_rx, camera_ry);
205+
206+ //AIを実行
207+ for(int i=0; i<MAX_HUMAN; i++){
208+ HumanAI[i].Process();
209+ }
210+
211+ //カメラワークを求める
212+ if( framecnt < 3*((int)GAMEFPS) ){
213+ camera_x = -5.0f;
214+ camera_y = 58.0f;
215+ camera_z = 29.0f;
216+ camera_rx = (float)M_PI/180*206;
217+ camera_ry = (float)M_PI/180*12;
218+ }
219+ else if( framecnt < 5*((int)GAMEFPS) ){
220+ camera_rx += (float)M_PI/180*1.1f;
221+ camera_ry -= (float)M_PI/180*0.7f;
222+ }
223+ else if( framecnt < 17*((int)GAMEFPS) ){
224+ camera_z += 0.08f;
225+ camera_y -= 0.05f;
226+ }
227+ else {
228+ GameState->PushMouseButton();
229+ }
230+
231+ framecnt += 1;
232+}
233+
234+void opening::Render3D()
235+{
236+ int skymodel, skytexture;
237+
238+ //フォグとカメラを設定
239+ d3dg->SetFog(1);
240+ d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL);
241+
242+ //カメラ座標に背景空を描画
243+ d3dg->SetWorldTransform(camera_x, camera_y, camera_z, 0.0f, 0.0f, 2.0f);
244+ Resource.GetSkyModelTexture(&skymodel, &skytexture);
245+ d3dg->RenderModel(skymodel, skytexture);
246+
247+ //Zバッファを初期化
248+ d3dg->ResetZbuffer();
249+
250+ //マップを描画
251+ d3dg->ResetWorldTransform();
252+ d3dg->DrawMapdata(false);
253+
254+ //オブジェクトを描画
255+ ObjMgr.Render(camera_x, camera_y, camera_z, 0);
256+}
257+
258+void opening::Render2D()
259+{
260+ float effect = 0.0f;
261+
262+ //ブラックアウト設定
263+ if( framecnt < (int)(1.0f*GAMEFPS) ){
264+ effect = GetEffectAlpha(framecnt, 1.0f, 1.0f, 0.0f, true);
265+ }
266+ if( ((int)(1.0f*GAMEFPS) <= framecnt)&&(framecnt < (int)(13.0f*GAMEFPS)) ){
267+ effect = 0.0f;
268+ }
269+ if( ((int)(11.0f*GAMEFPS) <= framecnt)&&(framecnt < (int)(15.0f*GAMEFPS)) ){
270+ effect = GetEffectAlpha(framecnt, 1.0f, 4.0f, 11.0f, false);
271+ }
272+ if( (int)(15.0f*GAMEFPS) <= framecnt ){
273+ effect = 1.0f;
274+ }
275+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,effect));
276+
277+ //上下の黒縁描画
278+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, 40, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
279+ d3dg->Draw2DBox(0, SCREEN_HEIGHT - 40, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
280+
281+ //プロジェクト名
282+ if( ((int)(0.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(4.0f*GAMEFPS)) ){
283+ char str[32];
284+ float effectA = 1.0f;
285+ sprintf(str, GAMENAME" project", 0, 0);
286+ if( framecnt < (int)(1.5f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 0.5f, false); }
287+ if( framecnt > (int)(3.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 3.0f, true); }
288+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*22/2, SCREEN_HEIGHT - 140, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 22, 22);
289+ }
290+
291+ //スタッフ名・その1
292+ if( ((int)(4.0f*GAMEFPS) < framecnt)&&(framecnt < (int)(8.0f*GAMEFPS)) ){
293+ float effectA = 1.0f;
294+ if( framecnt < (int)(5.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 4.0f, false); }
295+ if( framecnt > (int)(7.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 7.0f, true); }
296+ d3dg->Draw2DTextureFontText(60, 150, "ORIGINAL", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 20, 20);
297+ }
298+ if( ((int)(4.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(8.5f*GAMEFPS)) ){
299+ float effectA = 1.0f;
300+ if( framecnt < (int)(5.5f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 4.5f, false); }
301+ if( framecnt > (int)(7.5f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 7.5f, true); }
302+ d3dg->Draw2DTextureFontText(100, 180, "nine-two", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 20, 20);
303+ d3dg->Draw2DTextureFontText(100, 210, "TENNKUU", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 20, 20);
304+ }
305+
306+ //スタッフ名・その2
307+ if( ((int)(7.0f*GAMEFPS) < framecnt)&&(framecnt < (int)(11.0f*GAMEFPS)) ){
308+ float effectA = 1.0f;
309+ if( framecnt < (int)(8.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 7.0f, false); }
310+ if( framecnt > (int)(10.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 10.0f, true); }
311+ d3dg->Draw2DTextureFontText(330, 300, "REMAKE", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 20, 20);
312+ }
313+ if( ((int)(7.5f*GAMEFPS) < framecnt)&&(framecnt < (int)(11.5f*GAMEFPS)) ){
314+ float effectA = 1.0f;
315+ if( framecnt < (int)(8.5f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 7.5f, false); }
316+ if( framecnt > (int)(10.5f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 10.5f, true); }
317+ d3dg->Draw2DTextureFontText(370, 330, "[-_-;](mikan)", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA), 20, 20);
318+ //d3dg->Draw2DTexture(410, 360, opening_banner, 200, 40, effectA);
319+ }
320+
321+ //ゲーム名
322+ if( (int)(12.0f*GAMEFPS) <= framecnt ){ //framecnt < (int)(17.0f*GAMEFPS)
323+ char str[32];
324+ float effectA = 1.0f;
325+ sprintf(str, GAMENAME, 0, 0);
326+ if( framecnt < (int)(13.0f*GAMEFPS) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 12.0f, false); }
327+ if( ((int)(16.0f*GAMEFPS) < framecnt)&&(framecnt < (int)(17.0f*GAMEFPS)) ){ effectA = GetEffectAlpha(framecnt, 1.0f, 1.0f, 16.0f, true); }
328+ if( framecnt >= (int)(17.0f*GAMEFPS) ){ effectA = 0.0f; }
329+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*22/2, (SCREEN_HEIGHT-11)/2, str, d3dg->GetColorCode(1.0f,0.0f,0.0f,effectA), 22, 22);
330+ }
331+}
332+
333+void opening::Destroy()
334+{
335+ //ブロックデータ解放
336+ d3dg->CleanupMapdata();
337+
338+ //オブジェクトマネージャー解放
339+ ObjMgr.Cleanup();
340+
341+ //背景空解放
342+ Resource.CleanupSkyModelTexture();
343+
344+ //d3dg->CleanupTexture(opening_banner);
345+
346+ GameState->NextState();
347+}
348+
349+//! @brief コンストラクタ
350+mainmenu::mainmenu()
351+{
352+ mainmenu_scrollitems_official = 0;
353+ mainmenu_scrollitems_addon = 0;
354+}
355+
356+//! @brief ディストラクタ
357+mainmenu::~mainmenu()
358+{}
359+
360+int mainmenu::Create()
361+{
362+ char path[MAX_PATH];
363+ char bdata[MAX_PATH];
364+ char pdata[MAX_PATH];
365+
366+ //デモを決定し読み込む
367+ switch( GetRand(6) ){
368+ case 0:
369+ strcpy(path, "data\\map2\\");
370+ break;
371+ case 1:
372+ strcpy(path, "data\\map4\\");
373+ break;
374+ case 2:
375+ strcpy(path, "data\\map5\\");
376+ break;
377+ case 3:
378+ strcpy(path, "data\\map7\\");
379+ break;
380+ case 4:
381+ strcpy(path, "data\\map8\\");
382+ break;
383+ case 5:
384+ strcpy(path, "data\\map16\\");
385+ break;
386+ }
387+ strcpy(bdata, path);
388+ strcat(bdata, "temp.bd1");
389+ strcpy(pdata, path);
390+ strcat(pdata, "demo.pd1");
391+
392+ //ブロックデータ読み込み
393+ if( BlockData.LoadFiledata(bdata) ){
394+ //block data open failed
395+ return 1;
396+ }
397+ BlockData.CalculationBlockdata(false);
398+ d3dg->LoadMapdata(&BlockData, path);
399+ CollD.InitCollision(&BlockData);
400+
401+ //ポイントデータ読み込み
402+ if( PointData.LoadFiledata(pdata) ){
403+ //point data open failed
404+ return 1;
405+ }
406+ ObjMgr.LoadPointData();
407+
408+ //AI設定
409+ for(int i=0; i<MAX_HUMAN; i++){
410+ HumanAI[i].SetClass(&ObjMgr, i, &BlockData, &PointData, &GameParamInfo, &CollD, GameSound);
411+ HumanAI[i].Init();
412+ }
413+
414+ gametitle = d3dg->LoadTexture("data\\title.dds", false, false);
415+
416+ //サウンド初期化
417+ GameSound->InitWorldSound();
418+
419+ mainmenu_mouseX = SCREEN_WIDTH/2;
420+ mainmenu_mouseY = SCREEN_HEIGHT/2;
421+
422+ //標準ミッションのスクロールバーの設定
423+ if( TOTAL_OFFICIALMISSION > TOTAL_MENUITEMS ){
424+ mainmenu_scrollbar_official_height = (float)(MAINMENU_H-25) / TOTAL_OFFICIALMISSION * TOTAL_MENUITEMS;
425+ mainmenu_scrollbar_official_scale = ((float)(MAINMENU_H-25) - mainmenu_scrollbar_official_height) / (TOTAL_OFFICIALMISSION - TOTAL_MENUITEMS);
426+ }
427+ else{
428+ mainmenu_scrollbar_official_height = 0.0f;
429+ mainmenu_scrollbar_official_scale = 0.0f;
430+ }
431+
432+ //addonのスクロールバーの設定
433+ if( GameAddon.GetTotaldatas() > TOTAL_MENUITEMS ){
434+ mainmenu_scrollbar_addon_height = (float)(MAINMENU_H-25) / GameAddon.GetTotaldatas() * TOTAL_MENUITEMS;
435+ mainmenu_scrollbar_addon_scale = ((float)(MAINMENU_H-25) - mainmenu_scrollbar_addon_height) / (GameAddon.GetTotaldatas() - TOTAL_MENUITEMS);
436+ }
437+ else{
438+ mainmenu_scrollbar_addon_height = 0.0f;
439+ mainmenu_scrollbar_addon_scale = 0.0f;
440+ }
441+
442+ mainmenu_scrollbar_official_y = 141;
443+ mainmenu_scrollbar_addon_y = 141;
444+ mainmenu_scrollbar_flag = false;
445+ inputCtrl->MoveMouseCenter();
446+ framecnt = 0;
447+
448+ GameState->NextState();
449+ return 0;
450+}
451+
452+void mainmenu::Input()
453+{
454+ inputCtrl->GetInputState(false);
455+
456+ //スクロールバーの情報などを取得
457+ int scrollitems;
458+ float scrollbar_height;
459+ float scrollbar_scale;
460+ int scrollbar_y;
461+ int totalmission;
462+ if( GameInfoData.selectaddon == false ){
463+ scrollitems = mainmenu_scrollitems_official;
464+ scrollbar_height = mainmenu_scrollbar_official_height;
465+ scrollbar_scale = mainmenu_scrollbar_official_scale;
466+ scrollbar_y = mainmenu_scrollbar_official_y;
467+ totalmission = TOTAL_OFFICIALMISSION;
468+ }
469+ else{
470+ scrollitems = mainmenu_scrollitems_addon;
471+ scrollbar_height = mainmenu_scrollbar_addon_height;
472+ scrollbar_scale = mainmenu_scrollbar_addon_scale;
473+ scrollbar_y = mainmenu_scrollbar_addon_y;
474+ totalmission = GameAddon.GetTotaldatas();
475+ }
476+
477+ //マウス座標を取得
478+ int y = mainmenu_mouseY;
479+ inputCtrl->GetMouseMovement(&mainmenu_mouseX, &mainmenu_mouseY);
480+ if( mainmenu_mouseX < 0 ){ mainmenu_mouseX = 0; }
481+ if( mainmenu_mouseX > SCREEN_WIDTH-1 ){ mainmenu_mouseX = SCREEN_WIDTH-1; }
482+ if( mainmenu_mouseY < 0 ){ mainmenu_mouseY = 0; }
483+ if( mainmenu_mouseY > SCREEN_HEIGHT-1 ){ mainmenu_mouseY = SCREEN_HEIGHT-1; }
484+
485+ //ESCキーを処理
486+ if( inputCtrl->CheckKeyDown(GetEscKeycode()) ){
487+ GameState->PushBackSpaceKey();
488+ }
489+
490+ //スクロールバーを押したか判定
491+ if( inputCtrl->CheckMouseButtonDownL() ){
492+ if( ((MAINMENU_X+341) < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+360))&&(MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems) < mainmenu_mouseY)
493+ &&(mainmenu_mouseY < MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems + scrollbar_height))
494+ ){
495+ mainmenu_scrollbar_flag = true;
496+ }
497+ }
498+
499+ if( inputCtrl->CheckMouseButtonUpL() ){
500+ mainmenu_scrollbar_flag = false;
501+
502+ // UP
503+ if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&(MAINMENU_Y < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30) ){
504+ if( scrollitems > 0 ){ scrollitems -= 1; }
505+ }
506+
507+ // DOWN
508+ 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)) ){
509+ if( scrollitems < (totalmission - TOTAL_MENUITEMS) ){ scrollitems += 1; }
510+ }
511+
512+ //ミッション選択
513+ for(int i=0; i<TOTAL_MENUITEMS; i++){
514+ char name[32];
515+ if( GameInfoData.selectaddon == false ){
516+ GameParamInfo.GetOfficialMission(scrollitems + i, name, NULL, NULL, NULL);
517+ }
518+ else{
519+ strcpy(name, GameAddon.GetMissionName(scrollitems + i));
520+ }
521+
522+ 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) ){
523+ GameInfoData.selectmission_id = scrollitems + i;
524+ GameState->PushMouseButton();
525+ }
526+ }
527+ }
528+
529+ //スクロールバーの移動
530+ if( mainmenu_scrollbar_flag == true ){
531+ scrollbar_y += mainmenu_mouseY - y;
532+ if( scrollbar_y < MAINMENU_Y+1 ){ scrollbar_y = MAINMENU_Y+1; }
533+ if( scrollbar_y > MAINMENU_Y+MAINMENU_H-24 - (int)(scrollbar_height) ){ scrollbar_y = MAINMENU_Y+MAINMENU_H-24 - (int)(scrollbar_height); }
534+
535+ scrollitems = (scrollbar_y - (MAINMENU_Y+1)) / (int)(scrollbar_scale);
536+ if( scrollitems < 0 ){
537+ scrollitems = 0;
538+ }
539+ if( scrollitems > (totalmission - TOTAL_MENUITEMS) ){
540+ scrollitems = (totalmission - TOTAL_MENUITEMS);
541+ }
542+ }
543+ else{
544+ scrollbar_y = MAINMENU_Y+1 + (int)(scrollbar_scale*scrollitems);
545+ }
546+
547+ //スクロールバーの情報などを反映
548+ if( GameInfoData.selectaddon == false ){
549+ mainmenu_scrollitems_official = scrollitems;
550+ mainmenu_scrollbar_official_y = scrollbar_y;
551+ }
552+ else{
553+ mainmenu_scrollitems_addon = scrollitems;
554+ mainmenu_scrollbar_addon_y = scrollbar_y;
555+ }
556+
557+ //標準ミッションとアドオンリストの切り替え
558+ if( inputCtrl->CheckMouseButtonUpL() ){
559+ if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){
560+ if( GameInfoData.selectaddon == false ){
561+ if( GameAddon.GetTotaldatas() > 0 ){
562+ GameInfoData.selectaddon = true;
563+ }
564+ }
565+ else{
566+ GameInfoData.selectaddon = false;
567+ }
568+ }
569+ }
570+}
571+
572+void mainmenu::Process()
573+{
574+ //オブジェクトマネージャーを実行
575+ ObjMgr.Process(-1, camera_rx, camera_ry);
576+
577+ //AIを実行
578+ for(int i=0; i<MAX_HUMAN; i++){
579+ HumanAI[i].Process();
580+ }
581+
582+ //カメラ位置を計算
583+ human *myHuman = ObjMgr.GetPlayerHumanObject();
584+ myHuman->GetPosData(&camera_x, &camera_y, &camera_z, NULL);
585+ camera_x -= 4.0f;
586+ camera_y += 22.0f;
587+ camera_z -= 12.0f;
588+ camera_rx = (float)M_PI/180 * (45);
589+ camera_ry = (float)M_PI/180 * (-25);
590+
591+ framecnt += 1;
592+}
593+
594+void mainmenu::Render3D()
595+{
596+ //フォグとカメラを設定
597+ d3dg->SetFog(0);
598+ d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL);
599+
600+ //Zバッファを初期化
601+ d3dg->ResetZbuffer();
602+
603+ //マップを描画
604+ d3dg->ResetWorldTransform();
605+ d3dg->DrawMapdata(false);
606+
607+ //オブジェクトを描画
608+ ObjMgr.Render(camera_x, camera_y, camera_z, 0);
609+}
610+
611+void mainmenu::Render2D()
612+{
613+ int color, color2;
614+ float effect;
615+
616+ //スクロールバーの情報などを取得
617+ int scrollitems;
618+ float scrollbar_height;
619+ int scrollbar_y;
620+ int totalmission;
621+ if( GameInfoData.selectaddon == false ){
622+ scrollitems = mainmenu_scrollitems_official;
623+ scrollbar_height = mainmenu_scrollbar_official_height;
624+ scrollbar_y = mainmenu_scrollbar_official_y;
625+ totalmission = TOTAL_OFFICIALMISSION;
626+ }
627+ else{
628+ scrollitems = mainmenu_scrollitems_addon;
629+ scrollbar_height = mainmenu_scrollbar_addon_height;
630+ scrollbar_y = mainmenu_scrollbar_addon_y;
631+ totalmission = GameAddon.GetTotaldatas();
632+ }
633+
634+ //ゲームのバージョン情報描画
635+ d3dg->Draw2DTextureFontText(522+1, 75+1, GAMEVERSION, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 18, 22);
636+ d3dg->Draw2DTextureFontText(522, 75, GAMEVERSION, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 18, 22);
637+
638+ //メニューエリア描画
639+ if( GameAddon.GetTotaldatas() > 0 ){ //addonがあれば
640+ d3dg->Draw2DBox(MAINMENU_X-1, MAINMENU_Y, MAINMENU_X+360, MAINMENU_Y+MAINMENU_H+1, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
641+ }
642+ else{
643+ d3dg->Draw2DBox(MAINMENU_X-1, MAINMENU_Y, MAINMENU_X+360, MAINMENU_Y+MAINMENU_H-24, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
644+ }
645+ d3dg->Draw2DBox(MAINMENU_X+341, MAINMENU_Y+1, MAINMENU_X+360, MAINMENU_Y+MAINMENU_H-24, d3dg->GetColorCode(0.5f,0.5f,0.5f,0.5f));
646+
647+ //スクロールバー描画
648+ if( totalmission > TOTAL_MENUITEMS ){
649+ //色を設定
650+ if( mainmenu_scrollbar_flag == true ){
651+ color = d3dg->GetColorCode(0.6f,0.3f,0.25f,1.0f);
652+ color2 = d3dg->GetColorCode(0.8f,0.3f,0.25f,1.0f);
653+ }
654+ else if( ((MAINMENU_X+341) < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+360))&&(scrollbar_y < mainmenu_mouseY)&&(mainmenu_mouseY < scrollbar_y + (int)scrollbar_height) ){
655+ color = d3dg->GetColorCode(0.4f,0.67f,0.57f,1.0f);
656+ color2 = d3dg->GetColorCode(0.38f,0.77f,0.64f,1.0f);
657+ }
658+ else{
659+ color = d3dg->GetColorCode(0.6f,0.6f,0.25f,1.0f);
660+ color2 = d3dg->GetColorCode(0.8f,0.8f,0.25f,1.0f);
661+ }
662+
663+ //描画
664+ d3dg->Draw2DBox(MAINMENU_X+341, scrollbar_y, MAINMENU_X+360, scrollbar_y + (int)scrollbar_height, color);
665+ d3dg->Draw2DBox(MAINMENU_X+341+3, scrollbar_y +3, MAINMENU_X+360-3, scrollbar_y + (int)scrollbar_height -3, color2);
666+ }
667+
668+ //'< UP >'描画
669+ if( scrollitems > 0 ){
670+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+1, "< UP >", d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 25, 26);
671+
672+ //文字の色を設定
673+ if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&(MAINMENU_Y < mainmenu_mouseY)&&(mainmenu_mouseY < MAINMENU_Y+30) ){
674+ color = d3dg->GetColorCode(0.0f,1.0f,1.0f,1.0f);
675+ }
676+ else{
677+ color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
678+ }
679+
680+ //文字を描画
681+ d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y, "< UP >", color, 25, 26);
682+ }
683+ else{
684+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+1, "< UP >", d3dg->GetColorCode(0.6f,0.6f,0.6f,1.0f), 25, 26);
685+ }
686+
687+ //'< DOWN >'描画
688+ if( scrollitems < (totalmission - TOTAL_MENUITEMS) ){
689+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-55+1, "< DOWN >", d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 25, 26);
690+
691+ //文字の色を設定
692+ 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)) ){
693+ color = d3dg->GetColorCode(0.0f,1.0f,1.0f,1.0f);
694+ }
695+ else{
696+ color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
697+ }
698+
699+ //文字を描画
700+ d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-55, "< DOWN >", color, 25, 26);
701+ }
702+ else{
703+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-55+1, "< DOWN >", d3dg->GetColorCode(0.6f,0.6f,0.6f,1.0f), 25, 26);
704+ }
705+
706+ //標準ミッションとaddon切り替え
707+ if( GameInfoData.selectaddon == false ){
708+ //addonがあれば
709+ if( GameAddon.GetTotaldatas() > 0 ){
710+ //文字の色を設定
711+ if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){
712+ color = d3dg->GetColorCode(0.0f,1.0f,1.0f,1.0f);
713+ }
714+ else{
715+ color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
716+ }
717+
718+ //文字を描画
719+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-25+1, "ADD-ON MISSIONS >>", d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 17, 22);
720+ d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-25, "ADD-ON MISSIONS >>", color, 17, 22);
721+ }
722+ }
723+ else{
724+ //addonがあれば
725+ //if( GameAddon.GetTotaldatas() > 0 ){
726+ //文字の色を設定
727+ if( (MAINMENU_X < mainmenu_mouseX)&&(mainmenu_mouseX < (MAINMENU_X+340))&&((MAINMENU_Y+MAINMENU_H-25) < mainmenu_mouseY)&&(mainmenu_mouseY < (MAINMENU_Y+MAINMENU_H-2)) ){
728+ color = d3dg->GetColorCode(0.0f,1.0f,1.0f,1.0f);
729+ }
730+ else{
731+ color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
732+ }
733+
734+ //文字を描画
735+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+MAINMENU_H-25+1, "<< STANDARD MISSIONS", d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 17, 22);
736+ d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+MAINMENU_H-25, "<< STANDARD MISSIONS", color, 17, 22);
737+ //}
738+ }
739+
740+ //ミッション名を描画
741+ for(int i=0; i<TOTAL_MENUITEMS; i++){
742+ char name[32];
743+ strcpy(name, "");
744+
745+ //ミッション名を取得
746+ if( GameInfoData.selectaddon == false ){
747+ GameParamInfo.GetOfficialMission(scrollitems + i, name, NULL, NULL, NULL);
748+ }
749+ else{
750+ strcpy(name, GameAddon.GetMissionName(scrollitems + i));
751+ }
752+
753+ //文字の色を設定
754+ 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) ){
755+ color = d3dg->GetColorCode(1.0f,0.6f,0.6f,1.0f);
756+ }
757+ else{
758+ color = d3dg->GetColorCode(0.6f,0.6f,1.0f,1.0f);
759+ }
760+
761+ //文字を描画
762+ d3dg->Draw2DTextureFontText(MAINMENU_X+1, MAINMENU_Y+30+1 + i*30, name, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 20, 26);
763+ d3dg->Draw2DTextureFontText(MAINMENU_X, MAINMENU_Y+30 + i*30, name, color, 20, 26);
764+ }
765+
766+ //マウスカーソル描画(赤線)
767+ d3dg->Draw2DBox(0, mainmenu_mouseY-1, SCREEN_WIDTH, mainmenu_mouseY+1, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
768+ d3dg->Draw2DBox(mainmenu_mouseX-1, 0, mainmenu_mouseX+1, SCREEN_HEIGHT, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
769+ d3dg->Draw2DLine(0, mainmenu_mouseY, SCREEN_WIDTH, mainmenu_mouseY, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
770+ d3dg->Draw2DLine(mainmenu_mouseX, 0, mainmenu_mouseX, SCREEN_HEIGHT, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
771+
772+ //ゲームのロゴマーク描画
773+ d3dg->Draw2DTexture(20, 25, gametitle, 480, 80, 1.0f);
774+
775+ //ブラックアウト設定
776+ if( framecnt < (int)(2.0f*GAMEFPS) ){
777+ effect = GetEffectAlpha(framecnt, 1.0f, 2.0f, 0.0f, true);
778+ }
779+ else{
780+ effect = 0.0f;
781+ }
782+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,effect));
783+}
784+
785+void mainmenu::Destroy()
786+{
787+ //ブロックデータ解放
788+ d3dg->CleanupMapdata();
789+
790+ //オブジェクトマネージャー解放
791+ ObjMgr.Cleanup();
792+
793+ //背景空解放
794+ Resource.CleanupSkyModelTexture();
795+
796+ d3dg->CleanupTexture(gametitle);
797+
798+ GameState->NextState();
799+}
800+
801+//! @brief コンストラクタ
802+briefing::briefing()
803+{}
804+
805+//! @brief ディストラクタ
806+briefing::~briefing()
807+{}
808+
809+int briefing::Create()
810+{
811+ char path[MAX_PATH];
812+ char pdata[MAX_PATH];
813+ char PictureA[MAX_PATH];
814+ char PictureB[MAX_PATH];
815+
816+ //背景画像を取得
817+ gametitle = d3dg->LoadTexture("data\\title.dds", false, false);
818+
819+ //mifファイルのファイルパス取得
820+ if( GameInfoData.selectaddon == false ){
821+ GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, NULL, path, pdata);
822+ strcat(path, pdata);
823+ strcat(path, ".txt");
824+ }
825+ else{
826+ strcpy(path, "addon\\");
827+ strcat(path, GameAddon.GetFileName(GameInfoData.selectmission_id));
828+ }
829+
830+ //mifファイルを読み込み
831+ if( MIFdata.LoadFiledata(path) != 0 ){
832+ //briefing data open failed
833+ return 1;
834+ }
835+
836+ //ブリーフィング画像のファイルパス取得
837+ MIFdata.GetPicturefilePath(PictureA, PictureB);
838+
839+ //ブリーフィング画像読み込み
840+ if( strcmp(PictureB, "!") == 0 ){
841+ TwoTexture = false;
842+ TextureA = d3dg->LoadTexture(PictureA, true, false);
843+ TextureB = -1;
844+ }
845+ else{
846+ TwoTexture = true;
847+ TextureA = d3dg->LoadTexture(PictureA, true, false);
848+ TextureB = d3dg->LoadTexture(PictureB, true, false);
849+ }
850+
851+ //マウスカーソルを中央へ移動
852+ inputCtrl->MoveMouseCenter();
853+ framecnt = 0;
854+
855+ GameState->NextState();
856+ return 0;
857+}
858+
859+void briefing::Render2D()
860+{
861+ float effectA = GetEffectAlphaLoop(framecnt, 0.8f, 0.7f, true);
862+ float effectB = GetEffectAlphaLoop(framecnt, 0.8f, 1.0f, true);
863+ int effectB_sizeW = (int)( (float)(framecnt%((int)(GAMEFPS*1.0f))) * 0.2f + 18 );
864+ int effectB_sizeH = (int)( (float)(framecnt%((int)(GAMEFPS*1.0f))) * 1.0f + 26 );
865+
866+ //メモ:背景画像の描画は、自動的に行われる。
867+
868+ //固定文字描画
869+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 60*4, 30, "BRIEFING", d3dg->GetColorCode(1.0f,1.0f,0.0f,effectA), 60, 42);
870+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH - 210 - effectB_sizeW*20/2, SCREEN_HEIGHT - 37 - effectB_sizeH/2,
871+ "LEFT CLICK TO BEGIN", d3dg->GetColorCode(1.0f,1.0f,1.0f,effectB), effectB_sizeW, effectB_sizeH);
872+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH - 210 - 18*20/2, SCREEN_HEIGHT - 37 - 26/2, "LEFT CLICK TO BEGIN", d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 18, 26);
873+
874+ //ブリーフィング画像描画
875+ if( TwoTexture == false ){
876+ d3dg->Draw2DBox(40, 180, 40+160, 180+150, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f));
877+ d3dg->Draw2DTexture(40, 180, TextureA, 160, 150, 1.0f);
878+ }
879+ else{
880+ d3dg->Draw2DBox(40, 130, 40+160, 130+150, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f));
881+ d3dg->Draw2DTexture(40, 130, TextureA, 160, 150, 1.0f);
882+
883+ d3dg->Draw2DBox(40, 300, 40+160, 300+150, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f));
884+ d3dg->Draw2DTexture(40, 300, TextureB, 160, 150, 1.0f);
885+ }
886+
887+ //ミッション名を取得・描画
888+ char mname[64];
889+ if( MIFdata.GetFiletype() == false ){
890+ GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, mname, NULL, NULL);
891+ }
892+ else{
893+ strcpy(mname, MIFdata.GetMissionFullname());
894+ }
895+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(mname)*18/2, 90, mname, d3dg->GetColorCode(1.0f,0.5f,0.0f,1.0f), 18, 25);
896+
897+ //ミッション説明を描画
898+ d3dg->Draw2DMSFontText(230, 180, MIFdata.GetBriefingText(), d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f));
899+}
900+
901+void briefing::Destroy(){
902+ //ブリーフィング画像を開放
903+ d3dg->CleanupTexture(TextureA);
904+ d3dg->CleanupTexture(TextureB);
905+
906+ //背景画像を開放
907+ d3dg->CleanupTexture(gametitle);
908+
909+ GameState->NextState();
910+}
911+
912+//! @brief コンストラクタ
913+maingame::maingame()
914+{
915+ ShowInfo_Debugmode = false;
916+ Camera_F2mode = 0;
917+ Camera_HOMEmode = false;
918+ time_input = 0;
919+ time_process_object = 0;
920+ time_process_ai = 0;
921+ time_process_event = 0;
922+ time_sound = 0;
923+ time_render = 0;
924+}
925+
926+//! @brief ディストラクタ
927+maingame::~maingame()
928+{}
929+
930+int maingame::Create()
931+{
932+ MainGameInfo = GameInfoData;
933+ char path[MAX_PATH];
934+ char bdata[MAX_PATH];
935+ char pdata[MAX_PATH];
936+ char pdata2[MAX_PATH];
937+
938+ //.bd1と.pd1のファイルパスを求める
939+ if( MIFdata.GetFiletype() == false ){
940+ GameParamInfo.GetOfficialMission(MainGameInfo.selectmission_id, NULL, NULL, path, pdata2);
941+
942+ strcpy(bdata, path);
943+ strcat(bdata, "temp.bd1");
944+ strcpy(pdata, path);
945+ strcat(pdata, pdata2);
946+ strcat(pdata, ".pd1");
947+ }
948+ else{
949+ MIFdata.GetDatafilePath(bdata, pdata);
950+
951+ strcpy(path, bdata);
952+ for(int i=strlen(path)-1; i>0; i--){
953+ if( path[i] == '\\' ){
954+ path[i+1] = 0x00;
955+ break;
956+ }
957+ }
958+ }
959+
960+ //追加小物を読み込む
961+ Resource.LoadAddSmallObject(MIFdata.GetAddSmallobjectModelPath(), MIFdata.GetAddSmallobjectTexturePath(), MIFdata.GetAddSmallobjectSoundPath());
962+
963+ //ブロックデータ読み込み
964+ if( BlockData.LoadFiledata(bdata) ){
965+ //block data open failed
966+ return 1;
967+ }
968+ BlockData.CalculationBlockdata(MIFdata.GetScreenFlag());
969+ d3dg->LoadMapdata(&BlockData, path);
970+ CollD.InitCollision(&BlockData);
971+
972+ //ポイントデータ読み込み
973+ if( PointData.LoadFiledata(pdata) ){
974+ //point data open failed
975+ return 1;
976+ }
977+ ObjMgr.LoadPointData();
978+
979+ //AI設定
980+ for(int i=0; i<MAX_HUMAN; i++){
981+ HumanAI[i].SetClass(&ObjMgr, i, &BlockData, &PointData, &GameParamInfo, &CollD, GameSound);
982+ HumanAI[i].Init();
983+ }
984+
985+
986+ //背景空読み込み
987+ Resource.LoadSkyModelTexture(MIFdata.GetSkynumber());
988+
989+ //サウンド初期化
990+ GameSound->InitWorldSound();
991+
992+ //イベント初期化
993+ for(int i=0; i<TOTAL_EVENTLINE; i++){
994+ Event[i].SetClass(&PointData, &ObjMgr);
995+ }
996+ Event[0].Reset(TOTAL_EVENTENTRYPOINT_0);
997+ Event[1].Reset(TOTAL_EVENTENTRYPOINT_1);
998+ Event[2].Reset(TOTAL_EVENTENTRYPOINT_2);
999+
1000+ //プレイヤーの向きを取得
1001+ ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry);
1002+
1003+ view_rx = 0.0f;
1004+ view_ry = 0.0f;
1005+ Camera_Debugmode = false;
1006+ tag = false;
1007+ radar = false;
1008+ wireframe = false;
1009+ CenterLine = false;
1010+ Camera_F1mode = false;
1011+ InvincibleID = -1;
1012+ PlayerAI = false;
1013+ AIstop = false;
1014+ AINoFight = false;
1015+ framecnt = 0;
1016+ start_framecnt = 0;
1017+ end_framecnt = 0;
1018+ message_id = -1;
1019+ message_cnt = 0;
1020+ redflash_flag = false;
1021+ MainGameInfo.missioncomplete = false;
1022+ MainGameInfo.fire = 0;
1023+ MainGameInfo.ontarget = 0;
1024+ MainGameInfo.kill = 0;
1025+ MainGameInfo.headshot = 0;
1026+
1027+#ifdef ENABLE_DEBUGCONSOLE
1028+ Show_Console = false;
1029+
1030+ //コンソール用初期化
1031+ InfoConsoleData = new ConsoleData [MAX_CONSOLELINES];
1032+ InputConsoleData = new ConsoleData;
1033+ for(int i=0; i<MAX_CONSOLELINES; i++){
1034+ InfoConsoleData[i].color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
1035+ InfoConsoleData[i].textdata[0] = NULL;
1036+ }
1037+ InputConsoleData->color = d3dg->GetColorCode(1.0f,1.0f,0.0f,1.0f);
1038+ InputConsoleData->textdata[0] = NULL;
1039+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Game Debug Console.");
1040+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), " Command list >help");
1041+#endif
1042+
1043+ GameState->NextState();
1044+ return 0;
1045+}
1046+
1047+//! @brief 特定操作の入力をチェック
1048+bool maingame::CheckInputControl(int CheckKey, int mode)
1049+{
1050+ int KeyCode = OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey));
1051+ if( KeyCode == -1 ){
1052+ if( mode == 0 ){
1053+ return inputCtrl->CheckMouseButtonNowL();
1054+ }
1055+ if( mode == 1 ){
1056+ return inputCtrl->CheckMouseButtonDownL();
1057+ }
1058+ //if( mode == 2 ){
1059+ return inputCtrl->CheckMouseButtonUpL();
1060+ //}
1061+ }
1062+ if( KeyCode == -2 ){
1063+ if( mode == 0 ){
1064+ return inputCtrl->CheckMouseButtonNowR();
1065+ }
1066+ if( mode == 1 ){
1067+ return inputCtrl->CheckMouseButtonDownR();
1068+ }
1069+ //if( mode == 2 ){
1070+ return inputCtrl->CheckMouseButtonUpR();
1071+ //}
1072+ }
1073+ if( KeyCode == -3 ){
1074+ int CodeL, CodeR;
1075+ GetDoubleKeyCode(0, &CodeL, &CodeR);
1076+ if( mode == 0 ){
1077+ if( inputCtrl->CheckKeyNow(CodeL) ){
1078+ return true;
1079+ }
1080+ return inputCtrl->CheckKeyNow(CodeR);
1081+ }
1082+ if( mode == 1 ){
1083+ if( inputCtrl->CheckKeyDown(CodeL) ){
1084+ return true;
1085+ }
1086+ return inputCtrl->CheckKeyDown(CodeR);
1087+ }
1088+ //if( mode == 2 ){
1089+ if( inputCtrl->CheckKeyUp(CodeL) ){
1090+ return true;
1091+ }
1092+ return inputCtrl->CheckKeyUp(CodeR);
1093+ //}
1094+ }
1095+ if( KeyCode == -4 ){
1096+ int CodeL, CodeR;
1097+ GetDoubleKeyCode(1, &CodeL, &CodeR);
1098+ if( mode == 0 ){
1099+ if( inputCtrl->CheckKeyNow(CodeL) ){
1100+ return true;
1101+ }
1102+ return inputCtrl->CheckKeyNow(CodeR);
1103+ }
1104+ if( mode == 1 ){
1105+ if( inputCtrl->CheckKeyDown(CodeL) ){
1106+ return true;
1107+ }
1108+ return inputCtrl->CheckKeyDown(CodeR);
1109+ }
1110+ //if( mode == 2 ){
1111+ if( inputCtrl->CheckKeyUp(CodeL) ){
1112+ return true;
1113+ }
1114+ return inputCtrl->CheckKeyUp(CodeR);
1115+ //}
1116+ }
1117+
1118+ if( mode == 0 ){
1119+ return inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) );
1120+ }
1121+ if( mode == 1 ){
1122+ return inputCtrl->CheckKeyDown( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) );
1123+ }
1124+ //if( mode == 2 ){
1125+ return inputCtrl->CheckKeyUp( OriginalkeycodeToDinputdef(GameConfig.GetKeycode(CheckKey)) );
1126+ //}
1127+}
1128+
1129+void maingame::Input()
1130+{
1131+ time = GetTimeMS();
1132+ static unsigned int bullettime = 0;
1133+
1134+ //プレイヤーのクラスを取得
1135+ human *myHuman = ObjMgr.GetPlayerHumanObject();
1136+ int PlayerID = ObjMgr.GetPlayerID();
1137+
1138+ //キー入力を取得
1139+ inputCtrl->GetInputState(true);
1140+ inputCtrl->MoveMouseCenter();
1141+
1142+ //マウスの移動量取得
1143+ int x, y;
1144+ float MouseSensitivity;
1145+ inputCtrl->GetMouseMovement(&x, &y);
1146+
1147+ //視点の移動量計算
1148+ float mang = 0.0f;
1149+ if( myHuman->GetScopeMode() == 0 ){ mang = 0.01f; }
1150+ if( myHuman->GetScopeMode() == 1 ){ mang = 0.0032f; }
1151+ if( myHuman->GetScopeMode() == 2 ){ mang = 0.0060f; }
1152+ MouseSensitivity = (float)M_PI/180 * mang * GameConfig.GetMouseSensitivity();
1153+
1154+ //マウス反転(オプション設定)が有効ならば、反転する。
1155+ if( GameConfig.GetInvertMouseFlag() == true ){
1156+ y *= -1;
1157+ }
1158+
1159+ if( Camera_Debugmode == false ){ //通常モードならば
1160+ if( myHuman->GetHP() > 0 ){
1161+ //マウスによる向きを計算
1162+ mouse_rx += x * MouseSensitivity;
1163+ mouse_ry -= y * MouseSensitivity;
1164+
1165+ //キー操作による向きを計算
1166+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x00)) ){ mouse_ry += (float)M_PI/180 * 3; } // [↑]
1167+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x01)) ){ mouse_ry -= (float)M_PI/180 * 3; } // [↓]
1168+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x02)) ){ mouse_rx -= (float)M_PI/180 * 3; } // [←]
1169+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x03)) ){ mouse_rx += (float)M_PI/180 * 3; } // [→]
1170+
1171+ if( mouse_ry > (float)M_PI/18*7 ) mouse_ry = (float)M_PI/18*7;
1172+ if( mouse_ry < (float)M_PI/18*7 *-1 ) mouse_ry = (float)M_PI/18*7 *-1;
1173+ }
1174+ }
1175+ else{ //デバックモードならば
1176+ //キー操作によりカメラ座標を計算
1177+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x00)) ){ camera_x += 2.0f; } // [↑]
1178+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x01)) ){ camera_x -= 2.0f; } // [↓]
1179+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x02)) ){ camera_z += 2.0f; } // [←]
1180+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x03)) ){ camera_z -= 2.0f; } // [→]
1181+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x48)) ){ camera_y += 2.0f; } //[NUM +]
1182+ if( inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x49)) ){ camera_y -= 2.0f; } //[NUM -]
1183+
1184+ //マウス移動をカメラの向きとして適用
1185+ //camera_rx -= x*0.0025f;
1186+ //camera_ry -= y*0.0025f;
1187+ camera_rx -= x * MouseSensitivity;
1188+ camera_ry -= y * MouseSensitivity;
1189+ if( camera_ry > (float)M_PI/18*7 ) camera_ry = (float)M_PI/18*7;
1190+ if( camera_ry < (float)M_PI/18*7 *-1 ) camera_ry = (float)M_PI/18*7 *-1;
1191+ }
1192+
1193+ //ゲーム終了操作かチェック
1194+ if( inputCtrl->CheckKeyDown(GetEscKeycode()) ){
1195+ GameState->PushBackSpaceKey();
1196+ }
1197+
1198+ //カメラ表示モード変更操作かチェック
1199+ if( inputCtrl->CheckKeyDown( GetFunctionKeycode(1) ) ){
1200+ if( Camera_F1mode == false ){
1201+ Camera_F1mode = true;
1202+ view_rx = 0.0f;
1203+ view_ry = (float)M_PI/8 * -1;
1204+ }
1205+ else{
1206+ Camera_F1mode = false;
1207+ view_rx = 0.0f;
1208+ view_ry = 0.0f;
1209+ }
1210+ }
1211+
1212+ //画面のUI変更操作かチェック
1213+ if( inputCtrl->CheckKeyDown( GetFunctionKeycode(2) ) ){
1214+ if( Camera_F2mode == 2 ){
1215+ Camera_F2mode = 0;
1216+ }
1217+ else{
1218+ Camera_F2mode += 1;
1219+ }
1220+ }
1221+
1222+ //リセット操作かチェック
1223+ if( inputCtrl->CheckKeyDown( GetFunctionKeycode(12) ) ){
1224+ GameState->PushF12Key();
1225+ }
1226+
1227+#ifdef ENABLE_DEBUGCONSOLE
1228+ //デバック用コンソールの表示操作かチェック
1229+ if( inputCtrl->CheckKeyDown( GetFunctionKeycode(11) ) ){
1230+ if( Show_Console == false ){
1231+ Show_Console = true;
1232+
1233+ strcpy(InputConsoleData->textdata, CONSOLE_PROMPT);
1234+ }
1235+ else{
1236+ Show_Console = false;
1237+ }
1238+ }
1239+
1240+ if( Show_Console == false ){
1241+#endif
1242+
1243+ if( PlayerAI == false ){
1244+
1245+ //前後左右の移動(走り)操作かチェック
1246+ if( CheckInputControl(KEY_MOVEFORWARD, 0) ){
1247+ ObjMgr.MoveForward(PlayerID);
1248+ }
1249+ if( CheckInputControl(KEY_MOVEBACKWARD, 0) ){
1250+ ObjMgr.MoveBack(PlayerID);
1251+ }
1252+ if( CheckInputControl(KEY_MOVELEFT, 0) ){
1253+ ObjMgr.MoveLeft(PlayerID);
1254+ }
1255+ if( CheckInputControl(KEY_MOVERIGHT, 0) ){
1256+ ObjMgr.MoveRight(PlayerID);
1257+ }
1258+
1259+ //歩き操作かチェック
1260+ if( CheckInputControl(KEY_WALK, 0) ){
1261+ ObjMgr.MoveWalk(PlayerID);
1262+ }
1263+
1264+ //ジャンプ操作かチェック
1265+ if( CheckInputControl(KEY_JUMP, 1) ){
1266+ ObjMgr.MoveJump(PlayerID);
1267+ }
1268+
1269+ if( Camera_Debugmode == true ){ //デバックモードならば
1270+ //発砲操作かチェック
1271+ if( CheckInputControl(KEY_Shot, 0) ){
1272+ //前回の発射より、4フレーム分よりも時間が経っていれば
1273+ if( bullettime + 4*((int)GAMEFPS) < GetTimeMS() ){
1274+ float x, y, z, rx, ry;
1275+ x = camera_x;
1276+ y = camera_y;
1277+ z = camera_z;
1278+ rx = camera_rx;
1279+ ry = camera_ry;
1280+
1281+ //未使用の弾オブジェクトを取得
1282+ bullet* newbullet = ObjMgr.GetNewBulletObject();
1283+ if( newbullet != NULL ){
1284+ //弾オブジェクトを設定
1285+ newbullet->SetPosData(x, y, z, rx, ry);
1286+ newbullet->SetParamData(40, 5, 10, 1024, ObjMgr.GetPlayerID(), true);
1287+ newbullet->SetDrawFlag(true);
1288+ GameSound->ShotWeapon(x, y, z, 0, 1024, true);
1289+
1290+ //スコアに加算
1291+ MainGameInfo.fire += 1;
1292+
1293+ //発射時間を記憶(連射間隔判定用)
1294+ bullettime = GetTimeMS();
1295+ }
1296+ }
1297+ }
1298+ }
1299+ else{ //デバックモードでなければ
1300+ HumanParameter humandata;
1301+ int id_param;
1302+ bool zombie;
1303+ int keymode;
1304+
1305+ //ゾンビかどうか判定
1306+ myHuman->GetParamData(&id_param, NULL, NULL, NULL);
1307+ GameParamInfo.GetHuman(id_param, &humandata);
1308+ if( humandata.type == 2 ){
1309+ zombie = true;
1310+ }
1311+ else{
1312+ zombie = false;
1313+ }
1314+
1315+ //連射モードを取得
1316+ if( zombie == true ){
1317+ keymode = 1;
1318+ }
1319+ else if( myHuman->GetWeaponBlazingmode() == false ){
1320+ keymode = 1;
1321+ }
1322+ else{
1323+ keymode = 0;
1324+ }
1325+
1326+ //発砲操作かチェック
1327+ if( CheckInputControl(KEY_Shot, keymode) ){
1328+
1329+ if( zombie == false ){
1330+ //弾の発射に成功すれば
1331+ if( ObjMgr.ShotWeapon(PlayerID) == 1 ){
1332+ //スコアに加算
1333+ MainGameInfo.fire += 1;
1334+
1335+ //プレイヤーの向きを取得
1336+ ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry);
1337+ }
1338+ }
1339+ else{
1340+ for(int i=0; i<MAX_HUMAN; i++){
1341+ human *EnemyHuman = ObjMgr.GeHumanObject(i);
1342+ if( ObjMgr.CheckZombieAttack(myHuman, EnemyHuman) == true ){
1343+ ObjMgr.HitZombieAttack(EnemyHuman);
1344+ }
1345+ }
1346+ }
1347+
1348+ }
1349+ }
1350+
1351+ //リロード操作かチェック
1352+ if( CheckInputControl(KEY_RELOAD, 1) ){
1353+ ObjMgr.ReloadWeapon(PlayerID);
1354+ }
1355+
1356+ //武器の切り替え操作かチェック
1357+ if( CheckInputControl(KEY_SWITCHWEAPON, 1) ){
1358+ ObjMgr.ChangeWeapon(PlayerID, -1);
1359+ }
1360+ if( CheckInputControl(KEY_WEAPON1, 1) ){
1361+ ObjMgr.ChangeWeapon(PlayerID, 0);
1362+ }
1363+ if( CheckInputControl(KEY_WEAPON2, 1) ){
1364+ ObjMgr.ChangeWeapon(PlayerID, 1);
1365+ }
1366+
1367+ //武器の廃棄操作かチェック
1368+ if( CheckInputControl(KEY_DROPWEAPON, 1) ){
1369+ ObjMgr.DumpWeapon(PlayerID);
1370+ }
1371+
1372+ //スコープ操作かチェック
1373+ if( CheckInputControl(KEY_ZOOM, 1) ){
1374+ ObjMgr.ChangeScopeMode(PlayerID);
1375+ }
1376+
1377+ //連射モード変更操作かチェック
1378+ if( CheckInputControl(KEY_ShotMODE, 1) ){
1379+ ObjMgr.ChangeShotMode(PlayerID);
1380+ }
1381+
1382+ //カメラ操作
1383+ if( Camera_F1mode == true ){
1384+ if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x0C) ) ){ //NUM8
1385+ view_ry -= (float)M_PI/180 * 2;
1386+ }
1387+ if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x09) ) ){ //NUM5
1388+ view_ry += (float)M_PI/180 * 2;
1389+ }
1390+ if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x08) ) ){ //NUM4
1391+ view_rx -= (float)M_PI/180 * 2;
1392+ }
1393+ if( inputCtrl->CheckKeyNow( OriginalkeycodeToDinputdef(0x0A) ) ){ //NUM6
1394+ view_rx += (float)M_PI/180 * 2;
1395+ }
1396+ }
1397+
1398+ //裏技・上昇の操作かチェック
1399+ if( (inputCtrl->CheckKeyNow( GetFunctionKeycode(5) ))&&(inputCtrl->CheckKeyNow(OriginalkeycodeToDinputdef(0x0F))) ){ // F5 + [ENTER]
1400+ Cmd_F5 = true;
1401+ }
1402+ else{
1403+ Cmd_F5 = false;
1404+ }
1405+
1406+ //裏技・弾追加の操作かチェック
1407+ if( inputCtrl->CheckKeyNow( GetFunctionKeycode(6) ) ){
1408+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x0F)) ){ // [ENTER]
1409+ ObjMgr.CheatAddBullet(PlayerID);
1410+ }
1411+ }
1412+
1413+ //裏技・武器変更の操作かチェック
1414+ if( inputCtrl->CheckKeyNow( GetFunctionKeycode(7) ) ){
1415+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)) ){ // [←]
1416+ int id_param = myHuman->GetMainWeaponTypeNO();
1417+
1418+ //次の武器番号を計算
1419+ if( id_param >= TOTAL_PARAMETERINFO_WEAPON-1 ){ id_param = 0; }
1420+ else{ id_param += 1; }
1421+
1422+ ObjMgr.CheatNewWeapon(PlayerID, id_param);
1423+ }
1424+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03)) ){ // [→]
1425+ int id_param = myHuman->GetMainWeaponTypeNO();
1426+
1427+ //次の武器番号を計算
1428+ if( id_param <= 0 ){ id_param = TOTAL_PARAMETERINFO_WEAPON-1; }
1429+ else{ id_param -= 1; }
1430+
1431+ ObjMgr.CheatNewWeapon(PlayerID, id_param);
1432+ }
1433+ }
1434+
1435+ //裏技・人変更の操作かチェック
1436+ if( inputCtrl->CheckKeyNow( GetFunctionKeycode(8) ) ){
1437+ int Player_HumanID;
1438+
1439+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x02)) ){ // [←]
1440+ //現在のプレイヤー番号を取得
1441+ Player_HumanID = ObjMgr.GetPlayerID();
1442+
1443+ //次の人を計算
1444+ Player_HumanID += 1;
1445+ if( Player_HumanID >= MAX_HUMAN ){ Player_HumanID = 0; }
1446+
1447+ //対象プレイヤー番号を適用
1448+ ObjMgr.SetPlayerID(Player_HumanID);
1449+
1450+ //プレイヤーの向きを取得
1451+ ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry);
1452+ }
1453+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x03)) ){ // [→]
1454+ //現在のプレイヤー番号を取得
1455+ Player_HumanID = ObjMgr.GetPlayerID();
1456+
1457+ //次の人を計算
1458+ Player_HumanID -= 1;
1459+ if( Player_HumanID < 0 ){ Player_HumanID = MAX_HUMAN-1; }
1460+
1461+ //対象プレイヤー番号を適用
1462+ ObjMgr.SetPlayerID(Player_HumanID);
1463+
1464+ //プレイヤーの向きを取得
1465+ ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry);
1466+ }
1467+ }
1468+
1469+ //裏技・人追加の操作かチェック
1470+ if( inputCtrl->CheckKeyNow( GetFunctionKeycode(9) ) ){
1471+ if( (inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x00)))||(inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x01))) ){ // [↑]・[↓]
1472+ float x, y, z, r;
1473+ int param, dataid, team;
1474+ int selectweapon;
1475+ weapon *weapon[TOTAL_HAVEWEAPON];
1476+ int weapon_paramid[TOTAL_HAVEWEAPON];
1477+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1478+ weapon[i] = NULL;
1479+ weapon_paramid[i] = 0;
1480+ }
1481+ int id;
1482+
1483+ //プレイヤーの座標や武器を取得
1484+ myHuman->GetPosData(&x, &y, &z, &r);
1485+ myHuman->GetParamData(&param, &dataid, NULL, &team);
1486+ myHuman->GetWeapon(&selectweapon, weapon);
1487+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1488+ if( weapon[i] != NULL ){
1489+ weapon[i]->GetParamData(&weapon_paramid[i], NULL, NULL);
1490+ }
1491+ }
1492+
1493+ //プレイヤーの目の前の座標を取得
1494+ x += cos(r*-1 + (float)M_PI/2)*10.0f;
1495+ y += 5.0f;
1496+ z += sin(r*-1 + (float)M_PI/2)*10.0f;
1497+
1498+ //人を追加
1499+ id = ObjMgr.AddHumanIndex(x, y, z, r, param, team, weapon_paramid);
1500+ if( id >= 0 ){
1501+ ObjMgr.ChangeWeapon(id, selectweapon);
1502+
1503+ //AIを設定
1504+ HumanAI[id].Init();
1505+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x00)) ){ // [↑]
1506+ HumanAI[id].SetHoldTracking(dataid);
1507+ }
1508+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x01)) ){ // [↓]
1509+ HumanAI[id].SetHoldWait(x, z, r);
1510+ }
1511+ }
1512+ }
1513+ }
1514+
1515+ //裏技・腕表示の操作かチェック
1516+ if( inputCtrl->CheckKeyDown( GetHomeKeycode() ) ){
1517+ if( Camera_HOMEmode == false ){
1518+ Camera_HOMEmode = true;
1519+ }
1520+ else{
1521+ Camera_HOMEmode = false;
1522+ }
1523+ }
1524+ }
1525+
1526+#ifdef ENABLE_DEBUGCONSOLE
1527+ }
1528+ if( Show_Console == true ){
1529+ InputConsole();
1530+ }
1531+#endif
1532+
1533+ time_input = GetTimeMS() - time;
1534+}
1535+
1536+void maingame::Process()
1537+{
1538+ //プレイヤーのクラスを取得
1539+ human *myHuman = ObjMgr.GetPlayerHumanObject();
1540+
1541+ int ontarget, kill, headshot;
1542+
1543+ //-----------------------------------
1544+
1545+ time = GetTimeMS();
1546+
1547+ //武器の持ち方を取得
1548+ int weaponid;
1549+ WeaponParameter data;
1550+ weaponid = myHuman->GetMainWeaponTypeNO();
1551+ GameParamInfo.GetWeapon(weaponid, &data);
1552+
1553+ //プレイヤー(オブジェクト)の向きを設定
1554+ if( (PlayerAI == false)&&(myHuman->GetHP() > 0) ){
1555+ myHuman->SetRxRy(mouse_rx, mouse_ry);
1556+ }
1557+
1558+ //オブジェクトマネージャーを実行
1559+ if( Cmd_F5 == true ){
1560+ ObjMgr.Process( ObjMgr.GetPlayerID() , camera_rx, camera_ry);
1561+ }
1562+ else{
1563+ ObjMgr.Process(-1, camera_rx, camera_ry);
1564+ }
1565+
1566+ //プレイヤーの戦歴を加算
1567+ ObjMgr.GetHumanShotInfo( ObjMgr.GetPlayerID(), &ontarget, &kill, &headshot);
1568+ MainGameInfo.ontarget += ontarget;
1569+ MainGameInfo.kill += kill;
1570+ MainGameInfo.headshot += headshot;
1571+
1572+ time_process_object = GetTimeMS() - time;
1573+
1574+ //-----------------------------------
1575+
1576+ time = GetTimeMS();
1577+ if( AIstop == false ){
1578+ int PlayerID = ObjMgr.GetPlayerID();
1579+ for(int i=0; i<MAX_HUMAN; i++){
1580+ if( (PlayerAI == false)&&(i == PlayerID) ){ continue; }
1581+ //AIを実行
1582+ HumanAI[i].Process();
1583+ }
1584+ }
1585+ time_process_ai = GetTimeMS() - time;
1586+
1587+ //-----------------------------------
1588+
1589+ //ミッションが終了していなければ、
1590+ if( end_framecnt == 0 ){
1591+ int check = ObjMgr.CheckGameOverorComplete();
1592+
1593+ //ゲームクリアー判定
1594+ if( check == 1 ){
1595+ end_framecnt += 1;
1596+ MainGameInfo.missioncomplete = true;
1597+ }
1598+
1599+ //ゲームオーバー判定
1600+ if( check == 2 ){
1601+ end_framecnt += 1;
1602+ MainGameInfo.missioncomplete = false;
1603+ }
1604+ }
1605+
1606+ //-----------------------------------
1607+
1608+ time = GetTimeMS();
1609+ bool SetMessageID;
1610+ if( end_framecnt == 0 ){
1611+ //イベント実行
1612+ for(int i=0; i<TOTAL_EVENTLINE; i++){
1613+ SetMessageID = false;
1614+ Event[i].Execution(&end_framecnt, &MainGameInfo.missioncomplete, &message_id, &SetMessageID);
1615+
1616+ //イベントメッセージが再セットされていたら、カウントを戻す。
1617+ if( SetMessageID == true ){
1618+ message_cnt = 0;
1619+ }
1620+ }
1621+ }
1622+ if( (message_id != -1)&&(message_cnt < (int)(TOTAL_EVENTENT_SHOWMESSEC*GAMEFPS)) ){
1623+ message_cnt += 1;
1624+ }
1625+ else{
1626+ message_id = -1;
1627+ message_cnt = 0;
1628+ }
1629+ time_process_event = GetTimeMS() - time;
1630+
1631+ //-----------------------------------
1632+
1633+ float x, y, z;
1634+ myHuman->GetPosData(&x, &y, &z, NULL);
1635+
1636+ if( PlayerAI == true ){
1637+ //プレイヤーの向きを取得
1638+ ObjMgr.GetPlayerHumanObject()->GetRxRy(&mouse_rx, &mouse_ry);
1639+ }
1640+
1641+ //カメラワークを求める
1642+ if( Camera_Debugmode == true ){
1643+ //
1644+ }
1645+ else if( myHuman->GetHP() <= 0 ){
1646+ float rx = (float)M_PI/180*end_framecnt;
1647+ float ry = (float)M_PI/180*85*-1;
1648+ float r = 25.0f;
1649+
1650+ camera_x = x + cos(rx)*cos(ry)*r;
1651+ camera_y = y - sin(ry)*r;
1652+ camera_z = z + sin(rx)*cos(ry)*r;
1653+ camera_rx = rx;
1654+ camera_ry = ry;
1655+ }
1656+ else if( Camera_F1mode == true ){
1657+ float crx = view_rx + mouse_rx*-1 + (float)M_PI/2;
1658+ float cry = view_ry + mouse_ry;
1659+ float dist;
1660+ 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 ){
1661+ dist -= 1.0f;
1662+ }
1663+ else{
1664+ dist = 13.0f;
1665+ }
1666+ camera_x = x - cos(crx)*cos(cry)*dist;
1667+ camera_y = y + HUMAN_HEIGTH + sin(cry*-1)*dist;
1668+ camera_z = z - sin(crx)*cos(cry)*dist;
1669+ camera_rx = crx;
1670+ camera_ry = cry;
1671+ }
1672+ else{
1673+ camera_x = x;
1674+ camera_y = y + VIEW_HEIGHT;
1675+ camera_z = z;
1676+ camera_rx = view_rx + mouse_rx*-1 + (float)M_PI/2;
1677+ camera_ry = view_ry + mouse_ry;
1678+ }
1679+
1680+ //ダメージを受けていれば、レッドフラッシュを描画する
1681+ redflash_flag = myHuman->CheckHit();
1682+
1683+ //-----------------------------------
1684+
1685+#ifdef ENABLE_DEBUGCONSOLE
1686+ //デバック用コンソールを表示しており、かつミッション終了のカウントが始まっていなければ〜
1687+ if( (Show_Console == true)&&(end_framecnt == 0) ){
1688+ //デバック用コンソールのメイン処理
1689+ ProcessConsole();
1690+ }
1691+#endif
1692+
1693+ //-----------------------------------
1694+
1695+ framecnt += 1;
1696+ if( start_framecnt < (int)(1.0f*GAMEFPS) ){ //ミッション開始中なら
1697+ start_framecnt += 1;
1698+ }
1699+ if( end_framecnt == 1 ){ //ミッション終了直後ならば
1700+ MainGameInfo.framecnt = framecnt;
1701+ GameInfoData = MainGameInfo;
1702+ end_framecnt += 1;
1703+ }
1704+ else if( end_framecnt > 0 ){ //ミッション終了中ならば
1705+ if( end_framecnt < (int)(5.0f*GAMEFPS) ){
1706+ end_framecnt += 1;
1707+ }
1708+ else{
1709+ GameState->PushMouseButton();
1710+ }
1711+ }
1712+}
1713+
1714+void maingame::Sound()
1715+{
1716+ time = GetTimeMS();
1717+
1718+ //サウンドを再生
1719+ GameSound->PlayWorldSound(camera_x, camera_y, camera_z, camera_rx);
1720+
1721+ time_sound = GetTimeMS() - time;
1722+}
1723+
1724+void maingame::Render3D()
1725+{
1726+ time = GetTimeMS();
1727+
1728+
1729+ int skymodel, skytexture;
1730+ human *myHuman = ObjMgr.GetPlayerHumanObject();
1731+
1732+ //フォグとカメラを設定
1733+ d3dg->SetFog(MIFdata.GetSkynumber());
1734+ if( Camera_F1mode == false ){
1735+ int scopemode = myHuman->GetScopeMode();
1736+ float viewangle = 0.0f;
1737+
1738+ //スコープによる視野角を決定
1739+ if( scopemode == 0 ){ viewangle = VIEWANGLE_NORMAL; }
1740+ if( scopemode == 1 ){ viewangle = VIEWANGLE_SCOPE_1; }
1741+ if( scopemode == 2 ){ viewangle = VIEWANGLE_SCOPE_2; }
1742+
1743+ d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, viewangle);
1744+ }
1745+ else{
1746+ d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL);
1747+ }
1748+
1749+ //カメラ座標に背景空を描画
1750+ d3dg->SetWorldTransform(camera_x, camera_y, camera_z, 0.0f, 0.0f, 2.0f);
1751+ Resource.GetSkyModelTexture(&skymodel, &skytexture);
1752+ d3dg->RenderModel(skymodel, skytexture);
1753+
1754+ //Zバッファを初期化
1755+ d3dg->ResetZbuffer();
1756+
1757+ if( CenterLine == true ){
1758+ //中心線描画(デバック用)
1759+ d3dg->Centerline();
1760+ }
1761+
1762+ //マップを描画
1763+ d3dg->ResetWorldTransform();
1764+ d3dg->DrawMapdata(wireframe);
1765+
1766+ //プレイヤーの描画有無の決定
1767+ int DrawPlayer = 0;
1768+ if( (Camera_F1mode == false)&&(Camera_Debugmode == false)&&(myHuman->GetHP() > 0) ){
1769+ if( Camera_HOMEmode == false ){
1770+ DrawPlayer = 1;
1771+ }
1772+ else{
1773+ DrawPlayer = 2;
1774+ }
1775+ }
1776+ //オブジェクトを描画
1777+ ObjMgr.Render(camera_x, camera_y, camera_z, DrawPlayer);
1778+}
1779+
1780+void maingame::Render2D()
1781+{
1782+ char str[256];
1783+ unsigned char stru[256];
1784+ float fps = GetFps(10);
1785+ float effect;
1786+
1787+ human *myHuman = ObjMgr.GetPlayerHumanObject();
1788+
1789+ int selectweapon;
1790+ weapon *weapon[TOTAL_HAVEWEAPON];
1791+ int weapon_paramid[TOTAL_HAVEWEAPON];
1792+ WeaponParameter weapon_paramdata;
1793+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1794+ weapon[i] = NULL;
1795+ weapon_paramid[i] = 0;
1796+ }
1797+ int lnbs = 0;
1798+ int nbs = 0;
1799+ int reloadcnt = 0;
1800+ int selectweaponcnt = 0;
1801+ int weaponmodel, weapontexture;
1802+ char weaponname[16];
1803+ int hp;
1804+ int param_scopemode;
1805+ int param_WeaponP;
1806+ int ErrorRange;
1807+
1808+ //各種設定やゲーム情報を取得
1809+ myHuman->GetWeapon(&selectweapon, weapon);
1810+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1811+ if( weapon[i] != NULL ){
1812+ if( selectweapon == i ){
1813+ weapon[i]->GetParamData(&weapon_paramid[i], &lnbs, &nbs);
1814+ reloadcnt = weapon[i]->GetReloadCnt();
1815+ }
1816+ else{
1817+ weapon[i]->GetParamData(&weapon_paramid[i], NULL, NULL);
1818+ }
1819+ }
1820+ }
1821+ selectweaponcnt = myHuman->GetChangeWeaponCnt();
1822+ GameParamInfo.GetWeapon(weapon_paramid[selectweapon], &weapon_paramdata);
1823+ strcpy(weaponname, weapon_paramdata.name);
1824+ hp = myHuman->GetHP();
1825+ param_scopemode = weapon_paramdata.scopemode;
1826+ param_WeaponP = weapon_paramdata.WeaponP;
1827+ ErrorRange = myHuman->GetGunsightErrorRange();
1828+
1829+ float human_x, human_y, human_z, human_rx;
1830+ myHuman->GetPosData(&human_x, &human_y, &human_z, &human_rx);
1831+
1832+ //レッドフラッシュ描画
1833+ if( redflash_flag == true ){
1834+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
1835+ redflash_flag = false;
1836+ }
1837+
1838+ //スコープ表示
1839+ if( (Camera_F1mode == false)&&(myHuman->GetScopeMode() == 1) ){
1840+ d3dg->Draw2DTexture(0, 0, Resource.GetScopeTexture(), SCREEN_WIDTH, SCREEN_HEIGHT, 1.0f);
1841+ d3dg->Draw2DLine(SCREEN_WIDTH/2-49, SCREEN_HEIGHT/2, SCREEN_WIDTH/2-4, SCREEN_HEIGHT/2, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1842+ d3dg->Draw2DLine(SCREEN_WIDTH/2+4, SCREEN_HEIGHT/2, SCREEN_WIDTH/2+49, SCREEN_HEIGHT/2, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1843+ d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2-49, SCREEN_WIDTH/2, SCREEN_HEIGHT/2-4, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1844+ d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2+4, SCREEN_WIDTH/2, SCREEN_HEIGHT/2+49, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1845+ d3dg->Draw2DBox(SCREEN_WIDTH/2-50, SCREEN_HEIGHT/2-1, SCREEN_WIDTH/20+50, SCREEN_HEIGHT/2+1, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
1846+ d3dg->Draw2DBox(SCREEN_WIDTH/2-1, SCREEN_HEIGHT/2-50, SCREEN_WIDTH/2+1, SCREEN_HEIGHT/2+50, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
1847+ }
1848+ if( (Camera_F1mode == false)&&(myHuman->GetScopeMode() == 2) ){
1849+ d3dg->Draw2DTexture(0, 0, Resource.GetScopeTexture(), SCREEN_WIDTH, SCREEN_HEIGHT, 1.0f);
1850+ d3dg->Draw2DLine(0, SCREEN_HEIGHT/2, SCREEN_WIDTH, SCREEN_HEIGHT/2, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1851+ d3dg->Draw2DLine(SCREEN_WIDTH/2, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1852+ d3dg->Draw2DBox(0, SCREEN_HEIGHT/2-1, SCREEN_WIDTH, SCREEN_HEIGHT/2+1, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
1853+ d3dg->Draw2DBox(SCREEN_WIDTH/2-1, 0, SCREEN_WIDTH/2+1, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.5f));
1854+ }
1855+
1856+ //目隠し表示
1857+ if( (Camera_Debugmode == false)&&(hp > 0) ){
1858+
1859+ int scopemode = myHuman->GetScopeMode();
1860+ float addang;
1861+ float adddist = 1.2f;
1862+
1863+ //スコープによる視野角を決定
1864+ if( scopemode == 0 ){ addang = VIEWANGLE_NORMAL / 4; }
1865+ if( scopemode == 1 ){ addang = VIEWANGLE_SCOPE_1 / 4; }
1866+ if( scopemode == 2 ){ addang = VIEWANGLE_SCOPE_2 / 4; }
1867+
1868+ //上
1869+ 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 ){
1870+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT/2, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1871+ }
1872+
1873+ //下
1874+ 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 ){
1875+ d3dg->Draw2DBox(0, SCREEN_HEIGHT/2, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1876+ }
1877+
1878+ //左
1879+ 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 ){
1880+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH/2, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1881+ }
1882+
1883+ //右
1884+ 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 ){
1885+ d3dg->Draw2DBox(SCREEN_WIDTH/2, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f));
1886+ }
1887+ }
1888+
1889+ //デバック用・ゲーム情報の表示
1890+ if( (ShowInfo_Debugmode == true)||(Camera_Debugmode == true) ){
1891+ //システムフォントによる表示 見やすい・重い
1892+ /*
1893+ sprintf(str, "OpenXOPS テスト\ncamera x:%.2f y:%.2f z:%.2f rx:%.2f ry:%.2f\n"
1894+ "human[%d]:x:%.2f y:%.2f z:%.2f rx:%.2f\n"
1895+ "I:%02dms PO:%02dms PA:%02dms PE:%02dms R:%02dms",
1896+ camera_x, camera_y, camera_z, camera_rx, camera_ry,
1897+ ObjMgr.GetPlayerID(), human_x, human_y, human_z, human_rx,
1898+ time_input, time_process_object, time_process_ai, time_process_event, time_render);
1899+ d3dg->Draw2DMSFontText(10+1, 10+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f));
1900+ d3dg->Draw2DMSFontText(10, 10, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f));
1901+ */
1902+
1903+ //テクスチャフォントによる表示 軽い・見にくい
1904+ sprintf(str, "frame:%d time %02d:%02d", framecnt, framecnt/(int)GAMEFPS/60, framecnt/(int)GAMEFPS%60);
1905+ d3dg->Draw2DTextureFontText(10+1, 10+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f), 10, 14);
1906+ d3dg->Draw2DTextureFontText(10, 10, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 10, 14);
1907+ sprintf(str, "camera x:%.2f y:%.2f z:%.2f rx:%.2f ry:%.2f", camera_x, camera_y, camera_z, camera_rx, camera_ry);
1908+ d3dg->Draw2DTextureFontText(10+1, 30+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f), 10, 14);
1909+ d3dg->Draw2DTextureFontText(10, 30, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 10, 14);
1910+ 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);
1911+ d3dg->Draw2DTextureFontText(10+1, 50+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f), 10, 14);
1912+ d3dg->Draw2DTextureFontText(10, 50, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 10, 14);
1913+ 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);
1914+ d3dg->Draw2DTextureFontText(10+1, 70+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f), 10, 14);
1915+ d3dg->Draw2DTextureFontText(10, 70, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 10, 14);
1916+ sprintf(str, "Render:%02dms", time_render);
1917+ d3dg->Draw2DTextureFontText(10+1, 90+1, str, d3dg->GetColorCode(0.1f,0.1f,0.1f,1.0f), 10, 14);
1918+ d3dg->Draw2DTextureFontText(10, 90, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 10, 14);
1919+ }
1920+
1921+ //ゲーム実行速度の表示
1922+ if( 1 ){
1923+ sprintf(str, "fps:%.2f", fps);
1924+ }
1925+ else{
1926+ int speed = (int)(fps / (1000.0f/GAMEFRAMEMS) * 100);
1927+ sprintf(str, "PROCESSING SPEED %d%%", speed);
1928+ }
1929+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH - strlen(str)*14 - 14 +1, 10+1, str, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 14, 18);
1930+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH - strlen(str)*14 - 14, 10, str, d3dg->GetColorCode(1.0f,0.5f,0.0f,1.0f), 14, 18);
1931+
1932+ //HUD表示・モードA
1933+ if( Camera_F2mode == 0 ){
1934+ //左下エリア描画
1935+ //"ウエエエエエエオ"
1936+ stru[0] = 0xB3; stru[1] = 0xB4; stru[2] = 0xB4; stru[3] = 0xB4; stru[4] = 0xB4;
1937+ stru[5] = 0xB4; stru[6] = 0xB4; stru[7] = 0xB5; stru[8] = 0x00;
1938+ d3dg->Draw2DTextureFontText(15, SCREEN_HEIGHT - 105, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1939+ //"テトトトトトトナ"
1940+ for(int i=0; stru[i] != 0x00; i++){ stru[i] += 0x10; }
1941+ d3dg->Draw2DTextureFontText(15, SCREEN_HEIGHT - 105 +32, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1942+ //"ウエエカキキキクケ"
1943+ stru[0] = 0xB3; stru[1] = 0xB4; stru[2] = 0xB4; stru[3] = 0xB6; stru[4] = 0xB7;
1944+ stru[5] = 0xB7; stru[6] = 0xB7; stru[7] = 0xB8; stru[8] = 0xB9; stru[9] = 0x00;
1945+ d3dg->Draw2DTextureFontText(15, SCREEN_HEIGHT - 55, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1946+ //"テトトニヌヌヌネノ"
1947+ for(int i=0; stru[i] != 0x00; i++){ stru[i] += 0x10; }
1948+ d3dg->Draw2DTextureFontText(15, SCREEN_HEIGHT - 55 +32, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1949+
1950+ //右下エリア用文字コード設定
1951+ stru[0] = 0xB0;//'ー';
1952+ for(int i=1; i<HUDA_WEAPON_SIZEW-1; i++){
1953+ stru[i] = 0xB1;//'ア';
1954+ }
1955+ stru[HUDA_WEAPON_SIZEW-1] = 0xB2;//'イ';
1956+ stru[HUDA_WEAPON_SIZEW] = 0x00;
1957+
1958+ //右下エリア描画
1959+ d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1960+ for(int i=0; i<HUDA_WEAPON_SIZEW; i++){ stru[i] += 0x10; }
1961+ for(int i=1; i<HUDA_WEAPON_SIZEH-1; i++){
1962+ d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY + 32*i, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1963+ }
1964+ for(int i=0; i<HUDA_WEAPON_SIZEW; i++){ stru[i] += 0x10; }
1965+ d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX, HUDA_WEAPON_POSY + 32*(HUDA_WEAPON_SIZEH-1), (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,0.5f), 32, 32);
1966+
1967+ //武器の弾数表示
1968+ sprintf((char*)stru, "A%d B%d", lnbs, (nbs - lnbs));
1969+ for(int i=0; i<(int)strlen((char*)stru); i++){
1970+ if( stru[i] == 'A' ){ stru[i] = 0xBB; } //'サ'
1971+ if( stru[i] == 'B' ){ stru[i] = 0xBA; } //'コ'
1972+ }
1973+ d3dg->Draw2DTextureFontText(25, SCREEN_HEIGHT - 96, (char*)stru, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 23, 24);
1974+
1975+ //HPによる色の決定
1976+ int statecolor;
1977+ if( hp >= 100 ){
1978+ statecolor = d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f);
1979+ }
1980+ else if( hp >= 50 ){
1981+ statecolor = d3dg->GetColorCode(1.0f/50*(100-hp),1.0f,0.0f,1.0f);
1982+ }
1983+ else if( hp > 0 ){
1984+ statecolor = d3dg->GetColorCode(1.0f,1.0f/50*hp,0.0f,1.0f);
1985+ }
1986+ else{
1987+ statecolor = d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f);
1988+ }
1989+
1990+ //HP表示
1991+ if( hp >= 80 ){
1992+ d3dg->Draw2DTextureFontText(23, SCREEN_HEIGHT - 45, "STATE", statecolor, 18, 24);
1993+ d3dg->Draw2DTextureFontText(155, SCREEN_HEIGHT - 45, "FINE", statecolor, 18, 24);
1994+ }
1995+ else if( hp >= 40 ){
1996+ d3dg->Draw2DTextureFontText(23, SCREEN_HEIGHT - 45, "STATE", statecolor, 18, 24);
1997+ d3dg->Draw2DTextureFontText(135, SCREEN_HEIGHT - 45, "CAUTION", statecolor, 18, 24);
1998+ }
1999+ else if( hp > 0 ){
2000+ d3dg->Draw2DTextureFontText(23, SCREEN_HEIGHT - 45, "STATE", statecolor, 18, 24);
2001+ d3dg->Draw2DTextureFontText(140, SCREEN_HEIGHT - 45, "DANGER", statecolor, 18, 24);
2002+ }
2003+ else{
2004+ d3dg->Draw2DTextureFontText(23, SCREEN_HEIGHT - 45, "STATE", statecolor, 18, 24);
2005+ d3dg->Draw2DTextureFontText(155, SCREEN_HEIGHT - 45, "DEAD", statecolor, 18, 24);
2006+ }
2007+
2008+ //武器名表示
2009+ d3dg->Draw2DTextureFontText(HUDA_WEAPON_POSX + 9, HUDA_WEAPON_POSY + 4, weaponname, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 16, 20);
2010+ }
2011+
2012+ //HUD表示・モードB
2013+ if( Camera_F2mode == 1 ){
2014+ //画面周りの線
2015+ d3dg->Draw2DLine(0, 0, SCREEN_WIDTH-1, 0, d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f));
2016+ d3dg->Draw2DLine(SCREEN_WIDTH-1, 0, SCREEN_WIDTH-1, SCREEN_HEIGHT-1, d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f));
2017+ d3dg->Draw2DLine(0, 0, 0, SCREEN_HEIGHT-1, d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f));
2018+ d3dg->Draw2DLine(0, SCREEN_HEIGHT-1, SCREEN_WIDTH-1, SCREEN_HEIGHT-1, d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f));
2019+
2020+ //武器名表示
2021+ d3dg->Draw2DBox(8, SCREEN_HEIGHT - 32, 227, SCREEN_HEIGHT - 7, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.3f));
2022+ d3dg->Draw2DTextureFontText(10, SCREEN_HEIGHT - 30, weaponname, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 16, 20);
2023+ }
2024+
2025+ //レーダー描画
2026+ if( radar == true ){
2027+ RenderRadar();
2028+ }
2029+
2030+ //イベントメッセージ表示
2031+ if( (message_id != -1)&&(message_cnt < (int)(TOTAL_EVENTENT_SHOWMESSEC*GAMEFPS)) ){
2032+ char messtr[MAX_POINTMESSAGEBYTE];
2033+ PointData.GetMessageText(messtr, message_id);
2034+ float effectA = 1.0f;
2035+ if( message_cnt < (int)(0.2f*GAMEFPS) ){ effectA = GetEffectAlpha(message_cnt, 1.0f, 0.2f, 0.0f, false); }
2036+ if( (int)((TOTAL_EVENTENT_SHOWMESSEC-0.2f)*GAMEFPS) < message_cnt ){ effectA = GetEffectAlpha(message_cnt, 1.0f, 0.2f, (TOTAL_EVENTENT_SHOWMESSEC - 0.2f), true); }
2037+ d3dg->Draw2DMSFontTextCenter(0 +1, SCREEN_HEIGHT - 140 +1, SCREEN_WIDTH, 140, messtr, d3dg->GetColorCode(0.1f,0.1f,0.1f,effectA));
2038+ d3dg->Draw2DMSFontTextCenter(0, SCREEN_HEIGHT - 140, SCREEN_WIDTH, 140, messtr, d3dg->GetColorCode(1.0f,1.0f,1.0f,effectA));
2039+ }
2040+
2041+ //リロード表示
2042+ if( reloadcnt > 0 ){
2043+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 145 +3, SCREEN_HEIGHT - 180+3, "RELOADING", d3dg->GetColorCode(0.2f,0.2f,0.2f,1.0f), 32, 34);
2044+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 145, SCREEN_HEIGHT - 180, "RELOADING", d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 32, 34);
2045+ }
2046+
2047+ //武器切り替え表示
2048+ if( selectweaponcnt > 0 ){
2049+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 130 +3, SCREEN_HEIGHT - 180+3, "CHANGING", d3dg->GetColorCode(0.2f,0.2f,0.2f,1.0f), 32, 34);
2050+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 130, SCREEN_HEIGHT - 180, "CHANGING", d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 32, 34);
2051+ }
2052+
2053+ //照準表示
2054+ if( (Camera_F1mode == false)&&(param_WeaponP != 2) ){
2055+ if( (weapon[selectweapon] != NULL)&&(myHuman->GetScopeMode() == 0)&&(param_scopemode != 2) ){
2056+ if( (end_framecnt == 0)||(GameInfoData.missioncomplete == true) ){
2057+ if( GameConfig.GetAnotherGunsightFlag() ){ //オプション型
2058+ //照準の透明度
2059+ float alpha = 1.0f - (float)ErrorRange/40.0f;
2060+ if( alpha < 0.0f ){ alpha = 0.0f; }
2061+
2062+ d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2, SCREEN_WIDTH/2, SCREEN_HEIGHT/2+4, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
2063+ d3dg->Draw2DLine(SCREEN_WIDTH/2-15, SCREEN_HEIGHT/2+15, SCREEN_WIDTH/2-19, SCREEN_HEIGHT/2+19, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
2064+ d3dg->Draw2DLine(SCREEN_WIDTH/2+15, SCREEN_HEIGHT/2+15, SCREEN_WIDTH/2+19, SCREEN_HEIGHT/2+19, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f));
2065+ d3dg->Draw2DLine(SCREEN_WIDTH/2-4, SCREEN_HEIGHT/2+4, SCREEN_WIDTH/2+4, SCREEN_HEIGHT/2+4, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
2066+
2067+ d3dg->Draw2DLine(SCREEN_WIDTH/2-4 - ErrorRange, SCREEN_HEIGHT/2-4 - ErrorRange/2, SCREEN_WIDTH/2-4 - ErrorRange, SCREEN_HEIGHT/2+4 + ErrorRange/2, d3dg->GetColorCode(1.0f,0.0f,0.0f,alpha));
2068+ d3dg->Draw2DLine(SCREEN_WIDTH/2+4 + ErrorRange, SCREEN_HEIGHT/2-4 - ErrorRange/2, SCREEN_WIDTH/2+4 + ErrorRange, SCREEN_HEIGHT/2+4 + ErrorRange/2, d3dg->GetColorCode(1.0f,0.0f,0.0f,alpha));
2069+ }
2070+ else{ //標準型
2071+ d3dg->Draw2DLine(SCREEN_WIDTH/2-13, SCREEN_HEIGHT/2, SCREEN_WIDTH/2-3, SCREEN_HEIGHT/2, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
2072+ d3dg->Draw2DLine(SCREEN_WIDTH/2+13, SCREEN_HEIGHT/2, SCREEN_WIDTH/2+3, SCREEN_HEIGHT/2, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
2073+ d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2-13, SCREEN_WIDTH/2, SCREEN_HEIGHT/2-3, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
2074+ d3dg->Draw2DLine(SCREEN_WIDTH/2, SCREEN_HEIGHT/2+13, SCREEN_WIDTH/2, SCREEN_HEIGHT/2+3, d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f));
2075+
2076+ stru[0] = 0xBD; stru[1] = 0x00; //"ス"
2077+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 16 - ErrorRange, SCREEN_HEIGHT/2 - 16, (char*)stru, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f), 32, 32);
2078+ stru[0] = 0xBE; stru[1] = 0x00; //"セ"
2079+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 16 + ErrorRange, SCREEN_HEIGHT/2 - 16, (char*)stru, d3dg->GetColorCode(1.0f,0.0f,0.0f,0.5f), 32, 32);
2080+ }
2081+ }
2082+ }
2083+ }
2084+
2085+ if( tag == true ){
2086+ int color;
2087+ if( ObjMgr.GetObjectInfoTag(camera_x, camera_y, camera_z, camera_rx, camera_ry, &color, str) == true ){
2088+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*14/2 + 1, SCREEN_HEIGHT/2 + 30 +1 , str, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 14, 18);
2089+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(str)*14/2, SCREEN_HEIGHT/2 + 30, str, color, 14, 18);
2090+ }
2091+ }
2092+
2093+
2094+ //-----------------------------------
2095+
2096+ //Zバッファを初期化
2097+ d3dg->ResetZbuffer();
2098+
2099+
2100+ //HUD表示・モードA
2101+ if( Camera_F2mode == 0 ){
2102+ int notselectweapon = selectweapon + 1;
2103+ if( notselectweapon == TOTAL_HAVEWEAPON ){ notselectweapon = 0; }
2104+
2105+ //(3D描画)カメラ座標を暫定設定
2106+ d3dg->SetCamera(camera_x, camera_y, camera_z, camera_rx, camera_ry, VIEWANGLE_NORMAL);
2107+
2108+ //(3D描画)所持している武器モデルの描画・メイン武器
2109+ GameParamInfo.GetWeapon(weapon_paramid[selectweapon], &weapon_paramdata);
2110+ Resource.GetWeaponModelTexture(weapon_paramid[selectweapon], &weaponmodel, &weapontexture);
2111+ d3dg->SetWorldTransformPlayerWeapon(true, camera_x, camera_y, camera_z, camera_rx, camera_ry, (float)M_PI/180*framecnt*2, weapon_paramdata.size);
2112+ d3dg->RenderModel(weaponmodel, weapontexture);
2113+
2114+ //(3D描画)所持している武器モデルの描画・サブ武器
2115+ GameParamInfo.GetWeapon(weapon_paramid[notselectweapon], &weapon_paramdata);
2116+ Resource.GetWeaponModelTexture(weapon_paramid[notselectweapon], &weaponmodel, &weapontexture);
2117+ d3dg->SetWorldTransformPlayerWeapon(false, camera_x, camera_y, camera_z, camera_rx, camera_ry, 0.0f, weapon_paramdata.size);
2118+ d3dg->RenderModel(weaponmodel, weapontexture);
2119+ }
2120+
2121+ //-----------------------------------
2122+
2123+#ifdef ENABLE_DEBUGCONSOLE
2124+ if( Show_Console == true ){
2125+ if( ScreenShot == false ){
2126+ RenderConsole();
2127+ }
2128+ }
2129+#endif
2130+
2131+ //-----------------------------------
2132+
2133+
2134+ //スタート時と終了時のブラックアウト設定
2135+ if( start_framecnt < (int)(1.0f*GAMEFPS) ){
2136+ effect = GetEffectAlpha(start_framecnt, 1.0f, 1.0f, 0.0f, true);
2137+ }
2138+ else if( end_framecnt > 0 ){
2139+ effect = GetEffectAlpha(end_framecnt, 1.0f, 4.0f, 0.0f, false);
2140+ }
2141+ else{
2142+ effect = 0.0f;
2143+ }
2144+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, d3dg->GetColorCode(0.0f,0.0f,0.0f,effect));
2145+
2146+ //終了時の文字表示
2147+ if( end_framecnt > 0 ){
2148+ if( end_framecnt < (int)(1.0f*GAMEFPS) ){
2149+ effect = GetEffectAlpha(end_framecnt, 1.0f, 1.0f, 0.0f, false);
2150+ }
2151+ else if( end_framecnt > (int)(4.0f*GAMEFPS) ){
2152+ effect = GetEffectAlpha(end_framecnt, 1.0f, 1.0f, 4.0f, true);
2153+ }
2154+ else{
2155+ effect = 1.0f;
2156+ }
2157+
2158+ if( GameInfoData.missioncomplete == true ){
2159+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 252, SCREEN_HEIGHT/2 + 10, "objective complete", d3dg->GetColorCode(1.0f,0.5f,0.0f,effect), 28, 32);
2160+ }
2161+ else{
2162+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 210, SCREEN_HEIGHT/2 + 10, "mission failure", d3dg->GetColorCode(1.0f,0.0f,0.0f,effect), 28, 32);
2163+ }
2164+ }
2165+
2166+
2167+ time_render = GetTimeMS() - time;
2168+}
2169+
2170+//! @brief レーダーに表示する座標に変換
2171+//! @param in_x 空間 X座標
2172+//! @param in_y 空間 Y座標
2173+//! @param in_z 空間 Z座標
2174+//! @param RadarPosX レーダーの描画 X座標(左上基準)
2175+//! @param RadarPosY レーダーの描画 Y座標(左上基準)
2176+//! @param RadarSize レーダーの描画サイズ
2177+//! @param RadarWorldR レーダーにポイントする距離
2178+//! @param out_x 2D X座標 を受け取るポインタ
2179+//! @param out_y 2D X座標 を受け取るポインタ
2180+//! @param local_y ローカル Y座標 を受け取るポインタ(NULL可)
2181+//! @param check 計算の省略
2182+//! @return 成功:true 失敗:false
2183+//! @attention checkフラグを有効にすると、レーダーから外れることが明らかになった時点で計算を終了し、falseを返します。
2184+bool maingame::GetRadarPos(float in_x, float in_y, float in_z, int RadarPosX, int RadarPosY, int RadarSize, float RadarWorldR, int *out_x, int *out_y, float *local_y, bool check)
2185+{
2186+ bool outf = false;
2187+ float x, y, z, r, rx;
2188+ float x2, z2, r2, rx2;
2189+
2190+ //カメラとの距離を計算
2191+ x = in_x - camera_x;
2192+ y = in_y - camera_y;
2193+ z = in_z - camera_z;
2194+
2195+ //近ければ処理する
2196+ if( (check == false) || ((abs(x) < RadarWorldR*2)&&(abs(z) < RadarWorldR*2)&&(abs(y) < 80.0f)) ){
2197+ //角度を距離を計算
2198+ rx = atan2(z, x);
2199+ r = sqrt(x*x + z*z);
2200+
2201+ //カメラ基準の座標を再計算
2202+ rx2 = (rx - camera_rx)*-1 - (float)M_PI/2;
2203+ x2 = cos(rx2) * r;
2204+ z2 = sin(rx2) * r;
2205+
2206+ //収まるか判定
2207+ if( (check == false) || ((abs(x2) < RadarWorldR)&&(abs(z2) < RadarWorldR)) ){
2208+ //描画座標を計算
2209+ r2 = r / RadarWorldR * (RadarSize/2);
2210+ *out_x = (int)(RadarPosX+RadarSize/2 + cos(rx2) * r2);
2211+ *out_y = (int)(RadarPosY+RadarSize/2 + sin(rx2) * r2);
2212+ if( local_y != NULL ){ *local_y = y; }
2213+ outf = true;
2214+ }
2215+ }
2216+
2217+ return outf;
2218+}
2219+
2220+//! @brief 簡易レーダー表示
2221+void maingame::RenderRadar()
2222+{
2223+ int RadarPosX = 10; //レーダーの描画 X座標(左上基準)
2224+ int RadarPosY = 130; //レーダーの描画 Y座標(左上基準)
2225+ int RadarSize = 200; //レーダーの描画サイズ
2226+ float RadarWorldR = 300.0f; //レーダーにポイントする距離
2227+
2228+ float ecr = DISTANCE_CHECKPOINT / RadarWorldR * (RadarSize/2);
2229+
2230+ //下地と囲い
2231+ d3dg->Draw2DBox(RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.6f));
2232+ d3dg->Draw2DLine(RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY, d3dg->GetColorCode(0.0f,0.8f,0.0f,1.0f));
2233+ d3dg->Draw2DLine(RadarPosX+RadarSize, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, d3dg->GetColorCode(0.0f,0.8f,0.0f,1.0f));
2234+ d3dg->Draw2DLine(RadarPosX+RadarSize, RadarPosY+RadarSize, RadarPosX, RadarPosY+RadarSize, d3dg->GetColorCode(0.0f,0.8f,0.0f,1.0f));
2235+ d3dg->Draw2DLine(RadarPosX, RadarPosY+RadarSize, RadarPosX, RadarPosY, d3dg->GetColorCode(0.0f,0.8f,0.0f,1.0f));
2236+
2237+ //マップを描画
2238+ int bs = BlockData.GetTotaldatas();
2239+ for(int i=0; i< bs; i++){
2240+ blockdata bdata;
2241+ float x_min, y_min, z_min, x_max, y_max, z_max;
2242+ int vid[4];
2243+ int bvx[4], bvy[4];
2244+
2245+ //ブロックのデータを取得
2246+ BlockData.Getdata(&bdata, i);
2247+
2248+ //表示候補のブロックを検出(荒削り)
2249+ CollD.GetBlockPosMINMAX(bdata, &x_min, &y_min, &z_min, &x_max, &y_max, &z_max);
2250+ if( CollideBoxAABB(x_min, y_min, z_min, x_max, y_max, z_max, camera_x-RadarWorldR*2, camera_y-1.0f, camera_z-RadarWorldR*2, camera_x+RadarWorldR*2, camera_y+1.0f, camera_z+RadarWorldR*2) == true ){
2251+
2252+ //各面ごとに処理する
2253+ for(int j=0; j<6; j++){
2254+ //登れない斜面か判定 ※地面や階段などの傾斜を除外する
2255+ float angle = acos(bdata.material[j].vy);
2256+ if( (HUMAN_MAPCOLLISION_SLOPEANGLE < angle)&&(angle < (float)M_PI/18*12) ){
2257+
2258+ //ブロック頂点データの関連付けを取得
2259+ blockdataface(j, &(vid[0]), NULL);
2260+
2261+ //4頂点を計算
2262+ for(int k=0; k<4; k++){
2263+ GetRadarPos(bdata.x[ vid[k] ], bdata.y[ vid[k] ], bdata.z[ vid[k] ], RadarPosX, RadarPosY, RadarSize, RadarWorldR, &(bvx[k]), &(bvy[k]), NULL, false);
2264+ }
2265+
2266+ int line_x1, line_y1, line_x2, line_y2;
2267+
2268+ //レーダーの四角形に収まるように描画する
2269+ if( Get2DLineInBox(bvx[0], bvy[0], bvx[1], bvy[1], RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, &line_x1, &line_y1, &line_x2, &line_y2) == true ){
2270+ d3dg->Draw2DLine(line_x1, line_y1, line_x2, line_y2, d3dg->GetColorCode(0.8f,0.8f,0.8f,1.0f));
2271+ }
2272+ if( Get2DLineInBox(bvx[1], bvy[1], bvx[2], bvy[2], RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, &line_x1, &line_y1, &line_x2, &line_y2) == true ){
2273+ d3dg->Draw2DLine(line_x1, line_y1, line_x2, line_y2, d3dg->GetColorCode(0.8f,0.8f,0.8f,1.0f));
2274+ }
2275+ if( Get2DLineInBox(bvx[2], bvy[2], bvx[3], bvy[3], RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, &line_x1, &line_y1, &line_x2, &line_y2) == true ){
2276+ d3dg->Draw2DLine(line_x1, line_y1, line_x2, line_y2, d3dg->GetColorCode(0.8f,0.8f,0.8f,1.0f));
2277+ }
2278+ if( Get2DLineInBox(bvx[3], bvy[3], bvx[0], bvy[0], RadarPosX, RadarPosY, RadarPosX+RadarSize, RadarPosY+RadarSize, &line_x1, &line_y1, &line_x2, &line_y2) == true ){
2279+ d3dg->Draw2DLine(line_x1, line_y1, line_x2, line_y2, d3dg->GetColorCode(0.8f,0.8f,0.8f,1.0f));
2280+ }
2281+ }
2282+ }
2283+ }
2284+ }
2285+
2286+ //イベントの到着ポイントを描画
2287+ for(int i=0; i<TOTAL_EVENTLINE; i++){
2288+ signed char p4 = Event[i].GetNextP4();
2289+ pointdata data;
2290+ if( PointData.SearchPointdata(&data, 0x08, 0, 0, 0, p4, 0) != 0 ){
2291+ float y;
2292+ int x_2d, y_2d;
2293+ float alpha;
2294+
2295+ if( (data.p1 == 13)||(data.p1 == 16) ){
2296+ data.y += VIEW_HEIGHT;
2297+
2298+ if( GetRadarPos(data.x, data.y, data.z, RadarPosX, RadarPosY, RadarSize, RadarWorldR, &x_2d, &y_2d, &y, true) == true ){
2299+ //高さによる透明度
2300+ if( (abs(y) < 40.0f) ){
2301+ alpha = 1.0f;
2302+ }
2303+ else{
2304+ alpha = 0.5f;
2305+ }
2306+
2307+ //マーカー描画
2308+ d3dg->Draw2DCycle(x_2d, y_2d, (int)ecr, d3dg->GetColorCode(1.0f,0.5f,0.0f,alpha));
2309+ }
2310+ }
2311+ }
2312+ }
2313+
2314+ //プレイヤーの情報を取得
2315+ int PlayerID = ObjMgr.GetPlayerID();
2316+ int myteamid;
2317+ ObjMgr.GeHumanObject(PlayerID)->GetParamData(NULL, NULL, NULL, &myteamid);
2318+
2319+ //人を描画
2320+ for(int i=0; i<MAX_HUMAN; i++){
2321+ human* thuman;
2322+ float tx, ty, tz;
2323+ int tteamid;
2324+ float y;
2325+ int x_2d, y_2d;
2326+ float alpha;
2327+ int color;
2328+
2329+ //人のオブジェクトを取得
2330+ thuman = ObjMgr.GeHumanObject(i);
2331+
2332+ //使われていない人や死体は無視する
2333+ if( thuman->GetDrawFlag() == false ){ continue; }
2334+ if( thuman->GetDeadFlag() == true ){ continue; }
2335+
2336+ //人の情報を取得
2337+ thuman->GetPosData(&tx, &ty, &tz, NULL);
2338+ thuman->GetParamData(NULL, NULL, NULL, &tteamid);
2339+ ty += VIEW_HEIGHT;
2340+
2341+ if( GetRadarPos(tx, ty, tz, RadarPosX, RadarPosY, RadarSize, RadarWorldR, &x_2d, &y_2d, &y, true) == true ){
2342+ //高さによる透明度
2343+ if( (abs(y) < 40.0f) ){
2344+ alpha = 1.0f;
2345+ }
2346+ else{
2347+ alpha = 0.5f;
2348+ }
2349+
2350+ //マーカーの色を決定
2351+ if( PlayerID == i ){ color = d3dg->GetColorCode(1.0f,1.0f,0.0f,alpha); } //プレイヤー自身
2352+ else if( tteamid == myteamid ){ color = d3dg->GetColorCode(0.0f,0.5f,1.0f,alpha); } //味方
2353+ else{ color = d3dg->GetColorCode(1.0f,0.0f,0.5f,alpha); } //敵
2354+
2355+ //マーカー描画
2356+ d3dg->Draw2DBox(x_2d-3, y_2d-3, x_2d+3, y_2d+3, color);
2357+ }
2358+ }
2359+}
2360+
2361+#ifdef ENABLE_DEBUGCONSOLE
2362+
2363+//! @brief デバック用コンソールに新たな文字列を追加
2364+//! @param color 文字の色
2365+//! @param str 追加する文字列のポインタ
2366+//! @attention 新しい文字列は常に下から追加されます。
2367+//! @attention 表示可能行数(定数:MAX_CONSOLELINES)を上回る場合、最初の行(1行目)を削除し1行ずつずらした上で、一番下の行に追加します。
2368+void maingame::AddInfoConsole(int color, char *str)
2369+{
2370+ for(int i=0; i<MAX_CONSOLELINES; i++){
2371+ if( InfoConsoleData[i].textdata[0] == NULL ){
2372+ InfoConsoleData[i].color = color;
2373+ strcpy(InfoConsoleData[i].textdata, str);
2374+ return;
2375+ }
2376+ }
2377+
2378+ for(int i=1; i<MAX_CONSOLELINES; i++){
2379+ memcpy(&(InfoConsoleData[i-1]), &(InfoConsoleData[i]), sizeof(ConsoleData));
2380+ }
2381+ InfoConsoleData[MAX_CONSOLELINES-1].color = color;
2382+ strcpy(InfoConsoleData[MAX_CONSOLELINES-1].textdata, str);
2383+}
2384+
2385+//! @brief 入力用コンソールに文字を一文字追加
2386+//! @param inchar 追加する文字
2387+void maingame::ConsoleInputText(char inchar)
2388+{
2389+ for(int i=0; i<MAX_CONSOLELEN; i++){
2390+ if( InputConsoleData->textdata[i] == NULL ){
2391+ InputConsoleData->textdata[i] = inchar;
2392+ InputConsoleData->textdata[i+1] = NULL;
2393+ return;
2394+ }
2395+ }
2396+}
2397+
2398+//! @brief 入力用コンソールの文字を一文字削除
2399+void maingame::ConsoleDeleteText()
2400+{
2401+ int s = strlen(InputConsoleData->textdata);
2402+ if( s == (int)strlen(CONSOLE_PROMPT) ){ return; }
2403+ InputConsoleData->textdata[ s-1 ] = NULL;
2404+}
2405+
2406+//! @brief コマンドの判定および引数(整数値)を取得
2407+//! @param cmd 判定するコマンド文字のポインタ
2408+//! @param num 与えられた引数を受け取るポインタ
2409+//! @return 取得:true 判定外:false
2410+bool maingame::GetCommandNum(char *cmd, int *num)
2411+{
2412+ char str[MAX_CONSOLELEN];
2413+
2414+ //コマンド名を調べる
2415+ strcpy(str, NewCommand);
2416+ str[ strlen(cmd) ] = NULL;
2417+ if( strcmp(str, cmd) != 0 ){ return false; }
2418+
2419+ //「コマンド名_X」分の文字数に達しているかどうか
2420+ if( strlen(cmd)+2 > strlen(NewCommand) ){ return false; }
2421+
2422+ //与えられた数字を調べる
2423+ *num = atoi(&(NewCommand[ strlen(cmd)+1 ]));
2424+ return true;
2425+}
2426+
2427+//! @brief デバック用コンソールの入力処理
2428+void maingame::InputConsole()
2429+{
2430+ NewCommand[0] = NULL;
2431+
2432+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x0F)) ){ // [ENTER]
2433+ //何か入力されていれば〜
2434+ if( strcmp(InputConsoleData->textdata, CONSOLE_PROMPT) != 0 ){
2435+ //コンソールに追加し、未処理コマンドとして登録
2436+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), InputConsoleData->textdata);
2437+ strcpy(NewCommand, &(InputConsoleData->textdata[strlen(CONSOLE_PROMPT)]));
2438+ }
2439+
2440+ //入力エリアを初期化
2441+ strcpy(InputConsoleData->textdata, CONSOLE_PROMPT);
2442+ }
2443+ else{
2444+ //数字
2445+ for(char key=0x16; key<=0x1F; key++){
2446+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(key)) ){
2447+ ConsoleInputText(key + 0x1A);
2448+ }
2449+ }
2450+ for(char key=0x04; key<=0x0D; key++){
2451+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(key)) ){
2452+ ConsoleInputText(key + 0x2C);
2453+ }
2454+ }
2455+
2456+ //アルファベット小文字
2457+ for(char key=0x20; key<=0x39; key++){
2458+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(key)) ){
2459+ ConsoleInputText(key + 0x41);
2460+ }
2461+ }
2462+
2463+ //スペース
2464+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x11)) ){ // [SPACE]
2465+ ConsoleInputText(' ');
2466+ }
2467+
2468+ //一文字削除
2469+ if( inputCtrl->CheckKeyDown(OriginalkeycodeToDinputdef(0x0E)) ){ // [BACK]
2470+ ConsoleDeleteText();
2471+ }
2472+ }
2473+}
2474+
2475+//! @brief デバック用コンソールのメイン処理
2476+void maingame::ProcessConsole()
2477+{
2478+ char str[MAX_CONSOLELEN];
2479+ int id;
2480+
2481+ //コマンドリスト
2482+ if( strcmp(NewCommand, "help") == 0 ){
2483+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "help human result event");
2484+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "ver");
2485+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "info view center map");
2486+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "tag radar");
2487+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "revive treat <NUM> nodamage <NUM>");
2488+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "kill <NUM> break <NUM> newobj <NUM>");
2489+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "bot nofight caution stop");
2490+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "ss clear");
2491+ }
2492+
2493+ //人の統計情報
2494+ if( strcmp(NewCommand, "human") == 0 ){
2495+ int alivemyfriend = 0;
2496+ int myfriend = 0;
2497+ int aliveenemy = 0;
2498+ int enemy = 0;
2499+ int myteamid;
2500+
2501+ //プレイヤーのチーム番号を取得
2502+ ObjMgr.GetPlayerHumanObject()->GetParamData(NULL, NULL, NULL, &myteamid);
2503+
2504+ for(int i=0; i<MAX_HUMAN; i++){
2505+ int teamid;
2506+ bool deadflag;
2507+ human *thuman = ObjMgr.GeHumanObject(i);
2508+ if( thuman->GetDrawFlag() == true ){
2509+ //死亡状態とチーム番号を取得
2510+ deadflag = thuman->GetDeadFlag();
2511+ thuman->GetParamData(NULL, NULL, NULL, &teamid);
2512+
2513+ //カウント
2514+ if( teamid == myteamid ){
2515+ myfriend += 1;
2516+ if( deadflag == false ){ alivemyfriend += 1; }
2517+ }
2518+ else{
2519+ enemy += 1;
2520+ if( deadflag == false ){ aliveenemy += 1; }
2521+ }
2522+ }
2523+ }
2524+
2525+ sprintf(str, "Friend:%d/%d Enemy:%d/%d Total:%d/%d",
2526+ alivemyfriend, myfriend, aliveenemy, enemy, alivemyfriend + aliveenemy, myfriend + enemy);
2527+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2528+ }
2529+
2530+ //暫定リザルト表示
2531+ if( strcmp(NewCommand, "result") == 0 ){
2532+ float rate;
2533+ if( MainGameInfo.fire == 0 ){
2534+ rate = 0.0f;
2535+ }
2536+ else{
2537+ rate = (float)MainGameInfo.ontarget / MainGameInfo.fire * 100;
2538+ }
2539+
2540+ sprintf(str, "Time %02d:%02d / Fired %d / On target %d", framecnt/(int)GAMEFPS/60, framecnt/(int)GAMEFPS%60, MainGameInfo.fire, MainGameInfo.ontarget);
2541+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2542+ sprintf(str, "AR rate %.1f%% / Kill %d / HS %d", rate, MainGameInfo.kill, MainGameInfo.headshot);
2543+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2544+ }
2545+
2546+ //イベントタスク表示
2547+ if( strcmp(NewCommand, "event") == 0 ){
2548+ for(int i=0; i<TOTAL_EVENTLINE; i++){
2549+ signed char p4 = Event[i].GetNextP4();
2550+ pointdata data;
2551+ if( PointData.SearchPointdata(&data, 0x08, 0, 0, 0, p4, 0) == 0 ){
2552+ sprintf(str, "Event %d No task.", i);
2553+ }
2554+ else{
2555+ sprintf(str, "Event %d [%d][%d][%d][%d]", i, data.p1, data.p2, data.p3, data.p4);
2556+ }
2557+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2558+ }
2559+ }
2560+
2561+ //デバック用文字の表示
2562+ if( strcmp(NewCommand, "info") == 0 ){
2563+ if( ShowInfo_Debugmode == false ){
2564+ ShowInfo_Debugmode = true;
2565+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Show Debug information.");
2566+ }
2567+ else{
2568+ ShowInfo_Debugmode = false;
2569+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Hide Debug information.");
2570+ }
2571+ }
2572+
2573+ //フリーカメラ切り替え
2574+ if( strcmp(NewCommand, "view") == 0 ){
2575+ if( Camera_Debugmode == false ){
2576+ Camera_Debugmode = true;
2577+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Change FreeView mode.");
2578+ }
2579+ else{
2580+ Camera_Debugmode = false;
2581+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Change PlayerView mode.");
2582+ }
2583+
2584+ //デバックモード開始時のカメラ設定
2585+ if( Camera_Debugmode == true ){
2586+ camera_x = 100.0f;
2587+ camera_y = 100.0f;
2588+ camera_z = -100.0f;
2589+ camera_rx = (float)M_PI/180*135;
2590+ camera_ry = (float)M_PI/180*(-40);
2591+ }
2592+ }
2593+
2594+ //3Dの中心線表示
2595+ if( strcmp(NewCommand, "center") == 0 ){
2596+ if( CenterLine == false ){
2597+ CenterLine = true;
2598+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Show World center position.");
2599+ }
2600+ else{
2601+ CenterLine = false;
2602+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Hide World center position.");
2603+ }
2604+ }
2605+
2606+ //マップをワイヤーフレーム化
2607+ if( strcmp(NewCommand, "map") == 0 ){
2608+ if( wireframe == false ){
2609+ wireframe = true;
2610+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Draw map on the Wire frame.");
2611+ }
2612+ else{
2613+ wireframe = false;
2614+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Draw map on the Normal.");
2615+ }
2616+ }
2617+
2618+ //オブジェクトのタグを表示
2619+ if( strcmp(NewCommand, "tag") == 0 ){
2620+ if( tag == false ){
2621+ tag = true;
2622+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Show object information.");
2623+ }
2624+ else{
2625+ tag = false;
2626+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Hide object information.");
2627+ }
2628+ }
2629+
2630+ if( strcmp(NewCommand, "radar") == 0 ){
2631+ if( radar == false ){
2632+ radar = true;
2633+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Show Radar.");
2634+ }
2635+ else{
2636+ radar = false;
2637+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Hide Radar.");
2638+ }
2639+ }
2640+
2641+ //全ての死者を蘇生する
2642+ if( strcmp(NewCommand, "revive") == 0 ){
2643+ for(int i=0; i<MAX_HUMAN; i++){
2644+ ObjMgr.HumanResuscitation(i);
2645+ }
2646+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "All human has resuscitation.");
2647+ }
2648+
2649+ //回復する
2650+ if( GetCommandNum("treat", &id) == true ){
2651+ if( (0 <= id)&&(id < MAX_HUMAN) ){
2652+ int param, hp;
2653+ HumanParameter data;
2654+ human *thuman = ObjMgr.GeHumanObject(id);
2655+
2656+ //初期時のHPを取得
2657+ thuman->GetParamData(&param, NULL, NULL, NULL);
2658+ GameParamInfo.GetHuman(param, &data);
2659+ hp = data.hp;
2660+
2661+ //回復
2662+ if( thuman->SetHP(hp) == true ){
2663+ sprintf(str, "Set the HP:%d to Human[%d].", data.hp, id);
2664+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2665+ }
2666+ }
2667+ }
2668+
2669+ //無敵化
2670+ if( GetCommandNum("nodamage", &id) == true ){
2671+ if( (0 <= id)&&(id < MAX_HUMAN) ){
2672+ if( InvincibleID == id ){
2673+ //同じ番号が指定されたらなら、無効化
2674+ InvincibleID = -1;
2675+ ObjMgr.GeHumanObject(id)->SetInvincibleFlag(false);
2676+ sprintf(str, "Not invincible Human[%d].", id);
2677+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2678+ }
2679+ else{
2680+ //既に誰かが指定されていたら、既に指定されている人を無効化
2681+ if( InvincibleID != -1 ){
2682+ ObjMgr.GeHumanObject(InvincibleID)->SetInvincibleFlag(false);
2683+ sprintf(str, "Not invincible Human[%d].", InvincibleID);
2684+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2685+ }
2686+
2687+ //新たに無敵状態の人を指定
2688+ InvincibleID = id;
2689+ ObjMgr.GeHumanObject(id)->SetInvincibleFlag(true);
2690+ sprintf(str, "Invincible Human[%d].", id);
2691+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2692+ }
2693+ }
2694+ }
2695+
2696+ //殺害
2697+ if( GetCommandNum("kill", &id) == true ){
2698+ if( (0 <= id)&&(id < MAX_HUMAN) ){
2699+ human *thuman = ObjMgr.GeHumanObject(id);
2700+ if( thuman->GetDrawFlag() == true ){
2701+ if( thuman->SetHP(0) == true ){
2702+ sprintf(str, "Killed Human[%d].", id);
2703+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2704+ }
2705+ }
2706+ }
2707+ }
2708+
2709+ //小物を破壊
2710+ if( GetCommandNum("break", &id) == true ){
2711+ if( (0 <= id)&&(id < MAX_SMALLOBJECT) ){
2712+ smallobject *tsmallobject = ObjMgr.GetSmallObject(id);
2713+ if( tsmallobject->GetDrawFlag() == true ){
2714+ tsmallobject->Destruction();
2715+ sprintf(str, "Broke SmallObject[%d].", id);
2716+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2717+ }
2718+ }
2719+ }
2720+
2721+ //小物を新規配置
2722+ if( GetCommandNum("newobj", &id) == true ){
2723+ if( (0 <= id)&&(id < TOTAL_PARAMETERINFO_SMALLOBJECT) ){
2724+ int dataid = ObjMgr.AddSmallObjectIndex(camera_x + cos(camera_rx)*20.0f, camera_y, camera_z + sin(camera_rx)*20.0f, camera_rx*-1, id, true);
2725+ if( dataid != -1 ){
2726+ sprintf(str, "Add SmallObject[%d].", dataid);
2727+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2728+ }
2729+ }
2730+ }
2731+
2732+ //プレイヤー操作をAI化
2733+ if( strcmp(NewCommand, "bot") == 0 ){
2734+ if( PlayerAI == false ){
2735+ PlayerAI = true;
2736+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Player is AI control. (bot)");
2737+ }
2738+ else{
2739+ PlayerAI = false;
2740+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Player is User control.");
2741+ }
2742+ }
2743+
2744+ //AIを非戦闘化させる
2745+ if( strcmp(NewCommand, "nofight") == 0 ){
2746+ if( AINoFight == false ){
2747+ AINoFight = true;
2748+ for(int i=0; i<MAX_HUMAN; i++){
2749+ HumanAI[i].SetNoFightFlag(true);
2750+ }
2751+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "AI had no Fight.");
2752+ }
2753+ else{
2754+ AINoFight = false;
2755+ for(int i=0; i<MAX_HUMAN; i++){
2756+ HumanAI[i].SetNoFightFlag(false);
2757+ }
2758+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "AI had Fight.");
2759+ }
2760+ }
2761+
2762+ //AIを警戒させる
2763+ if( strcmp(NewCommand, "caution") == 0 ){
2764+ for(int i=0; i<MAX_HUMAN; i++){
2765+ HumanAI[i].SetCautionMode();
2766+ }
2767+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Set cautious AI.");
2768+ }
2769+
2770+ //AIの処理を停止
2771+ if( strcmp(NewCommand, "stop") == 0 ){
2772+ if( AIstop == false ){
2773+ AIstop = true;
2774+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Stopped AI control.");
2775+ }
2776+ else{
2777+ AIstop = false;
2778+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Started AI control.");
2779+ }
2780+ }
2781+
2782+ /*
2783+ //ミッション達成
2784+ if( strcmp(NewCommand, "comp") == 0 ){
2785+ end_framecnt += 1;
2786+ MainGameInfo.missioncomplete = true;
2787+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Mission complete.");
2788+ }
2789+
2790+ //ミッション失敗
2791+ if( strcmp(NewCommand, "fail") == 0 ){
2792+ end_framecnt += 1;
2793+ MainGameInfo.missioncomplete = false;
2794+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "Mission fail.");
2795+ }
2796+ */
2797+
2798+ //バージョン情報取得
2799+ if( strcmp(NewCommand, "ver") == 0 ){
2800+ sprintf(str, "%s Version:%s", GAMENAME, GAMEVERSION);
2801+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2802+ }
2803+
2804+ //スクリーンショットを撮影
2805+ // ※コンソール画面を削除するため、撮影を1フレーム遅らせる。
2806+ if( ScreenShot == true ){
2807+ char fname[256];
2808+
2809+ //ファイル名を決定
2810+ GetTimeName(fname);
2811+ strcat(fname, ".bmp");
2812+
2813+ //撮影・保存
2814+ if( d3dg->SaveScreenShot(fname) == true ){
2815+ sprintf(str, "Saved Screenshot (File:%s)", fname);
2816+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), str);
2817+ }
2818+ else{
2819+ AddInfoConsole(d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), "[Error] Save failed.");
2820+ }
2821+ }
2822+ if( strcmp(NewCommand, "ss") == 0 ){
2823+ ScreenShot = true;
2824+ }
2825+ else{
2826+ ScreenShot = false;
2827+ }
2828+
2829+ //コンソールをクリア
2830+ if( strcmp(NewCommand, "clear") == 0 ){
2831+ for(int i=0; i<MAX_CONSOLELINES; i++){
2832+ InfoConsoleData[i].color = d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f);
2833+ InfoConsoleData[i].textdata[0] = NULL;
2834+ }
2835+ }
2836+}
2837+
2838+//! @brief デバック用コンソールの描画処理
2839+void maingame::RenderConsole()
2840+{
2841+ //下地
2842+ d3dg->Draw2DBox(0, 0, SCREEN_WIDTH, (MAX_CONSOLELINES+1)*18 + 5 + 5, d3dg->GetColorCode(0.0f,0.0f,0.0f,0.75f));
2843+
2844+ //表示中の文字
2845+ for(int i=0; i<MAX_CONSOLELINES; i++){
2846+ if( InfoConsoleData[i].textdata[0] != NULL ){
2847+ d3dg->Draw2DTextureFontText(5+1, i*18+5+1, InfoConsoleData[i].textdata, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 14, 17);
2848+ d3dg->Draw2DTextureFontText(5, i*18+5, InfoConsoleData[i].textdata, InfoConsoleData[i].color, 14, 17);
2849+ }
2850+ }
2851+
2852+ //入力中の文字
2853+ int cnt;
2854+ for(cnt=0; cnt<MAX_CONSOLELINES; cnt++){
2855+ if( InfoConsoleData[cnt].textdata[0] == NULL ){ break; }
2856+ }
2857+ d3dg->Draw2DTextureFontText(5+1, cnt*18+5+1, InputConsoleData->textdata, d3dg->GetColorCode(0.0f,0.0f,0.0f,1.0f), 14, 17);
2858+ d3dg->Draw2DTextureFontText(5, cnt*18+5, InputConsoleData->textdata, InputConsoleData->color, 14, 17);
2859+}
2860+
2861+#endif
2862+
2863+void maingame::Destroy()
2864+{
2865+ //ブロックデータ解放
2866+ d3dg->CleanupMapdata();
2867+
2868+ //オブジェクトマネージャー解放
2869+ ObjMgr.Cleanup();
2870+
2871+ //背景空解放
2872+ Resource.CleanupSkyModelTexture();
2873+
2874+#ifdef ENABLE_DEBUGCONSOLE
2875+ //コンソール用データを解放
2876+ if( InfoConsoleData != NULL ){ delete [] InfoConsoleData; }
2877+ if( InputConsoleData != NULL ){ delete InputConsoleData; }
2878+#endif
2879+
2880+ GameState->NextState();
2881+}
2882+
2883+//! @brief コンストラクタ
2884+result::result()
2885+{}
2886+
2887+//! @brief ディストラクタ
2888+result::~result()
2889+{}
2890+
2891+//! @brief リザルト画面の2D描画部分
2892+void result::Render2D()
2893+{
2894+ char mname[64];
2895+ char str[32];
2896+ float effectA = GetEffectAlphaLoop(framecnt, 1.0f, 0.8f, true);
2897+ float rate;
2898+ if( GameInfoData.fire == 0 ){
2899+ rate = 0.0f;
2900+ }
2901+ else{
2902+ rate = (float)GameInfoData.ontarget / GameInfoData.fire * 100;
2903+ }
2904+
2905+ //メモ:背景画像の描画は、自動的に行われる。
2906+
2907+ //固定文字描画
2908+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 50*3, 40, "RESULT", d3dg->GetColorCode(1.0f,0.0f,1.0f,effectA), 50, 42);
2909+
2910+ //ミッション名を取得し描画
2911+ if( MIFdata.GetFiletype() == false ){
2912+ GameParamInfo.GetOfficialMission(GameInfoData.selectmission_id, NULL, mname, NULL, NULL);
2913+ }
2914+ else{
2915+ strcpy(mname, MIFdata.GetMissionFullname());
2916+ }
2917+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - strlen(mname)*18/2, 100, mname, d3dg->GetColorCode(0.5f,0.5f,1.0f,1.0f), 18, 25);
2918+
2919+ //ミッションクリアーの有無
2920+ if( GameInfoData.missioncomplete == true ){
2921+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 216, 150, "mission successful", d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f), 24, 32);
2922+ }
2923+ else{
2924+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2 - 180, 150, "mission failure", d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f), 24, 32);
2925+ }
2926+
2927+ //結果表示
2928+ sprintf(str, "Time %dmin %dsec", GameInfoData.framecnt/(int)GAMEFPS/60, GameInfoData.framecnt/(int)GAMEFPS%60);
2929+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 210, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
2930+ sprintf(str, "Rounds fired %d", GameInfoData.fire);
2931+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 260, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
2932+ sprintf(str, "Rounds on target %d", GameInfoData.ontarget);
2933+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 310, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
2934+ sprintf(str, "Accuracy rate %.1f%%", rate);
2935+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 360, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
2936+ sprintf(str, "Kill %d / HeadShot %d", GameInfoData.kill, GameInfoData.headshot);
2937+ d3dg->Draw2DTextureFontText(SCREEN_WIDTH/2-strlen(str)*20/2, 410, str, d3dg->GetColorCode(1.0f,1.0f,1.0f,1.0f), 20, 32);
2938+}
2939+
2940+//! @brief screen派生クラスの初期化(クラスの設定)
2941+void InitScreen(opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result)
2942+{
2943+ Opening->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound);
2944+ MainMenu->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound);
2945+ Briefing->SetClass(&GameState, &d3dg, &inputCtrl);
2946+ MainGame->SetClass(&GameState, &d3dg, &inputCtrl, &GameSound);
2947+ Result->SetClass(&GameState, &d3dg, &inputCtrl);
2948+}
2949+
2950+//! @brief screen派生クラスの実行
2951+void ProcessScreen(HWND hWnd, opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result, unsigned int framecnt)
2952+{
2953+ int error;
2954+
2955+ switch(GameState.GetState()){
2956+ //オープニング初期化
2957+ case STATE_CREATE_OPENING:
2958+ error = Opening->Create();
2959+ if( error == 1 ){
2960+ MessageBox(hWnd, "block data open failed", "error", MB_OK);
2961+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
2962+ }
2963+ if( error == 2 ){
2964+ MessageBox(hWnd, "point data open failed", "error", MB_OK);
2965+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
2966+ }
2967+ break;
2968+
2969+ //オープニング実行
2970+ case STATE_NOW_OPENING:
2971+ Opening->Input();
2972+ Opening->Process();
2973+ Opening->Sound();
2974+ if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){
2975+ if( Opening->RenderMain() == true ){
2976+ ResetGame(hWnd);
2977+ }
2978+ }
2979+ break;
2980+
2981+ //オープニング廃棄
2982+ case STATE_DESTROY_OPENING:
2983+ Opening->Destroy();
2984+ break;
2985+
2986+ //メニュー初期化
2987+ case STATE_CREATE_MENU:
2988+ error = MainMenu->Create();
2989+ if( error == 1 ){
2990+ MessageBox(hWnd, "block data open failed", "error", MB_OK);
2991+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
2992+ }
2993+ if( error == 2 ){
2994+ MessageBox(hWnd, "point data open failed", "error", MB_OK);
2995+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
2996+ }
2997+ break;
2998+
2999+ //メニュー実行
3000+ case STATE_NOW_MENU:
3001+ MainMenu->Input();
3002+ MainMenu->Process();
3003+ MainMenu->Sound();
3004+ if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){
3005+ if( MainMenu->RenderMain() == true ){
3006+ ResetGame(hWnd);
3007+ }
3008+ }
3009+ break;
3010+
3011+ //メニュー廃棄
3012+ case STATE_DESTROY_MENU:
3013+ MainMenu->Destroy();
3014+ break;
3015+
3016+ //ブリーフィング初期化
3017+ case STATE_CREATE_BRIEFING:
3018+ error = Briefing->Create();
3019+ if( error == 1 ){
3020+ MessageBox(hWnd, "briefing data open failed", "error", MB_OK);
3021+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
3022+ }
3023+ break;
3024+
3025+ //ブリーフィング実行
3026+ case STATE_NOW_BRIEFING:
3027+ Briefing->Input();
3028+ Briefing->Process();
3029+ if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){
3030+ if( Briefing->RenderMain() == true ){
3031+ ResetGame(hWnd);
3032+ }
3033+ }
3034+ break;
3035+
3036+ //ブリーフィング廃棄
3037+ case STATE_DESTROY_BRIEFING:
3038+ Briefing->Destroy();
3039+ break;
3040+
3041+ //メインゲーム初期化
3042+ case STATE_CREATE_MAINGAME:
3043+ error = MainGame->Create();
3044+ if( error == 1 ){
3045+ MessageBox(hWnd, "block data open failed", "error", MB_OK);
3046+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
3047+ }
3048+ if( error == 2 ){
3049+ MessageBox(hWnd, "point data open failed", "error", MB_OK);
3050+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
3051+ }
3052+ break;
3053+
3054+ //メインゲーム実行
3055+ case STATE_NOW_MAINGAME:
3056+ MainGame->Input();
3057+ MainGame->Process();
3058+ MainGame->Sound();
3059+ if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){
3060+ if( MainGame->RenderMain() == true ){
3061+ ResetGame(hWnd);
3062+ }
3063+ }
3064+ break;
3065+
3066+ //メインゲーム廃棄
3067+ case STATE_DESTROY_MAINGAME:
3068+ MainGame->Destroy();
3069+ break;
3070+
3071+ //リザルト初期化
3072+ case STATE_CREATE_RESULT:
3073+ error = Result->Create();
3074+ break;
3075+
3076+ //リザルト実行
3077+ case STATE_NOW_RESULT:
3078+ Result->Input();
3079+ Result->Process();
3080+ if( (GameConfig.GetFrameskipFlag() == false)||(framecnt%2 == 0) ){
3081+ if( Result->RenderMain() == true ){
3082+ ResetGame(hWnd);
3083+ }
3084+ }
3085+ break;
3086+
3087+ //リザルト廃棄
3088+ case STATE_DESTROY_RESULT:
3089+ Result->Destroy();
3090+ break;
3091+
3092+ //ゲーム終了
3093+ case STATE_EXIT:
3094+ PostMessage(hWnd, WM_CLOSE, 0L, 0L);
3095+ break;
3096+
3097+ default:
3098+ break;
3099+ }
3100+}
\ No newline at end of file
--- tags/v1.010-20150220/collision.cpp (nonexistent)
+++ tags/v1.010-20150220/collision.cpp (revision 45)
@@ -0,0 +1,1163 @@
1+//! @file collision.cpp
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+#include "collision.h"
33+
34+//! @brief コンストラクタ
35+Collision::Collision()
36+{
37+ blockdata = NULL;
38+ bmin_x = new float[MAX_BLOCKS];
39+ bmin_y = new float[MAX_BLOCKS];
40+ bmin_z = new float[MAX_BLOCKS];
41+ bmax_x = new float[MAX_BLOCKS];
42+ bmax_y = new float[MAX_BLOCKS];
43+ bmax_z = new float[MAX_BLOCKS];
44+ BoardBlock = new bool[MAX_BLOCKS];
45+ bdata_worldgroup = new int[MAX_BLOCKS];
46+ for(int i=0; i<MAX_BLOCKS; i++){
47+ bmin_x[i] = 0.0f;
48+ bmin_y[i] = 0.0f;
49+ bmin_z[i] = 0.0f;
50+ bmax_x[i] = 0.0f;
51+ bmax_y[i] = 0.0f;
52+ bmax_z[i] = 0.0f;
53+ BoardBlock[i] = false;
54+ bdata_worldgroup[i] = 0;
55+ }
56+}
57+
58+//! @brief ディストラクタ
59+Collision::~Collision()
60+{
61+ if( bmin_x != NULL ){ delete [] bmin_x; }
62+ if( bmin_y != NULL ){ delete [] bmin_y; }
63+ if( bmin_z != NULL ){ delete [] bmin_z; }
64+ if( bmax_x != NULL ){ delete [] bmax_x; }
65+ if( bmax_y != NULL ){ delete [] bmax_y; }
66+ if( bmax_z != NULL ){ delete [] bmax_z; }
67+ if( BoardBlock != NULL ){ delete [] BoardBlock; }
68+ if( bdata_worldgroup != NULL ){ delete [] bdata_worldgroup; }
69+}
70+
71+//! @brief ブロックデータを取り込む
72+//! @param in_blockdata ブロックデータ
73+int Collision::InitCollision(BlockDataInterface* in_blockdata)
74+{
75+ int bs;
76+ struct blockdata data;
77+ int vID[4];
78+ float g0, g1, costheta;
79+ D3DXVECTOR3 dv1, dv2, dv3;
80+
81+ if( in_blockdata == NULL ){ return 1; }
82+ blockdata = in_blockdata;
83+
84+ bs = blockdata->GetTotaldatas();
85+
86+ for(int i=0; i<bs; i++){
87+ BoardBlock[i] = false;
88+ }
89+
90+ //判定用平面作成
91+ for(int i=0; i<bs; i++){
92+ blockdata->Getdata(&data, i);
93+ for(int j=0; j<6; j++){
94+ blockdataface(j, &vID[0], NULL);
95+
96+ dv1 = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] );
97+ dv2 = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] );
98+ dv3 = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] );
99+ D3DXPlaneFromPoints(&bdata_plane[i][j][0], &dv1, &dv2, &dv3);
100+ dv1 = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] );
101+ dv2 = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] );
102+ dv3 = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] );
103+ D3DXPlaneFromPoints(&bdata_plane[i][j][1], &dv1, &dv2, &dv3);
104+
105+ //2つの三角形が持つ法線のなす角を求める
106+ g0 = sqrt(bdata_plane[i][j][0].a * bdata_plane[i][j][0].a + bdata_plane[i][j][0].b * bdata_plane[i][j][0].b + bdata_plane[i][j][0].c * bdata_plane[i][j][0].c);
107+ g1 = sqrt(bdata_plane[i][j][1].a * bdata_plane[i][j][1].a + bdata_plane[i][j][1].b * bdata_plane[i][j][1].b + bdata_plane[i][j][1].c * bdata_plane[i][j][1].c);
108+ costheta = (bdata_plane[i][j][0].a * bdata_plane[i][j][1].a + bdata_plane[i][j][0].b * bdata_plane[i][j][1].b + bdata_plane[i][j][0].c * bdata_plane[i][j][1].c) / (g0 * g1);
109+
110+ //1つの面で法線が90度以上違う(=異常)なら〜
111+ if( acos(costheta) > (float)M_PI/2 ){
112+ //違う三角形で作る
113+ dv1 = D3DXVECTOR3( data.x[ vID[2] ], data.y[ vID[2] ], data.z[ vID[2] ] );
114+ dv2 = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] );
115+ dv3 = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] );
116+ D3DXPlaneFromPoints(&bdata_plane[i][j][0], &dv1, &dv2, &dv3);
117+ dv1 = D3DXVECTOR3( data.x[ vID[1] ], data.y[ vID[1] ], data.z[ vID[1] ] );
118+ dv2 = D3DXVECTOR3( data.x[ vID[3] ], data.y[ vID[3] ], data.z[ vID[3] ] );
119+ dv3 = D3DXVECTOR3( data.x[ vID[0] ], data.y[ vID[0] ], data.z[ vID[0] ] );
120+ D3DXPlaneFromPoints(&bdata_plane[i][j][1], &dv1, &dv2, &dv3);
121+ }
122+ }
123+ }
124+
125+ //板状のブロックを検出
126+ for(int i=0; i<bs; i++){
127+ blockdata->Getdata(&data, i);
128+
129+ BoardBlock[i] = false;
130+
131+ for(int j=0; j<8; j++){
132+ for(int k=j+1; k<8; k++){
133+ //一ヵ所でも頂点が同じなら、板状になっていると判定。
134+ if( (data.x[j] == data.x[k])&&(data.y[j] == data.y[k])&&(data.z[j] == data.z[k]) ){
135+ BoardBlock[i] = true;
136+ }
137+ }
138+ }
139+ }
140+
141+
142+ //ブロックAABB作成
143+ for(int i=0; i<bs; i++){
144+ blockdata->Getdata(&data, i);
145+ GetBlockPosMINMAX(data, &bmin_x[i], &bmin_y[i], &bmin_z[i], &bmax_x[i], &bmax_y[i], &bmax_z[i]);
146+ }
147+
148+ //ブロックの空間分割グループを計算
149+ for(int i=0; i<bs; i++){
150+ ///*
151+ blockdata->Getdata(&data, i);
152+
153+ bdata_worldgroup[i] = GetWorldGroup(bmin_x[i], bmin_z[i]);
154+ if( GetWorldGroup(bmax_x[i], bmax_z[i]) != bdata_worldgroup[i] ){
155+ bdata_worldgroup[i] = 0;
156+ }
157+ //*/
158+ //bdata_worldgroup[i] = 0;
159+ }
160+
161+ return 0;
162+}
163+
164+//! @brief ブロックの座標最大値・最小値を返す
165+//! @param data ブロックデータの構造体
166+//! @param *min_x 最小 X座標を返すポインタ
167+//! @param *min_y 最小 Y座標を返すポインタ
168+//! @param *min_z 最小 Z座標を返すポインタ
169+//! @param *max_x 最大 X座標を返すポインタ
170+//! @param *max_y 最大 Y座標を返すポインタ
171+//! @param *max_z 最大 Z座標を返すポインタ
172+void Collision::GetBlockPosMINMAX(struct blockdata data, float *min_x, float *min_y, float *min_z, float *max_x, float *max_y, float *max_z)
173+{
174+ *min_x = data.x[0];
175+ *min_y = data.y[0];
176+ *min_z = data.z[0];
177+ *max_x = data.x[0];
178+ *max_y = data.y[0];
179+ *max_z = data.z[0];
180+ for(int i=1; i<8; i++){
181+ if( *min_x > data.x[i] ){ *min_x = data.x[i]; }
182+ if( *min_y > data.y[i] ){ *min_y = data.y[i]; }
183+ if( *min_z > data.z[i] ){ *min_z = data.z[i]; }
184+
185+ if( *max_x < data.x[i] ){ *max_x = data.x[i]; }
186+ if( *max_y < data.y[i] ){ *max_y = data.y[i]; }
187+ if( *max_z < data.z[i] ){ *max_z = data.z[i]; }
188+ }
189+}
190+
191+//! @brief 空間分割のグループを算出
192+//! @param x X座標
193+//! @param z Z座標
194+//! @return グループ番号
195+//! @attention 「グループ番号」の概念は別途ドキュメントを参照
196+int Collision::GetWorldGroup(float x, float z)
197+{
198+ if( (x > 0)&&(z > 0) ){ return 1; }
199+ if( (x < 0)&&(z > 0) ){ return 2; }
200+ if( (x < 0)&&(z < 0) ){ return 3; }
201+ if( (x > 0)&&(z < 0) ){ return 4; }
202+ return 0;
203+}
204+
205+//! @brief ブロックに埋まっていないか調べる
206+//! @param blockid 判定するブロック番号
207+//! @param x X座標
208+//! @param y X座標
209+//! @param z X座標
210+//! @param worldgroup 空間のグループを利用して計算省略を試みる(true:有効・計算省略 false:無効・完全検索)
211+//! @param *planeid 表にある面番号(NULL可)
212+//! @return 埋っている:true 埋っていない:false
213+//! @warning *planeid が返す表面(0〜5)は、複数の面が該当する場合でも、最初に見つけた1面のみ返します。
214+bool Collision::CheckBlockInside(int blockid, float x, float y, float z, bool worldgroup, int *planeid)
215+{
216+ D3DXVECTOR3 dv;
217+
218+ if( blockdata == NULL ){ return false; }
219+ if( (blockid < 0)||(blockdata->GetTotaldatas() <= blockid) ){ return false; }
220+
221+ //板状のブロックは計算外
222+ if( BoardBlock[blockid] == true ){ return false; }
223+
224+
225+ //判定の荒削り
226+ if( worldgroup == true ){
227+
228+ //空間分割
229+ if( bdata_worldgroup[blockid] != 0 ){
230+ //観測点の空間のグループを取得
231+ int worldgroup = GetWorldGroup(x, z);
232+
233+ if( worldgroup != 0 ){
234+ //空間のグループが違えば計算外
235+ if( bdata_worldgroup[blockid] != worldgroup ){
236+ return false;
237+ }
238+ }
239+ }
240+
241+ //範囲で検索
242+ if( (x < bmin_x[blockid])||(bmax_x[blockid] < x) ){ return false; }
243+ if( (y < bmin_y[blockid])||(bmax_y[blockid] < y) ){ return false; }
244+ if( (z < bmin_z[blockid])||(bmax_z[blockid] < z) ){ return false; }
245+ }
246+
247+
248+ //6面から見て全て裏面かどうか
249+ for(int i=0; i<6; i++){
250+ dv = D3DXVECTOR3( x, y, z );
251+ if( (D3DXPlaneDotCoord(&bdata_plane[blockid][i][0], &dv) > 0)||(D3DXPlaneDotCoord(&bdata_plane[blockid][i][1], &dv) > 0) ){
252+ if( planeid != NULL ){ *planeid = i; }
253+ return false; //表面ならば終了
254+ }
255+ }
256+
257+ return true;
258+}
259+
260+//! @brief 全てのブロックに埋まっていないか調べる
261+//! @param x X座標
262+//! @param y X座標
263+//! @param z X座標
264+//! @return 埋っている:true 埋っていない:false
265+bool Collision::CheckALLBlockInside(float x, float y, float z)
266+{
267+ if( blockdata == NULL ){ return false; }
268+
269+ int bs = blockdata->GetTotaldatas();
270+
271+ for(int i=0; i<bs; i++){
272+ if( CheckBlockInside(i, x, y, z, true, NULL) == true ){ return true; }
273+ }
274+
275+ return false;
276+}
277+
278+//! @brief ブロックとレイ(光線)のあたり判定
279+//! @param blockid 判定するブロック番号
280+//! @param RayPos_x レイの位置(始点)を指定する X座標
281+//! @param RayPos_y レイの位置(始点)を指定する Y座標
282+//! @param RayPos_z レイの位置(始点)を指定する Z座標
283+//! @param RayDir_x レイのベクトルを指定する X成分
284+//! @param RayDir_y レイのベクトルを指定する Y成分
285+//! @param RayDir_z レイのベクトルを指定する Z成分
286+//! @param face 当たったブロックの面番号(0〜5)を受け取るポインタ (NULL可)
287+//! @param Dist 当たったブロックとの距離を受け取るポインタ
288+//! @param maxDist 判定を行う最大距離 (0.0 未満で無効・無限)
289+//! @return 当たっている:true 当たっていない:false
290+//! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
291+//! @warning 判定を行う最大距離を指定しないと、パフォーマンスが大幅に低下します。
292+//! @attention レイの始点から裏側になるブロックの面は無視されます。厚さをゼロに変形させた板状のブロックも無視します。
293+//! @attention また、レイが複数のブロックに当たる場合は、レイの始点から一番近い判定を返します。
294+bool Collision::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)
295+{
296+ if( blockdata == NULL ){ return false; }
297+
298+ struct blockdata data;
299+ int vID[4];
300+ float pDist;
301+ float min_pDist = FLT_MAX;
302+ int min_blockface = -1;
303+ float rmin_x = 0.0f;
304+ float rmin_y = 0.0f;
305+ float rmin_z = 0.0f;
306+ float rmax_x = 0.0f;
307+ float rmax_y = 0.0f;
308+ float rmax_z = 0.0f;
309+ int worldgroupA = 0;
310+ int worldgroupB = 0;
311+
312+ //板状のブロックは計算外
313+ if( BoardBlock[blockid] == true ){
314+ if( face != NULL ){ *face = 0; }
315+ *Dist = 0.0f;
316+ return false;
317+ }
318+
319+ if( maxDist > 0.0f ){
320+ //レイのAABBを作る
321+ rmin_x = RayPos_x + RayDir_x * maxDist;
322+ rmin_y = RayPos_y + RayDir_y * maxDist;
323+ rmin_z = RayPos_z + RayDir_z * maxDist;
324+ rmax_x = rmin_x;
325+ rmax_y = rmin_y;
326+ rmax_z = rmin_z;
327+ if( rmin_x > RayPos_x ){ rmin_x = RayPos_x; }
328+ if( rmin_y > RayPos_y ){ rmin_y = RayPos_y; }
329+ if( rmin_z > RayPos_z ){ rmin_z = RayPos_z; }
330+ if( rmax_x < RayPos_x ){ rmax_x = RayPos_x; }
331+ if( rmax_y < RayPos_y ){ rmax_y = RayPos_y; }
332+ if( rmax_z < RayPos_z ){ rmax_z = RayPos_z; }
333+ }
334+
335+ D3DXVECTOR3 pRayPos(RayPos_x, RayPos_y, RayPos_z);
336+ D3DXVECTOR3 pRayDir(RayDir_x, RayDir_y, RayDir_z);
337+
338+ if( maxDist > 0.0f ){
339+ //始点と終点の空間グループを取得
340+ worldgroupA = GetWorldGroup(RayPos_x, RayPos_z);
341+ worldgroupB = GetWorldGroup(RayPos_x + RayDir_x * maxDist, RayPos_z + RayDir_z * maxDist);
342+ }
343+
344+ blockdata->Getdata(&data, blockid);
345+
346+ if( maxDist > 0.0f ){
347+ if( bdata_worldgroup[blockid] != 0 ){
348+ //始点と終点が、空間のグループから出ていなければ
349+ if( (worldgroupA != 0)&&(worldgroupA == worldgroupB) ){
350+
351+ //空間のグループが違えば計算外
352+ if( bdata_worldgroup[blockid] == worldgroupA ){ //worldgroupA == worldgroupB
353+ //境界ボックス同士で判定
354+ if( CollideBoxAABB(bmin_x[blockid], bmin_y[blockid], bmin_z[blockid], bmax_x[blockid], bmax_y[blockid], bmax_z[blockid], rmin_x, rmin_y, rmin_z, rmax_x, rmax_y, rmax_z) == false ){
355+ //当たってなければ、このブロックは調べない。
356+ if( face != NULL ){ *face = 0; }
357+ *Dist = 0.0f;
358+ return false;
359+ }
360+ }
361+ }
362+ }
363+ }
364+
365+ //境界ボックスとレイで判定
366+ if( CollideAABBRay(bmin_x[blockid], bmin_y[blockid], bmin_z[blockid], bmax_x[blockid], bmax_y[blockid], bmax_z[blockid], RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, NULL, -1.0f) == false ){
367+ //当たってなければ、このブロックは調べない。
368+ if( face != NULL ){ *face = 0; }
369+ *Dist = 0.0f;
370+ return false;
371+ }
372+
373+ //各ポリゴン単位で判定
374+ for(int i=0; i<6; i++){
375+ blockdataface(i, vID, NULL);
376+ if( (D3DXPlaneDotCoord(&bdata_plane[blockid][i][0], &pRayPos) >= 0)||(D3DXPlaneDotCoord(&bdata_plane[blockid][i][1], &pRayPos) >= 0) ){
377+ D3DXVECTOR3 dv11, dv12, dv13;
378+ D3DXVECTOR3 dv21, dv22, dv23;
379+
380+ dv11 = D3DXVECTOR3( data.x[vID[0]], data.y[vID[0]], data.z[vID[0]]);
381+ dv12 = D3DXVECTOR3( data.x[vID[1]], data.y[vID[1]], data.z[vID[1]]);
382+ dv13 = D3DXVECTOR3( data.x[vID[2]], data.y[vID[2]], data.z[vID[2]]);
383+
384+ dv21 = D3DXVECTOR3( data.x[vID[2]], data.y[vID[2]], data.z[vID[2]]);
385+ dv22 = D3DXVECTOR3( data.x[vID[3]], data.y[vID[3]], data.z[vID[3]]);
386+ dv23 = D3DXVECTOR3( data.x[vID[0]], data.y[vID[0]], data.z[vID[0]]);
387+
388+ if( (D3DXIntersectTri(&dv11, &dv12, &dv13, &pRayPos, &pRayDir, NULL, NULL, &pDist) == TRUE)||
389+ (D3DXIntersectTri(&dv21, &dv22, &dv23, &pRayPos, &pRayDir, NULL, NULL, &pDist) == TRUE)
390+ ){
391+ if( min_pDist > pDist ){
392+ min_pDist = pDist;
393+ min_blockface = i;
394+ }
395+ }
396+ }
397+ }
398+
399+ //見つからなければ、ポインタに適当な数字を入れて返す。
400+ if( min_blockface == -1 ){
401+ if( face != NULL ){ *face = 0; }
402+ *Dist = 0.0f;
403+ return false;
404+ }
405+
406+ //計算結果を入れて返す
407+ if( face != NULL ){ *face = min_blockface; }
408+ *Dist = min_pDist;
409+ return true;
410+}
411+
412+//! @brief 全てのブロックとレイ(光線)のあたり判定
413+//! @param RayPos_x レイの位置(始点)を指定する X座標
414+//! @param RayPos_y レイの位置(始点)を指定する Y座標
415+//! @param RayPos_z レイの位置(始点)を指定する Z座標
416+//! @param RayDir_x レイのベクトルを指定する X成分
417+//! @param RayDir_y レイのベクトルを指定する Y成分
418+//! @param RayDir_z レイのベクトルを指定する Z成分
419+//! @param id 当たったブロックのIDを受け取るポインタ (NULL可)
420+//! @param face 当たったブロックの面番号(0〜5)を受け取るポインタ (NULL可)
421+//! @param Dist 当たったブロックとの距離を受け取るポインタ
422+//! @param maxDist 判定を行う最大距離 (0.0 未満で無効・無限)
423+//! @return 当たっている:true 当たっていない:false
424+//! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
425+//! @warning 判定を行う最大距離を指定しないと、パフォーマンスが大幅に低下します。
426+//! @warning 使い方は CheckALLBlockIntersectDummyRay()関数 と類似していますが、同関数より高精度で低速です。
427+//! @attention レイの始点から裏側になるブロックの面は無視されます。厚さをゼロに変形させた板状のブロックも無視します。
428+//! @attention また、レイが複数のブロックに当たる場合は、<b>レイの始点から一番近い判定</b>を返します。
429+bool Collision::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)
430+{
431+ if( blockdata == NULL ){ return false; }
432+
433+ int bs = blockdata->GetTotaldatas();
434+ struct blockdata data;
435+ int vID[4];
436+ float pDist;
437+ float min_pDist = FLT_MAX;
438+ int min_blockid = -1;
439+ int min_blockface = -1;
440+ float rmin_x = 0.0f;
441+ float rmin_y = 0.0f;
442+ float rmin_z = 0.0f;
443+ float rmax_x = 0.0f;
444+ float rmax_y = 0.0f;
445+ float rmax_z = 0.0f;
446+ int worldgroupA = 0;
447+ int worldgroupB = 0;
448+
449+ if( maxDist > 0.0f ){
450+ //レイのAABBを作る
451+ rmin_x = RayPos_x + RayDir_x * maxDist;
452+ rmin_y = RayPos_y + RayDir_y * maxDist;
453+ rmin_z = RayPos_z + RayDir_z * maxDist;
454+ rmax_x = rmin_x;
455+ rmax_y = rmin_y;
456+ rmax_z = rmin_z;
457+ if( rmin_x > RayPos_x ){ rmin_x = RayPos_x; }
458+ if( rmin_y > RayPos_y ){ rmin_y = RayPos_y; }
459+ if( rmin_z > RayPos_z ){ rmin_z = RayPos_z; }
460+ if( rmax_x < RayPos_x ){ rmax_x = RayPos_x; }
461+ if( rmax_y < RayPos_y ){ rmax_y = RayPos_y; }
462+ if( rmax_z < RayPos_z ){ rmax_z = RayPos_z; }
463+ }
464+
465+ D3DXVECTOR3 pRayPos(RayPos_x, RayPos_y, RayPos_z);
466+ D3DXVECTOR3 pRayDir(RayDir_x, RayDir_y, RayDir_z);
467+
468+ if( maxDist > 0.0f ){
469+ //始点と終点の空間グループを取得
470+ worldgroupA = GetWorldGroup(RayPos_x, RayPos_z);
471+ worldgroupB = GetWorldGroup(RayPos_x + RayDir_x * maxDist, RayPos_z + RayDir_z * maxDist);
472+ }
473+
474+ for(int i=0; i<bs; i++){
475+ //板状のブロックは計算外
476+ if( BoardBlock[i] == true ){ continue; }
477+
478+ blockdata->Getdata(&data, i);
479+
480+ if( maxDist > 0.0f ){
481+ if( bdata_worldgroup[i] != 0 ){
482+ //始点と終点が、空間のグループから出ていなければ
483+ if( (worldgroupA != 0)&&(worldgroupA == worldgroupB) ){
484+
485+ //空間のグループが違えば計算外
486+ if( bdata_worldgroup[i] == worldgroupA ){ //worldgroupA == worldgroupB
487+
488+ //境界ボックス同士で判定
489+ if( CollideBoxAABB(bmin_x[i], bmin_y[i], bmin_z[i], bmax_x[i], bmax_y[i], bmax_z[i], rmin_x, rmin_y, rmin_z, rmax_x, rmax_y, rmax_z) == false ){
490+ continue; //当たってなければ、このブロックは調べない。
491+ }
492+
493+ }
494+ }
495+ }
496+ }
497+
498+ //境界ボックスとレイで判定
499+ if( CollideAABBRay(bmin_x[i], bmin_y[i], bmin_z[i], bmax_x[i], bmax_y[i], bmax_z[i], RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, NULL, -1.0f) == false ){
500+ continue; //当たってなければ、このブロックは調べない。
501+ }
502+
503+ //各ポリゴン単位で判定
504+ for(int j=0; j<6; j++){
505+ blockdataface(j, vID, NULL);
506+ if( (D3DXPlaneDotCoord(&bdata_plane[i][j][0], &pRayPos) >= 0)||(D3DXPlaneDotCoord(&bdata_plane[i][j][1], &pRayPos) >= 0) ){
507+ D3DXVECTOR3 dv11, dv12, dv13;
508+ D3DXVECTOR3 dv21, dv22, dv23;
509+
510+ dv11 = D3DXVECTOR3( data.x[vID[0]], data.y[vID[0]], data.z[vID[0]]);
511+ dv12 = D3DXVECTOR3( data.x[vID[1]], data.y[vID[1]], data.z[vID[1]]);
512+ dv13 = D3DXVECTOR3( data.x[vID[2]], data.y[vID[2]], data.z[vID[2]]);
513+
514+ dv21 = D3DXVECTOR3( data.x[vID[2]], data.y[vID[2]], data.z[vID[2]]);
515+ dv22 = D3DXVECTOR3( data.x[vID[3]], data.y[vID[3]], data.z[vID[3]]);
516+ dv23 = D3DXVECTOR3( data.x[vID[0]], data.y[vID[0]], data.z[vID[0]]);
517+
518+ if( (D3DXIntersectTri(&dv11, &dv12, &dv13, &pRayPos, &pRayDir, NULL, NULL, &pDist) == TRUE)||
519+ (D3DXIntersectTri(&dv21, &dv22, &dv23, &pRayPos, &pRayDir, NULL, NULL, &pDist) == TRUE)
520+ ){
521+ if( min_pDist > pDist ){
522+ min_pDist = pDist;
523+ min_blockid = i;
524+ min_blockface = j;
525+ }
526+ }
527+ }
528+ }
529+ }
530+
531+ //見つけた距離が最大距離を超えていれば、判定を無効に。
532+ if( maxDist >= 0.0f ){
533+ if( min_pDist > maxDist ){
534+ min_blockid = -1;
535+ }
536+ }
537+
538+ //見つからなければ、ポインタに適当な数字を入れて返す。
539+ if( min_blockid == -1 ){
540+ if( id != NULL ){ *id = 0; }
541+ if( face != NULL ){ *face = 0; }
542+ *Dist = 0.0f;
543+ return false;
544+ }
545+
546+ //計算結果を入れて返す
547+ if( id != NULL ){ *id = min_blockid; }
548+ if( face != NULL ){ *face = min_blockface; }
549+ *Dist = min_pDist;
550+ return true;
551+}
552+
553+//! @brief 全てのブロックと衝突しているか判定
554+//! @param RayPos_x 始点 X座標
555+//! @param RayPos_y 始点 Y座標
556+//! @param RayPos_z 始点 Z座標
557+//! @param RayDir_x ベクトル X成分
558+//! @param RayDir_y ベクトル Y成分
559+//! @param RayDir_z ベクトル Z成分
560+//! @param id 当たったブロックのIDを受け取るポインタ (NULL可)
561+//! @param face 当たったブロックの面番号(0〜5)を受け取るポインタ (NULL可)
562+//! @param Dist ダミー変数のポインタ(常に 0.0f を返す)
563+//! @param maxDist 判定を行う最大距離 (0.0 未満指定 不可)
564+//! @return 当たっている:true 当たっていない:false
565+//! @warning 始点と ベクトルを間違えないこと。
566+//! @warning 使い方は CheckALLBlockIntersectRay()関数 と類似していますが、同関数より高速で低精度です。
567+//! @attention レイの始点から裏側になるブロックの面は無視されます。厚さをゼロに変形させた板状のブロックも無視します。
568+//! @attention また、レイが複数のブロックに当たる場合は、<b>一番最初に発見した判定</b>を返します。
569+bool Collision::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)
570+{
571+ if( blockdata == NULL ){ return false; }
572+ if( maxDist <= 0.0f ){ return false; }
573+
574+ float RayPos2_x = RayPos_x + RayDir_x * maxDist/2;
575+ float RayPos2_y = RayPos_y + RayDir_y * maxDist/2;
576+ float RayPos2_z = RayPos_z + RayDir_z * maxDist/2;
577+ float RayPos3_x = RayPos_x + RayDir_x * maxDist;
578+ float RayPos3_y = RayPos_y + RayDir_y * maxDist;
579+ float RayPos3_z = RayPos_z + RayDir_z * maxDist;
580+
581+ if( (id == NULL)&&(face == NULL) ){
582+ for(int i=0; i<MAX_BLOCKS; i++){
583+ //終了時点
584+ if( CheckBlockInside(i, RayPos3_x, RayPos3_y, RayPos3_z, true, NULL) == true ){
585+ *Dist = 0.0f;
586+ return true;
587+ }
588+
589+ //中間時点
590+ if( CheckBlockInside(i, RayPos2_x, RayPos2_y, RayPos2_z, true, NULL) == true ){
591+ *Dist = 0.0f;
592+ return true;
593+ }
594+ }
595+
596+ *Dist = 0.0f;
597+ return false;
598+ }
599+
600+ for(int i=0; i<MAX_BLOCKS; i++){
601+ int surface;
602+
603+ //開始地点
604+ CheckBlockInside(i, RayPos_x, RayPos_y, RayPos_z, false, &surface);
605+
606+ //終了時点
607+ if( CheckBlockInside(i, RayPos3_x, RayPos3_y, RayPos3_z, true, &surface) == true ){
608+ if( id != NULL ){ *id = i; }
609+ if( face != NULL ){ *face = surface; }
610+ *Dist = 0.0f;
611+ return true;
612+ }
613+
614+ //中間時点
615+ if( CheckBlockInside(i, RayPos2_x, RayPos2_y, RayPos2_z, true, &surface) == true ){
616+ if( id != NULL ){ *id = i; }
617+ if( face != NULL ){ *face = surface; }
618+ *Dist = 0.0f;
619+ return true;
620+ }
621+ }
622+
623+ if( id != NULL ){ *id = 0; }
624+ if( face != NULL ){ *face = 0; }
625+ *Dist = 0.0f;
626+ return false;
627+}
628+
629+//! @brief ブロックに沿って移動するベクトルを求める
630+void Collision::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)
631+{
632+ struct blockdata bdata;
633+ in_blockdata->Getdata(&bdata, id);
634+
635+ D3DXVECTOR3 out;
636+ D3DXVECTOR3 front(in_vx, in_vy, in_vz);
637+ D3DXVECTOR3 normal(bdata.material[face].vx, bdata.material[face].vy, bdata.material[face].vz);
638+
639+ //D3DXVec3Normalize(&out, &(front - D3DXVec3Dot(&front, &normal) * normal));
640+ out = (front - D3DXVec3Dot(&front, &normal) * normal);
641+
642+ *out_vx = out.x;
643+ *out_vy = out.y;
644+ *out_vz = out.z;
645+}
646+
647+//! @brief ブロックに反射するベクトルを求める
648+void Collision::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)
649+{
650+ struct blockdata bdata;
651+ in_blockdata->Getdata(&bdata, id);
652+
653+ D3DXVECTOR3 out;
654+ D3DXVECTOR3 front(in_vx, in_vy, in_vz);
655+ D3DXVECTOR3 normal(bdata.material[face].vx, bdata.material[face].vy, bdata.material[face].vz);
656+
657+ //D3DXVec3Normalize(&out, &(front - 2.0f * D3DXVec3Dot(&front, &normal) * normal));
658+ out = (front - 2.0f * D3DXVec3Dot(&front, &normal) * normal);
659+
660+ *out_vx = out.x;
661+ *out_vy = out.y;
662+ *out_vz = out.z;
663+}
664+
665+
666+//! @brief AABBによるあたり判定
667+//! @param box1_min_x 物体Aの最少 X座標
668+//! @param box1_min_y 物体Aの最少 Y座標
669+//! @param box1_min_z 物体Aの最少 Z座標
670+//! @param box1_max_x 物体Aの最大 X座標
671+//! @param box1_max_y 物体Aの最大 Y座標
672+//! @param box1_max_z 物体Aの最大 Z座標
673+//! @param box2_min_x 物体Bの最少 X座標
674+//! @param box2_min_y 物体Bの最少 Y座標
675+//! @param box2_min_z 物体Bの最少 Z座標
676+//! @param box2_max_x 物体Bの最大 X座標
677+//! @param box2_max_y 物体Bの最大 Y座標
678+//! @param box2_max_z 物体Bの最大 Z座標
679+//! @return 当たっている:true 当たっていない:false
680+//! @attention エラーがある場合「当たっていない:false」が返されます。
681+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)
682+{
683+ //エラー対策
684+ if( box1_min_x > box1_max_x ){ return false; }
685+ if( box1_min_y > box1_max_y ){ return false; }
686+ if( box1_min_z > box1_max_z ){ return false; }
687+ if( box2_min_x > box2_max_x ){ return false; }
688+ if( box2_min_y > box2_max_y ){ return false; }
689+ if( box2_min_z > box2_max_z ){ return false; }
690+
691+ if(
692+ (box1_min_x < box2_max_x)&&(box1_max_x > box2_min_x)&&
693+ (box1_min_y < box2_max_y)&&(box1_max_y > box2_min_y)&&
694+ (box1_min_z < box2_max_z)&&(box1_max_z > box2_min_z)
695+ ){
696+ return true;
697+ }
698+
699+ return false;
700+}
701+
702+//! @brief 円柱同士の当たり判定
703+//! @param c1_x 円柱1 底辺のx座標
704+//! @param c1_y 円柱1 底辺のy座標
705+//! @param c1_z 円柱1 底辺のz座標
706+//! @param c1_r 円柱1 の半径
707+//! @param c1_h 円柱1 の高さ
708+//! @param c2_x 円柱2 底辺のx座標
709+//! @param c2_y 円柱2 底辺のy座標
710+//! @param c2_z 円柱2 底辺のz座標
711+//! @param c2_r 円柱2 の半径
712+//! @param c2_h 円柱2 の高さ
713+//! @param *angle 円柱1からみた接触角度を受け取るポインタ(NULL可)
714+//! @param *length 円柱1からみた接触距離を受け取るポインタ(NULL可)
715+//! @return 当たっている:true 当たっていない:false
716+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)
717+{
718+ //先にお手軽な高さで判定
719+ if( (c1_y < c2_y + c2_h)&&(c1_y + c1_h > c2_y) ){
720+
721+ //距離で判定
722+ float x = c1_x - c2_x;
723+ float z = c1_z - c2_z;
724+ float caser = x*x + z*z;
725+ float minr = (c1_r+c2_r) * (c1_r+c2_r);
726+ if( caser < minr ){
727+ if( angle != NULL ){ *angle = atan2(z, x); }
728+ if( length != NULL ){ *length = sqrt(minr) - sqrt(caser); }
729+ return true;
730+ }
731+ }
732+
733+ return false;
734+}
735+
736+//! @brief 球体とレイ(光線)のあたり判定
737+//! @param s_x 球体のx座標
738+//! @param s_y 球体のy座標
739+//! @param s_z 球体のz座標
740+//! @param s_r 球体の半径
741+//! @param RayPos_x レイの位置(始点)を指定する X座標
742+//! @param RayPos_y レイの位置(始点)を指定する Y座標
743+//! @param RayPos_z レイの位置(始点)を指定する Z座標
744+//! @param RayDir_x レイのベクトルを指定する X成分
745+//! @param RayDir_y レイのベクトルを指定する Y成分
746+//! @param RayDir_z レイのベクトルを指定する Z成分
747+//! @param Dist 当たった球体との距離を受け取るポインタ
748+//! @param maxDist 判定を行う最大距離 (0.0 未満で無効・無限)
749+//! @return 当たっている:true 当たっていない:false
750+//! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
751+//! @warning 判定を行う最大距離を指定しないと、パフォーマンスが大幅に低下します。
752+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)
753+{
754+ if( maxDist > 0.0f ){
755+ float pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z;
756+
757+ //レイのAABBを作る
758+ pmin_x = RayPos_x + RayDir_x * maxDist;
759+ pmin_y = RayPos_y + RayDir_y * maxDist;
760+ pmin_z = RayPos_z + RayDir_z * maxDist;
761+ pmax_x = pmin_x;
762+ pmax_y = pmin_y;
763+ pmax_z = pmin_z;
764+ if( pmin_x > RayPos_x ){ pmin_x = RayPos_x; }
765+ if( pmin_y > RayPos_y ){ pmin_y = RayPos_y; }
766+ if( pmin_z > RayPos_z ){ pmin_z = RayPos_z; }
767+ if( pmax_x < RayPos_x ){ pmax_x = RayPos_x; }
768+ if( pmax_y < RayPos_y ){ pmax_y = RayPos_y; }
769+ if( pmax_z < RayPos_z ){ pmax_z = RayPos_z; }
770+
771+ //境界ボックス同士で判定
772+ if( CollideBoxAABB(s_x - s_r, s_y - s_r, s_z - s_r, s_x + s_r, s_y + s_r, s_z + s_r, pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z) == FALSE ){
773+ return false;
774+ }
775+ }
776+
777+ D3DXVECTOR3 pCenter(s_x, s_y, s_z);
778+ D3DXVECTOR3 pRayPos(RayPos_x, RayPos_y, RayPos_z);
779+ D3DXVECTOR3 pRayDir(RayDir_x, RayDir_y, RayDir_z);
780+
781+ //球体とレイの判定
782+ if( D3DXSphereBoundProbe(&pCenter, s_r, &pRayPos, &pRayDir) == TRUE ){
783+ if( Dist != NULL ){
784+ if( maxDist < 0.0f ){ maxDist = s_r * 2; }
785+
786+ //点とレイ始点の距離
787+ float x, y, z, d;
788+ x = s_x - RayPos_x;
789+ y = s_y - RayPos_y;
790+ z = s_z - RayPos_z;
791+ d = sqrt(x*x + y*y + z*z);
792+
793+ //レイ始点が半径より近い(=めり込んでいる)
794+ if( d < s_r ){
795+ *Dist = 0.0f;
796+ return true;
797+ }
798+
799+ //点(球体の中心)とレイの最短距離を求める
800+ float MinDist, RayDist, RDist;
801+ //点とレイの最短距離
802+ MinDist = DistancePosRay(s_x, s_y, s_z, RayPos_x, RayPos_y, RayPos_z, RayDir_x, RayDir_y, RayDir_z, maxDist);
803+ RayDist = sqrt(d*d - MinDist*MinDist); //(レイ始点から)点に最も近づく距離
804+ RDist = sqrt(s_r*s_r - MinDist*MinDist); //(点半径から)点に最も近づく距離
805+
806+ *Dist = RayDist - RDist; //レイ視点最短 - 半径最短 = レイ視点から半径までの最短
807+ }
808+ return true;
809+ }
810+
811+ return false;
812+}
813+
814+//! @brief AABBとレイ(光線)のあたり判定
815+//! @param box_min_x 物体の最少 X座標
816+//! @param box_min_y 物体の最少 Y座標
817+//! @param box_min_z 物体の最少 Z座標
818+//! @param box_max_x 物体の最大 X座標
819+//! @param box_max_y 物体の最大 Y座標
820+//! @param box_max_z 物体の最大 Z座標
821+//! @param RayPos_x レイの位置(始点)を指定する X座標
822+//! @param RayPos_y レイの位置(始点)を指定する Y座標
823+//! @param RayPos_z レイの位置(始点)を指定する Z座標
824+//! @param RayDir_x レイのベクトルを指定する X成分
825+//! @param RayDir_y レイのベクトルを指定する Y成分
826+//! @param RayDir_z レイのベクトルを指定する Z成分
827+//! @param Dist 当たったAABBとの距離を受け取るポインタ
828+//! @param maxDist 判定を行う最大距離 (0.0 未満で無効・無限)
829+//! @return 当たっている:true 当たっていない:false
830+//! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
831+//! @warning 判定を行う最大距離を指定しないと、パフォーマンスが大幅に低下します。
832+//! @todo 当たった距離として近似値を返すので、正確な値を求める。
833+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)
834+{
835+ if( box_min_x > box_max_x ){ return false; }
836+ if( box_min_y > box_max_y ){ return false; }
837+ if( box_min_z > box_max_z ){ return false; }
838+
839+ if( maxDist > 0.0f ){
840+ float pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z;
841+
842+ //レイのAABBを作る
843+ pmin_x = RayPos_x + RayDir_x * maxDist;
844+ pmin_y = RayPos_y + RayDir_y * maxDist;
845+ pmin_z = RayPos_z + RayDir_z * maxDist;
846+ pmax_x = pmin_x;
847+ pmax_y = pmin_y;
848+ pmax_z = pmin_z;
849+ if( pmin_x > RayPos_x ){ pmin_x = RayPos_x; }
850+ if( pmin_y > RayPos_y ){ pmin_y = RayPos_y; }
851+ if( pmin_z > RayPos_z ){ pmin_z = RayPos_z; }
852+ if( pmax_x < RayPos_x ){ pmax_x = RayPos_x; }
853+ if( pmax_y < RayPos_y ){ pmax_y = RayPos_y; }
854+ if( pmax_z < RayPos_z ){ pmax_z = RayPos_z; }
855+
856+ //境界ボックス同士で判定
857+ if( CollideBoxAABB(box_min_x, box_min_y, box_min_z, box_max_x, box_max_y, box_max_z, pmin_x, pmin_y, pmin_z, pmax_x, pmax_y, pmax_z) == FALSE ){
858+ return false;
859+ }
860+ }
861+
862+ D3DXVECTOR3 pMin(box_min_x, box_min_y, box_min_z);
863+ D3DXVECTOR3 pMax(box_max_x, box_max_y, box_max_z);
864+ D3DXVECTOR3 pRayPos(RayPos_x, RayPos_y, RayPos_z);
865+ D3DXVECTOR3 pRayDir(RayDir_x, RayDir_y, RayDir_z);
866+
867+ //AABBとレイ(光線)の判定
868+ if( D3DXBoxBoundProbe(&pMin, &pMax, &pRayPos, &pRayDir) == TRUE ){
869+ if( Dist != NULL ){
870+ float x, y, z;
871+ float d, mind;
872+
873+ //AABBの各頂点から距離を算出して、一番近い距離を「当たった距離」とする。
874+ //  ちゃんと計算しろよ ><
875+
876+ x = box_min_x - RayPos_x;
877+ y = box_min_y - RayPos_y;
878+ z = box_min_z - RayPos_z;
879+ d = sqrt(x*x + y*y + z*z);
880+ mind = d;
881+
882+ x = box_max_x - RayPos_x;
883+ y = box_min_y - RayPos_y;
884+ z = box_min_z - RayPos_z;
885+ d = sqrt(x*x + y*y + z*z);
886+ if( d < mind ){ mind = d; }
887+
888+ x = box_min_x - RayPos_x;
889+ y = box_max_y - RayPos_y;
890+ z = box_min_z - RayPos_z;
891+ d = sqrt(x*x + y*y + z*z);
892+ if( d < mind ){ mind = d; }
893+
894+ x = box_max_x - RayPos_x;
895+ y = box_max_y - RayPos_y;
896+ z = box_min_z - RayPos_z;
897+ d = sqrt(x*x + y*y + z*z);
898+ if( d < mind ){ mind = d; }
899+
900+ x = box_min_x - RayPos_x;
901+ y = box_min_y - RayPos_y;
902+ z = box_max_z - RayPos_z;
903+ d = sqrt(x*x + y*y + z*z);
904+ if( d < mind ){ mind = d; }
905+
906+ x = box_max_x - RayPos_x;
907+ y = box_min_y - RayPos_y;
908+ z = box_max_z - RayPos_z;
909+ d = sqrt(x*x + y*y + z*z);
910+ if( d < mind ){ mind = d; }
911+
912+ x = box_min_x - RayPos_x;
913+ y = box_max_y - RayPos_y;
914+ z = box_max_z - RayPos_z;
915+ d = sqrt(x*x + y*y + z*z);
916+ if( d < mind ){ mind = d; }
917+
918+ x = box_max_x - RayPos_x;
919+ y = box_max_y - RayPos_y;
920+ z = box_max_z - RayPos_z;
921+ d = sqrt(x*x + y*y + z*z);
922+ if( d < mind ){ mind = d; }
923+
924+ *Dist = mind;
925+ }
926+ return true;
927+ }
928+
929+ return false;
930+}
931+
932+//! @brief 点とレイの最短距離を求める
933+//! @param Pos_x 点のX座標
934+//! @param Pos_y 点のY座標
935+//! @param Pos_z 点のZ座標
936+//! @param RayPos_x レイの位置(始点)を指定する X座標
937+//! @param RayPos_y レイの位置(始点)を指定する Y座標
938+//! @param RayPos_z レイの位置(始点)を指定する Z座標
939+//! @param RayDir_x レイのベクトルを指定する X成分
940+//! @param RayDir_y レイのベクトルを指定する Y成分
941+//! @param RayDir_z レイのベクトルを指定する Z成分
942+//! @param maxDist 判定を行う最大距離
943+//! @return 最短距離
944+//! @warning RayPos(始点)と RayDir(ベクトル)を間違えないこと。
945+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)
946+{
947+ float x1, y1, z1;
948+ float x2, y2, z2;
949+ D3DXVECTOR3 in1, in2, out;
950+
951+ x1 = Pos_x - RayPos_x;
952+ y1 = Pos_y - RayPos_y;
953+ z1 = Pos_z - RayPos_z;
954+ x2 = RayDir_x * maxDist;
955+ y2 = RayDir_y * maxDist;
956+ z2 = RayDir_z * maxDist;
957+
958+ in1 = D3DXVECTOR3(x1, y1, z1);
959+ in2 = D3DXVECTOR3(x2, y2, z2);
960+
961+ D3DXVec3Cross(&out, &in1, &in2);
962+
963+ return sqrt(out.x*out.x + out.y*out.y + out.z*out.z) / maxDist;
964+}
965+
966+//! @brief 線分と線分の当たり判定(2D)
967+//! @param A1x 線分Aの始点 X座標
968+//! @param A1y 線分Aの始点 Y座標
969+//! @param A2x 線分Aの終点 X座標
970+//! @param A2y 線分Aの終点 Y座標
971+//! @param B1x 線分Bの始点 X座標
972+//! @param B1y 線分Bの始点 Y座標
973+//! @param B2x 線分Bの終点 X座標
974+//! @param B2y 線分Bの終点 Y座標
975+//! @param out_x 交点の X座標 を受け取るポインタ(NULL可)
976+//! @param out_y 交点の Y座標 を受け取るポインタ(NULL可)
977+//! @return 交差する:true 交差しない:false
978+bool Collide2DLine(int A1x, int A1y, int A2x, int A2y, int B1x, int B1y, int B2x, int B2y, int *out_x, int *out_y)
979+{
980+ //線分のベクトルを求める
981+ int Avx = A2x - A1x;
982+ int Avy = A2y - A1y;
983+ int Bvx = B2x - B1x;
984+ int Bvy = B2y - B1y;
985+
986+ float v1_v2 = (float)(Avx * Bvy - Avy * Bvx); //外積
987+ if( v1_v2 == 0.0f ){
988+ return false; //平行
989+ }
990+
991+ float vx = (float)(B1x - A1x);
992+ float vy = (float)(B1y - A1y);
993+ float v_v1 = vx * Avy - vy * Avx; //外積
994+ float v_v2 = vx * Bvy - vy * Bvx; //外積
995+ float t1 = v_v2 / v1_v2;
996+ float t2 = v_v1 / v1_v2;
997+
998+ if( (t1 <= 0)||(1 <= t1)||(t2 <= 0)||(1 <= t2) ){
999+ return false; //交差してない
1000+ }
1001+
1002+ if( out_x != NULL ){ *out_x = (int)(A1x + Avx * t1); }
1003+ if( out_y != NULL ){ *out_y = (int)(A1y + Avy * t1); }
1004+
1005+ return true;
1006+}
1007+
1008+//! @brief 四角形に収まる線分を求める(2D)
1009+//! @param line_x1 線分の始点 X座標
1010+//! @param line_y1 線分の始点 Y座標
1011+//! @param line_x2 線分の終点 X座標
1012+//! @param line_y2 線分の終点 Y座標
1013+//! @param box_x1 四角形の左上 X座標
1014+//! @param box_y1 四角形の左上 Y座標
1015+//! @param box_x2 四角形の右下 X座標
1016+//! @param box_y2 四角形の右下 Y座標
1017+//! @param out_line_x1 四角形に収まる 線分の始点 X座標 を受け取るポインタ
1018+//! @param out_line_y1 四角形に収まる 線分の始点 Y座標 を受け取るポインタ
1019+//! @param out_line_x2 四角形に収まる 線分の終点 X座標 を受け取るポインタ
1020+//! @param out_line_y2 四角形に収まる 線分の終点 Y座標 を受け取るポインタ
1021+//! @return 有効(描画する):true 無効(描画しない):false
1022+//! @warning 引数は必ず「box_x1 < box_x2」かつ「box_x1 < box_x2」にすること
1023+//! @note 簡易レーダーのマップ表示用
1024+bool Get2DLineInBox(int line_x1, int line_y1, int line_x2, int line_y2, int box_x1, int box_y1, int box_x2, int box_y2, int *out_line_x1, int *out_line_y1, int *out_line_x2, int *out_line_y2)
1025+{
1026+ //四角形指定が異常
1027+ if( (box_x1 >= box_x2)||(box_x1 >= box_x2) ){ return false; }
1028+
1029+ //上下左右の空間にあるなら、的外れ
1030+ if( (line_x1 < box_x1)&&(line_x2 < box_x1) ){ return false; }
1031+ if( (line_y1 < box_y1)&&(line_y2 < box_y1) ){ return false; }
1032+ if( (box_x2 < line_x1)&&(box_x2 < line_x2) ){ return false; }
1033+ if( (box_y2 < line_x1)&&(box_y2 < line_x2) ){ return false; }
1034+
1035+ //既に四角形に収まる
1036+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1037+ if( (box_x1 <= line_x2)&&(line_x2 <= box_x2)&&(box_y1 <= line_y2)&&(line_y2 <= box_y2) ){
1038+ *out_line_x1 = line_x1;
1039+ *out_line_y1 = line_y1;
1040+ *out_line_x2 = line_x2;
1041+ *out_line_y2 = line_y2;
1042+ return true;
1043+ }
1044+ }
1045+
1046+ int x, y;
1047+
1048+ //上辺
1049+ if( Collide2DLine(box_x1, box_y1, box_x2, box_y1, line_x1, line_y1, line_x2, line_y2, &x, &y) == true ){
1050+ //始点が四角形の内側なら終点を、違えば(=終点が内側)始点を書き換える。
1051+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1052+ line_x2 = x;
1053+ line_y2 = y;
1054+ }
1055+ else{
1056+ line_x1 = x;
1057+ line_y1 = y;
1058+ }
1059+ }
1060+ //右辺
1061+ if( Collide2DLine(box_x2, box_y1, box_x2, box_y2, line_x1, line_y1, line_x2, line_y2, &x, &y) == true ){
1062+ //始点が四角形の内側なら終点を、違えば(=終点が内側)始点を書き換える。
1063+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1064+ line_x2 = x;
1065+ line_y2 = y;
1066+ }
1067+ else{
1068+ line_x1 = x;
1069+ line_y1 = y;
1070+ }
1071+ }
1072+ //下辺
1073+ if( Collide2DLine(box_x2, box_y2, box_x1, box_y2, line_x1, line_y1, line_x2, line_y2, &x, &y) == true ){
1074+ //始点が四角形の内側なら終点を、違えば(=終点が内側)始点を書き換える。
1075+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1076+ line_x2 = x;
1077+ line_y2 = y;
1078+ }
1079+ else{
1080+ line_x1 = x;
1081+ line_y1 = y;
1082+ }
1083+ }
1084+ //左辺
1085+ if( Collide2DLine(box_x1, box_y2, box_x1, box_y1, line_x1, line_y1, line_x2, line_y2, &x, &y) == true ){
1086+ //始点が四角形の内側なら終点を、違えば(=終点が内側)始点を書き換える。
1087+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1088+ line_x2 = x;
1089+ line_y2 = y;
1090+ }
1091+ else{
1092+ line_x1 = x;
1093+ line_y1 = y;
1094+ }
1095+ }
1096+
1097+ //改めて四角形に収まるか確認
1098+ if( (box_x1 <= line_x1)&&(line_x1 <= box_x2)&&(box_y1 <= line_y1)&&(line_y1 <= box_y2) ){
1099+ if( (box_x1 <= line_x2)&&(line_x2 <= box_x2)&&(box_y1 <= line_y2)&&(line_y2 <= box_y2) ){
1100+ *out_line_x1 = line_x1;
1101+ *out_line_y1 = line_y1;
1102+ *out_line_x2 = line_x2;
1103+ *out_line_y2 = line_y2;
1104+ return true;
1105+ }
1106+ }
1107+
1108+ return false;
1109+}
1110+
1111+//! @brief 観測点から対象点への 距離判定・角度算出
1112+//! @param pos_x 観測点のX座標
1113+//! @param pos_y 観測点のY座標
1114+//! @param pos_z 観測点のZ座標
1115+//! @param rx 観測点の水平角度
1116+//! @param ry 観測点の垂直角度
1117+//! @param target_x 対象点のX座標
1118+//! @param target_y 対象点のY座標
1119+//! @param target_z 対象点のZ座標
1120+//! @param checkdist 判定距離(0.0f以下で判定無効)
1121+//! @param out_rx 対象点への水平角度(π〜-π)を受け取るポインタ(NULL可)
1122+//! @param out_ry 対象点への垂直角度を受け取るポインタ(NULL可)
1123+//! @param out_dist2 対象点への距離<b>の二乗</b>を受け取るポインタ(NULL可)
1124+//! @return 成功:true 失敗:false
1125+//! @warning out_dist2は距離の<b>二乗</b>です。必要に応じて改めて sqrt()関数 などを用いてください。
1126+//! @attention 引数 checkdist に有効な距離を与えた場合は、観測点から対象点への距離判定も行います。指定された距離より離れている場合、角度を計算せずに false を返します。
1127+//! @attention 逆に、引数 checkdist に0.0f以下を与えた場合、距離による判定を行いません。関数は常に true を返します。
1128+bool CheckTargetAngle(float pos_x, float pos_y, float pos_z, float rx, float ry, float target_x, float target_y, float target_z, float checkdist, float *out_rx, float *out_ry, float *out_dist2)
1129+{
1130+ float x, y, z;
1131+ float dist2 = 0.0f;
1132+ float angleX, angleY;
1133+
1134+ x = target_x - pos_x;
1135+ y = target_y - pos_y;
1136+ z = target_z - pos_z;
1137+
1138+ if( (checkdist > 0.0f)||(out_dist2 != NULL) ){
1139+ dist2 = (x*x + y*y + z*z);
1140+ }
1141+
1142+ if( checkdist > 0.0f ){
1143+ if( dist2 > checkdist * checkdist ){
1144+ return false;
1145+ }
1146+ }
1147+
1148+ if( out_rx != NULL ){
1149+ angleX = atan2(z, x) - rx;
1150+ for(; angleX > (float)M_PI; angleX -= (float)M_PI*2){}
1151+ for(; angleX < (float)M_PI*-1; angleX += (float)M_PI*2){}
1152+
1153+ *out_rx = angleX;
1154+ }
1155+ if( out_ry != NULL ){
1156+ angleY = atan2(y, sqrt(x*x + z*z)) - ry;
1157+
1158+ *out_ry = angleY;
1159+ }
1160+ if( out_dist2 != NULL ){ *out_dist2 = dist2; }
1161+
1162+ return true;
1163+}
\ No newline at end of file
--- tags/v1.010-20150220/gamemain.h (nonexistent)
+++ tags/v1.010-20150220/gamemain.h (revision 45)
@@ -0,0 +1,233 @@
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 ENABLE_DEBUGCONSOLE //!< @brief デバック用コンソールの有効化(コメント化で機能無効)
36+
37+#define MAINMENU_X 280 //!< メニューの表示 X座標(左上基準)
38+#define MAINMENU_Y 140 //!< メニューの表示 Y座標(〃)
39+#define TOTAL_MENUITEMS 8 //!< メニュー1画面に表示するミッション数
40+#define MAINMENU_H (TOTAL_MENUITEMS+2)*30 + 25 //!< メニューの表示サイズ・高さ
41+
42+#define HUDA_WEAPON_POSX (SCREEN_WIDTH - 255) //!< 武器情報を表示する領域・X座標
43+#define HUDA_WEAPON_POSY (SCREEN_HEIGHT - 98) //!< 武器情報を表示する領域・Y座標
44+#define HUDA_WEAPON_SIZEW 8 //!< 武器情報を表示する領域・横サイズ(32ピクセルの配置個数)
45+#define HUDA_WEAPON_SIZEH 3 //!< 武器情報を表示する領域・縦サイズ(32ピクセルの配置個数)
46+
47+#define VIEW_HEIGHT 19.0f //!< 視点の高さ
48+#define VIEWANGLE_NORMAL ((float)M_PI/180*65) //!< 視野角 標準
49+#define VIEWANGLE_SCOPE_1 ((float)M_PI/180*30) //!< 視野角 スコープ1
50+#define VIEWANGLE_SCOPE_2 ((float)M_PI/180*15) //!< 視野角 スコープ2
51+
52+#define TOTAL_EVENTLINE 3 //!< イベントのライン数
53+#define TOTAL_EVENTENTRYPOINT_0 -100 //!< ライン 0 の開始認識番号
54+#define TOTAL_EVENTENTRYPOINT_1 -110 //!< ライン 1 の開始認識番号
55+#define TOTAL_EVENTENTRYPOINT_2 -120 //!< ライン 2 の開始認識番号
56+
57+#define TOTAL_EVENTENT_SHOWMESSEC 5.0f //!< イベントメッセージを表示する秒数
58+
59+#ifdef ENABLE_DEBUGCONSOLE
60+ #define MAX_CONSOLELEN 45 //!< デバック用コンソールの文字数(行)
61+ #define MAX_CONSOLELINES 9 //!< デバック用コンソールの行数
62+ #define CONSOLE_PROMPT ">" //!< デバック用コンソールのプロンプト
63+#endif
64+
65+#ifndef H_LAYERLEVEL
66+ #define H_LAYERLEVEL 3 //!< Select include file.
67+#endif
68+#include "main.h"
69+
70+int InitGame(HWND hWnd);
71+
72+//! ゲームの状態を受け渡しする構造体
73+struct GameInfo{
74+ bool selectaddon; //!< addonを選択
75+ int selectmission_id; //!< 選択されたミッション
76+ bool missioncomplete; //!< ミッション完了
77+ unsigned int framecnt; //!< フレーム数
78+ int fire; //!< 射撃回数
79+ int ontarget; //!< 命中数
80+ int kill; //!< 倒した敵の数
81+ int headshot; //!< 敵の頭部に命中した数
82+};
83+
84+#ifdef ENABLE_DEBUGCONSOLE
85+//! コンソールを管理する構造体
86+struct ConsoleData{
87+ int color; //!< 色
88+ char textdata[MAX_CONSOLELEN]; //!< 文字列
89+};
90+#endif
91+
92+//! @brief オープニング画面管理クラス
93+//! @details オープニング画面を管理します。
94+class opening : public D3Dscene
95+{
96+ //int opening_banner; //!< オープニングで表示するテクスチャID
97+ void Render3D();
98+ void Render2D();
99+
100+public:
101+ opening();
102+ ~opening();
103+ int Create();
104+ void Process();
105+ void Destroy();
106+};
107+
108+//! @brief メニュー画面管理クラス
109+//! @details メニュー画面を管理します。
110+class mainmenu : public D3Dscene
111+{
112+ int mainmenu_mouseX; //!< メニュー画面マウスX座標
113+ int mainmenu_mouseY; //!< メニュー画面マウスY座標
114+ int mainmenu_scrollitems_official; //!< メニュー画面のスクロールしたアイテム数
115+ int mainmenu_scrollitems_addon; //!< メニュー画面のスクロールしたアイテム数
116+ float mainmenu_scrollbar_official_height; //!< メニュー画面のスクロールバーの高さ
117+ float mainmenu_scrollbar_official_scale; //!< メニュー画面のスクロールバーの目盛
118+ int mainmenu_scrollbar_official_y; //!< メニュー画面のスクロールバーのY座標
119+ float mainmenu_scrollbar_addon_height; //!< メニュー画面のスクロールバーの高さ
120+ float mainmenu_scrollbar_addon_scale; //!< メニュー画面のスクロールバーの目盛
121+ int mainmenu_scrollbar_addon_y; //!< メニュー画面のスクロールバーのY座標
122+ bool mainmenu_scrollbar_flag; //!< メニュー画面のスクロールバーを操作中を示すフラグ
123+ int gametitle; //!< ゲームタイトル画像
124+ void Render3D();
125+ void Render2D();
126+
127+public:
128+ mainmenu();
129+ ~mainmenu();
130+ int Create();
131+ void Input();
132+ void Process();
133+ void Destroy();
134+};
135+
136+//! @brief ブリーフィング画面管理クラス
137+//! @details ブリーフィング画面を管理します。
138+class briefing : public D2Dscene
139+{
140+ bool TwoTexture; //!< ブリーフィング画像を2枚使用
141+ int TextureA; //!< ブリーフィング画像A
142+ int TextureB; //!< ブリーフィング画像B
143+ void Render2D();
144+
145+public:
146+ briefing();
147+ ~briefing();
148+ int Create();
149+ void Destroy();
150+};
151+
152+//! @brief メインゲーム画面管理クラス
153+//! @details メインゲーム画面を管理します。
154+class maingame : public D3Dscene
155+{
156+ //class EventControl Event[TOTAL_EVENTLINE]; //!< イベント制御クラス
157+ float mouse_rx; //!< マウスによる水平軸角度
158+ float mouse_ry; //!< マウスによる垂直軸角度
159+ float view_rx; //!< マウス角度とカメラ角度の差(水平軸)
160+ float view_ry; //!< マウス角度とカメラ角度の差(垂直軸)
161+ bool ShowInfo_Debugmode; //!< 座標などを表示するデバックモード
162+ bool Camera_Debugmode; //!< カメラデバックモード
163+ bool tag; //!< オブジェクトのタグを表示
164+ bool radar; //!< 簡易レーダー表示
165+ bool wireframe; //!< マップをワイヤーフレーム表示
166+ bool CenterLine; //!< 3D空間に中心線を表示
167+ bool Camera_F1mode; //!< カメラF1モード
168+ int Camera_F2mode; //!< カメラF2モード
169+ bool Camera_HOMEmode; //!< カメラHOMEモード
170+ bool Cmd_F5; //!< 裏技F5モード
171+ int InvincibleID; //!< 無敵な人の判定
172+ bool PlayerAI; //!< プレイヤー操作をAIに委ねる
173+ bool AIstop; //!< AI処理を停止する
174+ bool AINoFight; //!< AIが非戦闘化する(戦わない)
175+ int start_framecnt; //!< メインゲーム開始時のカウント
176+ int end_framecnt; //!< メインゲーム終了のカウント
177+ int message_id; //!< 表示中のイベントメッセージ番号
178+ int message_cnt; //!< 表示中のイベントメッセージカウント
179+ bool redflash_flag; //!< レッドフラッシュ描画フラグ
180+ int time; //!< timer
181+ int time_input; //!< 入力取得の処理時間
182+ int time_process_object; //!< 基本オブジェクトの処理時間
183+ int time_process_ai; //!< AIの処理時間
184+ int time_process_event; //!< イベントの処理時間
185+ int time_sound; //!< サウンドの処理時間
186+ int time_render; //!< 描画の処理時間
187+ GameInfo MainGameInfo; //!< リザルト用管理クラス
188+ bool CheckInputControl(int CheckKey, int mode);
189+ void Render3D();
190+ void Render2D();
191+ bool GetRadarPos(float in_x, float in_y, float in_z, int RadarPosX, int RadarPosY, int RadarSize, float RadarWorldR, int *out_x, int *out_y, float *local_y, bool check);
192+ void RenderRadar();
193+
194+#ifdef ENABLE_DEBUGCONSOLE
195+ bool Show_Console; //!< デバック用コンソールを表示
196+ ConsoleData *InfoConsoleData; //!< デバック用コンソールデータ(表示済み)
197+ ConsoleData *InputConsoleData; //!< デバック用コンソールデータ(入力中)
198+ char NewCommand[MAX_CONSOLELEN]; //!< 新たに入力された未処理のコマンド
199+ bool ScreenShot; //!< SSを撮影する
200+ void AddInfoConsole(int color, char *str);
201+ void ConsoleInputText(char inchar);
202+ void ConsoleDeleteText();
203+ bool GetCommandNum(char *cmd, int *num);
204+ void InputConsole();
205+ void ProcessConsole();
206+ void RenderConsole();
207+#endif
208+
209+public:
210+ maingame();
211+ ~maingame();
212+ int Create();
213+ void Input();
214+ void Process();
215+ void Sound();
216+ void Destroy();
217+};
218+
219+//! @brief リザルト画面管理クラス
220+//! @details リザルト(結果表示)画面を管理します。
221+class result : public D2Dscene
222+{
223+ void Render2D();
224+
225+public:
226+ result();
227+ ~result();
228+};
229+
230+void InitScreen(opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result);
231+void ProcessScreen(HWND hWnd, opening *Opening, mainmenu *MainMenu, briefing *Briefing, maingame *MainGame, result *Result, unsigned int framecnt);
232+
233+#endif
\ No newline at end of file
--- tags/v1.010-20150220/event.h (nonexistent)
+++ tags/v1.010-20150220/event.h (revision 45)
@@ -0,0 +1,64 @@
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+ signed char GetNextP4();
61+ int Execution(int *endcnt, bool *complete, int *MessageID, bool *SetMessageID);
62+};
63+
64+#endif
\ No newline at end of file
--- tags/v1.010-20150220/collision.h (nonexistent)
+++ tags/v1.010-20150220/collision.h (revision 45)
@@ -0,0 +1,87 @@
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+bool Collide2DLine(int A1x, int A1y, int A2x, int A2y, int B1x, int B1y, int B2x, int B2y, int *out_x, int *out_y);
83+bool Get2DLineInBox(int line_x1, int line_y1, int line_x2, int line_y2, int box_x1, int box_y1, int box_x2, int box_y2, int *out_line_x1, int *out_line_y1, int *out_line_x2, int *out_line_y2);
84+
85+bool CheckTargetAngle(float pos_x, float pos_y, float pos_z, float rx, float ry, float target_x, float target_y, float target_z, float checkdist, float *out_rx, float *out_ry, float *out_dist2);
86+
87+#endif
\ No newline at end of file
--- tags/v1.010-20150220/event.cpp (nonexistent)
+++ tags/v1.010-20150220/event.cpp (revision 45)
@@ -0,0 +1,210 @@
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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
44+EventControl::~EventControl()
45+{}
46+
47+//! @brief 対象クラスを設定
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+//! @brief リセット
58+//! @param EntryP4 イベント処理を開始する認識番号 (-100、-110、-120 など)
59+void EventControl::Reset(signed char EntryP4)
60+{
61+ nextp4 = EntryP4;
62+ waitcnt = 0;
63+}
64+
65+//! @brief 次に処理する認識番号
66+//! @return P4:認識番号
67+signed char EventControl::GetNextP4()
68+{
69+ return nextp4;
70+}
71+
72+//! @brief 対象の人物がケースを持っているかチェック
73+//! @param in_human 調べる対象のhumanのポインタ
74+//! @return 持っている:true 持っていない:false
75+bool EventControl::CheckHaveCase(human *in_human)
76+{
77+ int selectweapon;
78+ weapon *out_weapon[TOTAL_HAVEWEAPON];
79+ int weaponid;
80+
81+ //所有する武器オブジェクトを全て取得
82+ in_human->GetWeapon(&selectweapon, out_weapon);
83+
84+ //全て調べる
85+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
86+ if( out_weapon[i] != NULL ){
87+
88+ //武器の種類番号を取得し、それがケースかどうか。
89+ out_weapon[i]->GetParamData(&weaponid, NULL, NULL);
90+ if( weaponid == ID_WEAPON_CASE ){
91+ return true;
92+ }
93+ }
94+ }
95+ return false;
96+}
97+
98+//! @brief 処理を実行
99+//! @param endcnt 終了カウントのポインタ
100+//! @param complete ミッション成功フラグのポインタ
101+//! @param MessageID イベントメッセージ番号のポインタ
102+//! @param SetMessageID イベントメッセージ読み出しフラグ
103+//! @return 実行したステップ数
104+//! @attention 渡された引数に変更がない場合、渡された引数のデータは操作されません。
105+//! @attention SetMessageID は、メッセージイベントが実行された場合に true になります。<b>前回から変更されたとは限りません。</b>
106+int EventControl::Execution(int *endcnt, bool *complete, int *MessageID, bool *SetMessageID)
107+{
108+ pointdata data, pathdata;
109+ int cnt = 0;
110+ human* thuman;
111+ smallobject* tsmallobject;
112+ float hx, hy, hz;
113+ float x, y, z;
114+ int pid;
115+
116+ for(int i=0; i<TOTAL_EVENTFRAMESTEP; i++){
117+ cnt = i;
118+
119+ //次のポイントを探す
120+ if( Point->SearchPointdata(&data, 0x08, 0, 0, 0, nextp4, 0) == 0 ){ return cnt; }
121+ if( (data.p1 < 10)||(19 < data.p1) ){ return cnt; }
122+
123+ switch(data.p1){
124+ case 10: //任務達成
125+ *endcnt += 1;
126+ *complete = true;
127+ return cnt;
128+
129+ case 11: //任務失敗
130+ *endcnt += 1;
131+ *complete = false;
132+ return cnt;
133+
134+ case 12: //死亡待ち
135+ thuman = ObjMgr->SearchHuman(data.p2);
136+ if( thuman == NULL ){ return cnt; }
137+ if( thuman->GetDeadFlag() == false ){ return cnt; }
138+ nextp4 = data.p3;
139+ break;
140+
141+ case 13: //到着待ち
142+ thuman = ObjMgr->SearchHuman(data.p2);
143+ if( thuman == NULL ){ return cnt; }
144+ thuman->GetPosData(&hx, &hy, &hz, NULL);
145+ x = hx - data.x;
146+ y = hy - data.y;
147+ z = hz - data.z;
148+ if( sqrt(x*x + y*y+ + z*z) > DISTANCE_CHECKPOINT ){ return cnt; }
149+ nextp4 = data.p3;
150+ break;
151+
152+ case 14: //歩きに変更
153+ if( Point->SearchPointdata(&pid, 0x08, 0, 0, 0, data.p2, 0) > 0 ){
154+ //対象がAIパスならば、強制的にパラメータを書き換える
155+ Point->Getdata(&pathdata, pid);
156+ if( (pathdata.p1 == 3)||(pathdata.p1 == 8) ){
157+ pathdata.p2 = 0;
158+ }
159+ Point->SetParam(pid, pathdata.p1, pathdata.p2, pathdata.p3, pathdata.p4);
160+ }
161+ nextp4 = data.p3;
162+ break;
163+
164+ case 15: //小物破壊待ち
165+ tsmallobject = ObjMgr->SearchSmallobject(data.p2);
166+ if( tsmallobject == NULL ){ return cnt; }
167+ if( tsmallobject->GetDrawFlag() == true ){ return cnt; }
168+ nextp4 = data.p3;
169+ break;
170+
171+ case 16: //ケース待ち
172+ thuman = ObjMgr->SearchHuman(data.p2);
173+ if( thuman == NULL ){ return cnt; }
174+ thuman->GetPosData(&hx, &hy, &hz, NULL);
175+ x = hx - data.x;
176+ y = hy - data.y;
177+ z = hz - data.z;
178+ if( sqrt(x*x + y*y+ + z*z) > DISTANCE_CHECKPOINT ){ return cnt; }
179+ if( CheckHaveCase(thuman) == false ){ return cnt; }
180+ nextp4 = data.p3;
181+ break;
182+
183+ case 17: //時間待ち
184+ if( (int)GAMEFPS * ((unsigned char)data.p2) > waitcnt ){
185+ waitcnt += 1;
186+ return cnt;
187+ }
188+ waitcnt = 0;
189+ nextp4 = data.p3;
190+ break;
191+
192+ case 18: //メッセージ
193+ if( (0 <= data.p2)&&(data.p2 < MAX_POINTMESSAGES) ){
194+ *MessageID = data.p2;
195+ }
196+ nextp4 = data.p3;
197+ //break;
198+ *SetMessageID = true;
199+ return cnt;
200+
201+ case 19: //チーム変更
202+ thuman = ObjMgr->SearchHuman(data.p2);
203+ if( thuman == NULL ){ return cnt; }
204+ thuman->SetTeamID(0);
205+ nextp4 = data.p3;
206+ break;
207+ }
208+ }
209+ return cnt;
210+}
\ No newline at end of file
--- tags/v1.010-20150220/object.cpp (nonexistent)
+++ tags/v1.010-20150220/object.cpp (revision 45)
@@ -0,0 +1,2596 @@
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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
51+object::~object()
52+{}
53+
54+//! @brief 設定値を管理するクラスを登録
55+//! @attention 各関数を使用する前に実行すること。
56+void object::SetParameterInfoClass(class ParameterInfo *in_Param)
57+{
58+ Param = in_Param;
59+}
60+
61+//! @brief 座標と角度を設定
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+//! @brief 座標と角度を取得
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+//! @brief 描画フラグを設定
88+//! @param flag 設定するフラグ
89+void object::SetDrawFlag(bool flag)
90+{
91+ RenderFlag = flag;
92+}
93+
94+//! @brief 描画フラグを取得
95+//! @return 現在設定されているフラグ
96+bool object::GetDrawFlag()
97+{
98+ return RenderFlag;
99+}
100+
101+//! @brief モデルデータを設定
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+//! @brief テクスチャを設定
111+//! @param id テクスチャ認識番号
112+void object::SetTexture(int id)
113+{
114+ id_texture = id;
115+}
116+
117+//! @brief 計算を実行(自由落下など)
118+int object::RunFrame()
119+{
120+ return 0;
121+}
122+
123+//! @brief 描画
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+//! @brief コンストラクタ
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+ legrotation_x = 0.0f;
157+ point_dataid = dataid;
158+ point_p4 = p4;
159+ teamid = team;
160+
161+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
162+ weapon[i] = NULL;
163+ }
164+ selectweapon = 1;
165+ //if( Param->GetHuman(id_param, &data) == 0 ){
166+ // hp = data.hp;
167+ //}
168+ //else{
169+ hp = 0;
170+ //}
171+#ifdef HUMAN_DEADBODY_COLLISION
172+ deadstate = 0;
173+#endif
174+ id_texture = -1;
175+ id_upmodel = -1;
176+ for(int i=0; i<TOTAL_ARMMODE; i++){
177+ id_armmodel[i] = -1;
178+ }
179+ id_legmodel = -1;
180+ for(int i=0; i<TOTAL_WALKMODE; i++){
181+ id_walkmodel[i] = -1;
182+ }
183+ for(int i=0; i<TOTAL_RUNMODE; i++){
184+ id_runmodel[i] = -1;
185+ }
186+
187+ move_rx = 0.0f;
188+ MoveFlag = 0x00;
189+ MoveFlag_lt = MoveFlag;
190+ scopemode = 0;
191+ HitFlag = false;
192+ walkcnt = 0;
193+ runcnt = 0;
194+ totalmove = 0.0f;
195+ StateGunsightErrorRange = 0;
196+ ReactionGunsightErrorRange = 0;
197+}
198+
199+//! @brief ディストラクタ
200+human::~human()
201+{}
202+
203+//! @brief 設定値を設定
204+//! @param id_param 人の種類番号
205+//! @param dataid ポイントのデータ番号
206+//! @param p4 第4パラメータ
207+//! @param team チーム番号
208+//! @param init オブジェクトを初期化
209+void human::SetParamData(int id_param, int dataid, signed char p4, int team, bool init)
210+{
211+ id_parameter = id_param;
212+ point_dataid = dataid;
213+ point_p4 = p4;
214+ teamid = team;
215+
216+ if( init == true ){
217+ HumanParameter data;
218+
219+ move_x = 0.0f;
220+ move_y = 0.0f;
221+ move_z = 0.0f;
222+ move_y_flag = false;
223+ rotation_y = 0.0f;
224+ armrotation_y = (float)M_PI/18 * -3;
225+ reaction_y = 0.0f;
226+ legrotation_x = 0.0f;
227+
228+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
229+ weapon[i] = NULL;
230+ }
231+ selectweapon = 1;
232+ if( Param->GetHuman(id_param, &data) == 0 ){
233+ hp = data.hp;
234+ }
235+ else{
236+ hp = 0;
237+ }
238+#ifdef HUMAN_DEADBODY_COLLISION
239+ deadstate = 0;
240+#endif
241+ MoveFlag = 0x00;
242+ MoveFlag_lt = MoveFlag;
243+ scopemode = 0;
244+ HitFlag = false;
245+ totalmove = 0.0f;
246+ Invincible = false;
247+ }
248+}
249+
250+//! @brief 設定値を取得
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+//! @brief HPを取得
264+//! @return HP
265+int human::GetHP()
266+{
267+ return hp;
268+}
269+
270+//! @brief HPを設定
271+//! @param in_hp 新たに設定するHP
272+//! @return 成功:true 失敗:false
273+//! @attention HPが1以上の人に対して実行しないと失敗します。
274+bool human::SetHP(int in_hp)
275+{
276+ if( hp > 0 ){
277+ hp = in_hp;
278+ return true;
279+ }
280+ return false;
281+}
282+
283+
284+//! @brief 死体かどうか判定
285+//! @return 死体:true 死体でない:false
286+//! @warning 完全に静止した状態を「死体」と判定します。倒れている最中の人は対象に含まれないため、hp <= 0 が全て死体と判定されるとは限りません。
287+bool human::GetDeadFlag()
288+{
289+#ifdef HUMAN_DEADBODY_COLLISION
290+ if( deadstate == 5 ){ return true; }
291+ return false;
292+#else
293+ if( hp <= 0 ){ return true; }
294+ return false;
295+#endif
296+}
297+
298+//! @brief チーム番号を設定(上書き)
299+//! @param id 新しいチーム番号
300+void human::SetTeamID(int id)
301+{
302+ teamid = id;
303+}
304+
305+//! @brief 無敵フラグを取得
306+//! @return true:無敵 false:通常
307+//! @attention 無敵状態の場合、銃弾・手榴弾の爆発・落下 によるダメージを一切受けません。
308+bool human::GetInvincibleFlag()
309+{
310+ return Invincible;
311+}
312+
313+//! @brief 無敵フラグを設定
314+//! @param flag true:無敵 false:通常
315+//! @attention 無敵状態の場合、銃弾・手榴弾の爆発・落下 によるダメージを一切受けません。
316+void human::SetInvincibleFlag(bool flag)
317+{
318+ Invincible = flag;
319+}
320+
321+//! @brief 前処理の移動量を取得
322+//! @param *x X軸移動量を取得するポインタ(NULL可)
323+//! @param *y Y軸移動量を取得するポインタ(NULL可)
324+//! @param *z Z軸移動量を取得するポインタ(NULL可)
325+void human::GetMovePos(float *x, float *y, float *z)
326+{
327+ if( x != NULL ){ *x = move_x; }
328+ if( y != NULL ){ *y = move_y; }
329+ if( z != NULL ){ *z = move_z; }
330+}
331+
332+//! @brief モデルデータを設定
333+//! @param upmodel 上半身のモデル
334+//! @param armmodel[] 腕のモデルの配列(配列数:TOTAL_ARMMODE)
335+//! @param legmodel 足(静止状態)のモデル
336+//! @param walkmodel[] 腕のモデルの配列(配列数:TOTAL_WALKMODE)
337+//! @param runmodel[] 腕のモデルの配列(配列数:TOTAL_RUNMODE)
338+void human::SetModel(int upmodel, int armmodel[], int legmodel, int walkmodel[], int runmodel[])
339+{
340+ id_upmodel = upmodel;
341+ for(int i=0; i<TOTAL_ARMMODE; i++){
342+ id_armmodel[i] = armmodel[i];
343+ }
344+ id_legmodel = legmodel;
345+ for(int i=0; i<TOTAL_WALKMODE; i++){
346+ id_walkmodel[i] = walkmodel[i];
347+ }
348+ for(int i=0; i<TOTAL_RUNMODE; i++){
349+ id_runmodel[i] = runmodel[i];
350+ }
351+}
352+
353+//! @brief 武器を設定
354+//! @param in_weapon[] 設定するweaponクラスのポインタ配列
355+//! @warning 通常は PickupWeapon()関数 を使用すること
356+void human::SetWeapon(class weapon *in_weapon[])
357+{
358+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
359+ if( in_weapon[i] == NULL ){
360+ weapon[i] = NULL;
361+ }
362+ else{
363+ //武器を正しく拾えれば、所持武器として登録
364+ if( in_weapon[i]->Pickup() == 0 ){
365+ weapon[i] = in_weapon[i];
366+ }
367+ }
368+ }
369+}
370+
371+//! @brief 武器を拾う
372+//! @param in_weapon[] 設定するweaponクラスのポインタ
373+//! @return 成功:1 失敗:0
374+//! @attention 人の種類が ゾンビ の場合、この関数は失敗します。
375+int human::PickupWeapon(class weapon *in_weapon)
376+{
377+ if( in_weapon == NULL ){
378+ return 0;
379+ }
380+
381+ //人の種類が ゾンビ ならば、失敗
382+ HumanParameter Paraminfo;
383+ Param->GetHuman(id_parameter, &Paraminfo);
384+ if( Paraminfo.type == 2 ){
385+ return 0;
386+ }
387+
388+ if( weapon[selectweapon] == NULL ){
389+ //武器を正しく拾えれば、所持武器として登録
390+ if( in_weapon->Pickup() == 0 ){
391+ weapon[selectweapon] = in_weapon;
392+
393+ //切り替え完了のカウント
394+ selectweaponcnt = 10;
395+
396+ return 1;
397+ }
398+ }
399+ return 0;
400+}
401+
402+//! @brief 武器を切り替える(持ち替える)
403+//! @param id 持ち替える武器 (-1 で次の武器)
404+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
405+void human::ChangeWeapon(int id)
406+{
407+ //体力がなければ失敗
408+ if( hp <= 0 ){ return; }
409+
410+ //リロード中なら失敗
411+ if( weapon[selectweapon] != NULL ){
412+ if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return; }
413+ }
414+
415+ //同じ武器に切り替えようとしているなら、失敗
416+ if( selectweapon == id ){ return; }
417+
418+ //武器切り替え中なら失敗
419+ if( selectweaponcnt > 0 ){ return; }
420+
421+ if( id == -1 ){
422+ //次の武器番号を選択
423+ selectweapon += 1;
424+ if( selectweapon == TOTAL_HAVEWEAPON ){
425+ selectweapon = 0;
426+ }
427+ }
428+ else{
429+ //武器番号が範囲内か確認
430+ if( (id < 0)||((TOTAL_HAVEWEAPON -1) < id ) ){ return; }
431+ selectweapon = id;
432+ }
433+
434+ //スコープ表示を解除
435+ SetDisableScope();
436+
437+ //腕の角度(反動)を設定
438+ reaction_y = (float)M_PI/18*2 * -1;
439+
440+ //切り替え完了のカウント
441+ selectweaponcnt = 10;
442+}
443+
444+//! @brief 武器の切り替えカウントを取得
445+//! @return カウント数 (1以上で切り替え中)
446+int human::GetChangeWeaponCnt()
447+{
448+ return selectweaponcnt;
449+}
450+
451+//! @brief 武器を取得
452+//! @param out_selectweapon 選択されている武器 (0 〜 [TOTAL_HAVEWEAPON]-1)
453+//! @param out_weapon 受け取るweaponクラスのポインタ配列 (配列数:TOTAL_HAVEWEAPON)
454+void human::GetWeapon(int *out_selectweapon, class weapon *out_weapon[])
455+{
456+ *out_selectweapon = selectweapon;
457+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
458+ out_weapon[i] = weapon[i];
459+ }
460+}
461+
462+//! @brief 現在装備している武器の種類番号を取得
463+//! @return 武器の種類番号(0 〜 TOTAL_PARAMETERINFO_WEAPON -1)
464+//! @attention 現在手に持っている武器の種類番号です。 GetWeapon()関数 を用いて調べるのと同等です。
465+int human::GetMainWeaponTypeNO()
466+{
467+ if( weapon[selectweapon] == NULL ){
468+ return ID_WEAPON_NONE;
469+ }
470+
471+ int id_param;
472+ weapon[selectweapon]->GetParamData(&id_param, NULL, NULL);
473+ return id_param;
474+}
475+
476+//! @brief 連射設定を取得
477+//! @return 連射可能:true 連射不可:false
478+bool human::GetWeaponBlazingmode()
479+{
480+ int param_id;
481+ WeaponParameter data;
482+
483+ //武器を装備していなければ、失敗
484+ if( weapon[selectweapon] == NULL ){ return false; }
485+
486+ //装備している武器の種類番号を取得
487+ weapon[selectweapon]->GetParamData(&param_id, NULL, NULL);
488+
489+ //連射設定を返す
490+ Param->GetWeapon(param_id, &data);
491+ return data.blazingmode;
492+}
493+
494+//! @brief 発砲処理
495+//! @param weapon_paramid 発砲した武器の番号を受け取るポインタ
496+//! @param GunsightErrorRange 発砲した際の照準誤差を受け取るポインタ
497+//! @return 成功:1 失敗:0
498+//! @attention 弾オブジェクトの処理や、発砲音の再生は別途行う必要があります。
499+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
500+bool human::ShotWeapon(int *weapon_paramid, int *GunsightErrorRange)
501+{
502+ int param_id;
503+
504+ //武器切り替え中なら失敗
505+ if( selectweaponcnt > 0 ){ return false; }
506+
507+ //武器を装備していなければ、失敗
508+ if( weapon[selectweapon] == NULL ){ return false; }
509+
510+ //弾の発射処理を行う
511+ if( weapon[selectweapon]->Shot() != 0 ){ return false; }
512+
513+ //武器の種類番号を取得
514+ weapon[selectweapon]->GetParamData(&param_id, NULL, NULL);
515+
516+
517+ //武器の設定値を取得
518+ WeaponParameter ParamData;
519+ if( Param->GetWeapon(param_id, &ParamData) != 0 ){ return false; }
520+
521+ //精密スコープの武器でスコープを覗いていなければ、誤差 20。
522+ if( (scopemode == 0)&&(ParamData.scopemode == 2) ){
523+ ReactionGunsightErrorRange = 20;
524+ }
525+
526+
527+ //武器の種類番号と誤差を返す
528+ *weapon_paramid = param_id;
529+ *GunsightErrorRange = StateGunsightErrorRange + ReactionGunsightErrorRange;
530+
531+
532+ //精密スコープ以外の武器を、スコープを使わずに使っていたら、設定された誤差を加算。
533+ if( (ParamData.scopemode != 2)&&(scopemode == 0) ){
534+ ReactionGunsightErrorRange += ParamData.reaction;
535+ }
536+
537+ //スコープを使用している状態の反動を加算
538+ if( (ParamData.scopemode == 1)&&(scopemode != 0) ){
539+ armrotation_y += (float)M_PI/180 * (WEAPONERRORRANGE_SCALE * ParamData.reaction);
540+ }
541+ if( ParamData.scopemode == 2 ){
542+ armrotation_y += (float)M_PI/180 * (WEAPONERRORRANGE_SCALE * ParamData.reaction);
543+ }
544+
545+ //腕に反動を伝える
546+ if( param_id == ID_WEAPON_GRENADE ){
547+ reaction_y = (float)M_PI/18*2;
548+ }
549+ else{
550+ reaction_y = (float)M_PI/360 * ParamData.reaction;
551+ }
552+
553+ //武器が無くなっていれば、装備から外した扱いに。 (手榴弾用)
554+ if( weapon[selectweapon]->GetDrawFlag() == false ){
555+ weapon[selectweapon] = NULL;
556+ }
557+ return true;
558+}
559+
560+//! @brief リロード
561+//! @return 成功:true 失敗:false
562+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
563+bool human::ReloadWeapon()
564+{
565+ //武器切り替え中なら失敗
566+ if( selectweaponcnt > 0 ){ return false; }
567+
568+ //何かしらの武器を装備していれば〜
569+ if( weapon[selectweapon] != NULL ){
570+ //リロード中なら失敗
571+ if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return false; }
572+
573+ //リロード処理を開始
574+ if( weapon[selectweapon]->StartReload() != 0 ){ return false; }
575+
576+ //スコープモードを解除
577+ SetDisableScope();
578+ return true;
579+ }
580+ return false;
581+}
582+
583+//! @brief 武器を捨てる
584+//! @return 成功:true 失敗:false
585+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
586+bool human::DumpWeapon()
587+{
588+ //武器切り替え中なら失敗
589+ if( selectweaponcnt > 0 ){ return false; }
590+
591+ //何かしらの武器を装備していれば〜
592+ if( weapon[selectweapon] != NULL ){
593+ //リロード中なら失敗
594+ if( weapon[selectweapon]->GetReloadCnt() > 0 ){ return false; }
595+
596+ //武器を捨て、装備を解除
597+ weapon[selectweapon]->Dropoff(pos_x, pos_y, pos_z, rotation_x, 1.63f);
598+ weapon[selectweapon] = NULL;
599+
600+ //スコープモードを解除
601+ SetDisableScope();
602+
603+ return true;
604+ }
605+
606+ return false;
607+}
608+
609+//! @brief 武器のショットモード切り替え
610+//! @return 成功:0 失敗:1
611+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
612+int human::ChangeShotMode()
613+{
614+ //武器を装備してなければ失敗
615+ if( weapon[selectweapon] == NULL ){ return 1; }
616+
617+ //装備している武器の情報を取得
618+ int param_id, lnbs, nbs;
619+ weapon[selectweapon]->GetParamData(&param_id, &lnbs, &nbs);
620+
621+ //武器のショットモード切り替え先(新しい武器番号)を調べる
622+ WeaponParameter ParamData;
623+ int ChangeWeapon;
624+ if( Param->GetWeapon(param_id, &ParamData) != 0 ){ return 1; }
625+ ChangeWeapon = ParamData.ChangeWeapon;
626+
627+ //新しい武器番号が正しいか確認
628+ if( ChangeWeapon == param_id ){ return 1; }
629+ if( (ChangeWeapon < 0)||(TOTAL_PARAMETERINFO_WEAPON-1 < ChangeWeapon) ){ return 1; }
630+
631+ //設定を適用
632+ weapon[selectweapon]->SetParamData(ChangeWeapon, lnbs, nbs, false);
633+ return 0;
634+}
635+
636+//! @brief 前進(走り)を設定
637+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
638+void human::SetMoveForward()
639+{
640+ SetFlag(MoveFlag, MOVEFLAG_FORWARD);
641+}
642+
643+//! @brief 後退を設定
644+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
645+void human::SetMoveBack()
646+{
647+ SetFlag(MoveFlag, MOVEFLAG_BACK);
648+}
649+
650+//! @brief 左走りを設定
651+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
652+void human::SetMoveLeft()
653+{
654+ SetFlag(MoveFlag, MOVEFLAG_LEFT);
655+}
656+
657+//! @brief 右走りを設定
658+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
659+void human::SetMoveRight()
660+{
661+ SetFlag(MoveFlag, MOVEFLAG_RIGHT);
662+}
663+
664+//! @brief 歩きを設定
665+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
666+void human::SetMoveWalk()
667+{
668+ SetFlag(MoveFlag, MOVEFLAG_WALK);
669+}
670+
671+//! @brief 人の移動モードを取得
672+//! @param nowdata 現在の値を取得:true 前フレームの値を使用:false
673+//! @return 歩き:1 走り:2 移動してない:0
674+int human::GetMovemode(bool nowdata)
675+{
676+ //使用されていないか、処理されていなければ終了
677+ if( RenderFlag == false ){ return 0; }
678+ if( hp <= 0 ){ return 0; }
679+
680+ if( nowdata == false ){ //前のデータ
681+ //歩きならば 1
682+ if( GetFlag(MoveFlag_lt, MOVEFLAG_WALK) ){
683+ return 1;
684+ }
685+ //走りならば 2
686+ if( GetFlag(MoveFlag_lt, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){
687+ return 2;
688+ }
689+ }
690+ else{ //現在のデータ
691+ //歩きならば 1
692+ if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){
693+ return 1;
694+ }
695+ //走りならば 2
696+ if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){
697+ return 2;
698+ }
699+ }
700+
701+ //移動してない
702+ return 0;
703+}
704+
705+//! @brief スコープを設定
706+//! @return 成功:true 失敗:false
707+bool human::SetEnableScope()
708+{
709+ int param_id;
710+ WeaponParameter data;
711+
712+ //何も武器を装備してなければ失敗
713+ if( weapon[selectweapon] == NULL ){ return false; }
714+
715+ //武器の種類番号を取得
716+ weapon[selectweapon]->GetParamData(&param_id, NULL, NULL);
717+
718+ //武器の設定値を取得
719+ Param->GetWeapon(param_id, &data);
720+
721+ //スコープを設定
722+ scopemode = data.scopemode;
723+ return true;
724+}
725+
726+//! @brief スコープを解除
727+void human::SetDisableScope()
728+{
729+ scopemode = 0;
730+}
731+
732+//! @brief スコープ設定を取得
733+int human::GetScopeMode()
734+{
735+ return scopemode;
736+}
737+
738+//! @brief 横軸と縦軸の向きを取得
739+//! @param rx 横軸を取得するポインタ
740+//! @param ry 縦軸を取得するポインタ
741+void human::GetRxRy(float *rx, float *ry)
742+{
743+ *rx = rotation_x;
744+ *ry = armrotation_y;
745+}
746+
747+//! @brief 横軸と縦軸の向きを設定
748+//! @param rx 設定する横軸
749+//! @param ry 設定する縦軸
750+void human::SetRxRy(float rx, float ry)
751+{
752+ rotation_x = rx;
753+ armrotation_y = ry;
754+}
755+
756+//! @brief 全体の回転角度取得
757+//! @return 縦軸を取得するポインタ
758+//! @warning 死亡して倒れる際の角度です。GetRxRy()関数で受け取る値とは異なります。
759+float human::GetDeadRy()
760+{
761+ return rotation_y;
762+}
763+
764+//! @brief ジャンプ
765+//! @return 成功:0 失敗:1
766+//! @attention ゲーム上から直接呼び出すことは避け、ObjectManagerクラスから呼び出してください。
767+int human::Jump()
768+{
769+ //地面に触れており、落下速度が0.0ならば
770+ if( move_y_flag == false ){
771+ if( move_y == 0.0f ){
772+ move_y = HUMAN_JUMP_SPEED;
773+ return 0;
774+ }
775+ }
776+ return 1;
777+}
778+
779+//! @brief 押しだす・力を加える
780+//! @param rx 横軸
781+//! @param ry 縦軸
782+//! @param speed 速度
783+void human::AddPosOrder(float rx, float ry, float speed)
784+{
785+ move_x += cos(rx) * cos(ry) * speed;
786+ move_y += sin(ry) * speed;
787+ move_z += sin(rx) * cos(ry) * speed;
788+}
789+
790+//! @brief 弾が 頭 にヒット
791+//! @param attacks 弾の攻撃力
792+void human::HitBulletHead(int attacks)
793+{
794+ if( Invincible == false ){
795+ hp -= (int)((float)attacks * HUMAN_DAMAGE_HEAD);
796+ }
797+ HitFlag = true;
798+}
799+
800+//! @brief 弾が 上半身 にヒット
801+//! @param attacks 弾の攻撃力
802+void human::HitBulletUp(int attacks)
803+{
804+ if( Invincible == false ){
805+ hp -= (int)((float)attacks * HUMAN_DAMAGE_UP);
806+ }
807+ HitFlag = true;
808+}
809+
810+//! @brief 弾が 下半身 にヒット
811+//! @param attacks 弾の攻撃力
812+void human::HitBulletLeg(int attacks)
813+{
814+ if( Invincible == false ){
815+ hp -= (int)((float)attacks * HUMAN_DAMAGE_LEG);
816+ }
817+ HitFlag = true;
818+}
819+
820+//! @brief ゾンビの攻撃がヒット
821+void human::HitZombieAttack()
822+{
823+ if( Invincible == false ){
824+ hp -= HUMAN_DAMAGE_ZOMBIEU + GetRand(HUMAN_DAMAGE_ZOMBIEA);
825+ }
826+ HitFlag = true;
827+}
828+
829+//! @brief 手榴弾の爆風がヒット
830+//! @param attacks 爆風の攻撃力
831+//! @attention 距離による計算を事前に済ませてください。
832+void human::HitGrenadeExplosion(int attacks)
833+{
834+ if( Invincible == false ){
835+ hp -= attacks;
836+ }
837+ HitFlag = true;
838+}
839+
840+//! @brief 被弾したかチェックする
841+//! @return 被弾した:true 被弾してない:false
842+//! @attention 実行すると、フラグは false に初期化されます。
843+bool human::CheckHit()
844+{
845+ bool returnflag = HitFlag;
846+ HitFlag = false;
847+ return returnflag;
848+}
849+
850+//! @brief 合計移動量を取得
851+//! @return 合計移動量
852+float human::GetTotalMove()
853+{
854+ return totalmove;
855+}
856+
857+//! @brief 照準の状態誤差の処理
858+//! @attention ControlProcess()より前で処理すること
859+void human::GunsightErrorRange()
860+{
861+ //初期化
862+ StateGunsightErrorRange = 0;
863+
864+ //各操作による誤差を設定
865+ if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){
866+ StateGunsightErrorRange = 4;
867+ }
868+ if( GetFlag(MoveFlag, MOVEFLAG_FORWARD) ){
869+ StateGunsightErrorRange = 8;
870+ }
871+ if( GetFlag(MoveFlag, MOVEFLAG_BACK) ){
872+ StateGunsightErrorRange = 6;
873+ }
874+ if( GetFlag(MoveFlag, (MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){
875+ StateGunsightErrorRange = 7;
876+ }
877+ if( move_y_flag == true ){
878+ StateGunsightErrorRange = 22;
879+ }
880+ if( hp < 40 ){
881+ StateGunsightErrorRange += 3;
882+ }
883+
884+ //何か武器を装備していれば
885+ if( weapon[selectweapon] != NULL ){
886+ //武器の設定データを取得
887+ int param;
888+ WeaponParameter data;
889+ weapon[selectweapon]->GetParamData(&param, NULL, NULL);
890+ Param->GetWeapon(param, &data);
891+
892+ //誤差を 1 減らす
893+ ReactionGunsightErrorRange -= 1;
894+
895+ //誤差の範囲を補正
896+ if( ReactionGunsightErrorRange < 0 ){ ReactionGunsightErrorRange = 0; }
897+ if( ReactionGunsightErrorRange > data.ErrorRangeMAX ){ ReactionGunsightErrorRange = data.ErrorRangeMAX; }
898+ }
899+ else{
900+ ReactionGunsightErrorRange = 0;
901+ }
902+}
903+
904+//! @brief 死亡判定と倒れる処理
905+//! @return 静止した死体:4 倒れ終わった直後:3 倒れている最中:2 倒れ始める:1 何もしない:0
906+int human::CheckAndProcessDead(class Collision *CollD)
907+{
908+#ifdef HUMAN_DEADBODY_COLLISION
909+ float add_ry = 0.0f;
910+ float check_posx, check_posy, check_posz;
911+
912+ if( deadstate == 0 ){
913+ if( hp <= 0 ){ //HPが 0 以下になった(死亡した)瞬間なら、倒し始める
914+ //体の角度・腕の角度
915+ switch( GetRand(4) ){
916+ case 0:
917+ add_ry = (float)M_PI/180*6;
918+ armrotation_y = (float)M_PI/2;
919+ break;
920+ case 1:
921+ add_ry = (float)M_PI/180*6 * -1;
922+ armrotation_y = (float)M_PI/2;
923+ break;
924+ case 2:
925+ add_ry = (float)M_PI/180*6;
926+ armrotation_y = (float)M_PI/2 * -1;
927+ break;
928+ case 3:
929+ add_ry = (float)M_PI/180*6 * -1;
930+ armrotation_y = (float)M_PI/2 * -1;
931+ break;
932+ }
933+
934+ //死体が埋まらぬよう、高さを +1.0 する
935+ pos_y += 1.0f;
936+
937+ //所持している武器を全て捨てる
938+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
939+ if( weapon[i] != NULL ){
940+ weapon[i]->Dropoff(pos_x, pos_y, pos_z, (float)M_PI/18*GetRand(36), 1.5f);
941+ weapon[i] = NULL;
942+ }
943+ }
944+
945+ //スコープモードを解除
946+ SetDisableScope();
947+
948+ //次のフレームの頭の座標を取得
949+ check_posx = pos_x + cos(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH;
950+ check_posy = pos_y + cos(add_ry) * HUMAN_HEIGTH;
951+ check_posz = pos_z + sin(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH;
952+
953+ if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){
954+ deadstate = 2;
955+ }
956+ else{
957+ rotation_y += add_ry;
958+ deadstate = 1;
959+ }
960+ return 1;
961+ }
962+ return 0;
963+ }
964+
965+ if( deadstate == 1 ){
966+ //135度以上倒れていれば
967+ if( abs(rotation_y) >= (float)M_PI/4*3 ){
968+ deadstate = 2;
969+ return 2;
970+ }
971+
972+ if( pos_y <= (HUMAN_DEADLINE + 10.0f) ){
973+ //90度以上倒れていれば
974+ if( abs(rotation_y) >= (float)M_PI/2 ){
975+ deadstate = 4;
976+ return 2;
977+ }
978+ }
979+
980+ //前後に倒す
981+ if( rotation_y > 0.0f ){ //rotation_y < (float)M_PI/4*3
982+ add_ry = (float)M_PI/180*6;
983+ }
984+ else if( rotation_y < 0.0f ){ //rotation_y > (float)M_PI/4*3 * -1
985+ add_ry = (float)M_PI/180*6 * -1;
986+ }
987+
988+ if( pos_y <= HUMAN_DEADLINE ){
989+ rotation_y += add_ry;
990+ }
991+ else{
992+ //次のフレームの頭の座標を取得
993+ check_posx = pos_x + cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
994+ check_posy = pos_y + cos(rotation_y + add_ry) * HUMAN_HEIGTH;
995+ check_posz = pos_z + sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
996+
997+ if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){
998+ deadstate = 3;
999+ }
1000+ else{
1001+ rotation_y += add_ry;
1002+ }
1003+ }
1004+
1005+ return 2;
1006+ }
1007+
1008+ if( deadstate == 2 ){
1009+ if( pos_y <= HUMAN_DEADLINE ){
1010+ deadstate = 4;
1011+ return 2;
1012+ }
1013+
1014+ //次のフレームの足の座標
1015+ check_posx = pos_x;
1016+ check_posy = pos_y - 0.5f;
1017+ check_posz = pos_z;
1018+
1019+ if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){
1020+ deadstate = 4;
1021+ }
1022+ else{
1023+ pos_y -= 0.5f;
1024+ }
1025+
1026+ return 2;
1027+ }
1028+
1029+ if( deadstate == 3 ){
1030+ //deadstate = 4;
1031+
1032+ //90度以上倒れていれば
1033+ if( abs(rotation_y) >= (float)M_PI/2 ){
1034+ deadstate = 4;
1035+ return 2;
1036+ }
1037+
1038+ //前後に倒す
1039+ if( rotation_y > 0.0f ){ //rotation_y < (float)M_PI/2
1040+ add_ry = (float)M_PI/180*6;
1041+ }
1042+ else if( rotation_y < 0.0f ){ //rotation_y > (float)M_PI/2 * -1
1043+ add_ry = (float)M_PI/180*6 * -1;
1044+ }
1045+
1046+ //次のフレームの足の座標を取得
1047+ check_posx = pos_x - cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
1048+ check_posy = pos_y + 0.1f;
1049+ check_posz = pos_z - sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
1050+
1051+ if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){
1052+ deadstate = 4;
1053+ return 2;
1054+ }
1055+
1056+ //次のフレームの頭の座標を取得
1057+ check_posx = pos_x - cos(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
1058+ check_posy = pos_y + cos(rotation_y + add_ry) * HUMAN_HEIGTH;
1059+ check_posz = pos_z - sin(rotation_x*-1 - (float)M_PI/2) * sin(rotation_y + add_ry) * HUMAN_HEIGTH;
1060+
1061+ if( CollD->CheckALLBlockInside(check_posx, check_posy, check_posz) == true ){
1062+ deadstate = 4;
1063+ return 2;
1064+ }
1065+
1066+ //足の座標を移動
1067+ pos_x -= cos(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH;
1068+ pos_z -= sin(rotation_x*-1 - (float)M_PI/2) * sin(add_ry) * HUMAN_HEIGTH;
1069+
1070+ rotation_y += add_ry;
1071+ return 2;
1072+ }
1073+
1074+ if( deadstate == 4 ){
1075+ //何もしない(固定)
1076+ deadstate = 5;
1077+ return 3;
1078+ }
1079+
1080+ if( deadstate == 5 ){
1081+ //何もしない(固定)
1082+ return 4;
1083+ }
1084+
1085+ return 0;
1086+#else
1087+ if( abs(rotation_y) >= (float)M_PI/2 ){
1088+ return 4;
1089+ }
1090+ else if( rotation_y > 0.0f ){ //倒れ始めていれば、そのまま倒れる。
1091+ if( rotation_y < (float)M_PI/2 ){
1092+ rotation_y += (float)M_PI/180*6;
1093+ return 2;
1094+ }
1095+ return 3;
1096+ }
1097+ else if( rotation_y < 0.0f ){ //倒れ始めていれば、そのまま倒れる。
1098+ if( rotation_y > (float)M_PI/2 * -1 ){
1099+ rotation_y -= (float)M_PI/180*6;
1100+ return 2;
1101+ }
1102+ return 3;
1103+ }
1104+ else if( hp <= 0 ){ //HPが 0 以下になった(死亡した)瞬間なら、倒し始める
1105+ //体の角度・腕の角度
1106+ switch( GetRand(4) ){
1107+ case 0:
1108+ rotation_y = (float)M_PI/180*6;
1109+ armrotation_y = (float)M_PI/2;
1110+ break;
1111+ case 1:
1112+ rotation_y = (float)M_PI/180*6 * -1;
1113+ armrotation_y = (float)M_PI/2;
1114+ break;
1115+ case 2:
1116+ rotation_y = (float)M_PI/180*6;
1117+ armrotation_y = (float)M_PI/2 * -1;
1118+ break;
1119+ case 3:
1120+ rotation_y = (float)M_PI/180*6 * -1;
1121+ armrotation_y = (float)M_PI/2 * -1;
1122+ break;
1123+ }
1124+
1125+ //死体が埋まらぬよう、高さを +1.0 する
1126+ pos_y += 1.0f;
1127+
1128+ //所持している武器を全て捨てる
1129+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1130+ if( weapon[i] != NULL ){
1131+ weapon[i]->Dropoff(pos_x, pos_y, pos_z, (float)M_PI/18*GetRand(36), 1.5f);
1132+ weapon[i] = NULL;
1133+ }
1134+ }
1135+
1136+ //スコープモードを解除
1137+ SetDisableScope();
1138+
1139+ return 1;
1140+ }
1141+
1142+ return 0;
1143+#endif
1144+}
1145+
1146+//! @brief 操作による移動計算
1147+//! @attention 実行すると、各キーフラグは false に初期化されます。
1148+void human::ControlProcess()
1149+{
1150+ //進行方向と速度を決定
1151+ if( GetFlag(MoveFlag, MOVEFLAG_WALK) ){
1152+ move_rx = 0.0f;
1153+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_PROGRESSWALK_ACCELERATION);
1154+ walkcnt += 1;
1155+ runcnt = 0;
1156+ }
1157+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_FORWARD ){
1158+ move_rx = 0.0f;
1159+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_PROGRESSRUN_ACCELERATION);
1160+ walkcnt = 0;
1161+ runcnt += 1;
1162+ }
1163+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_BACK ){
1164+ move_rx = (float)M_PI;
1165+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_REGRESSRUN_ACCELERATION);
1166+ walkcnt = 0;
1167+ runcnt += 1;
1168+ }
1169+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_LEFT ){
1170+ move_rx = (float)M_PI/2;
1171+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_SIDEWAYSRUN_ACCELERATION);
1172+ walkcnt = 0;
1173+ runcnt += 1;
1174+ }
1175+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == MOVEFLAG_RIGHT ){
1176+ move_rx = (float)M_PI/2 * -1;
1177+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_SIDEWAYSRUN_ACCELERATION);
1178+ walkcnt = 0;
1179+ runcnt += 1;
1180+ }
1181+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_FORWARD | MOVEFLAG_LEFT) ){
1182+ move_rx = (float)M_PI/4;
1183+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_PROGRESSRUN_SIDEWAYSRUN_ACCELERATION);
1184+ walkcnt = 0;
1185+ runcnt += 1;
1186+ }
1187+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_BACK | MOVEFLAG_LEFT) ){
1188+ move_rx = (float)M_PI/4*3;
1189+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_REGRESSRUN_SIDEWAYSRUN_ACCELERATION);
1190+ walkcnt = 0;
1191+ runcnt += 1;
1192+ }
1193+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_BACK | MOVEFLAG_RIGHT) ){
1194+ move_rx = (float)M_PI/4*3 * -1;
1195+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_REGRESSRUN_SIDEWAYSRUN_ACCELERATION);
1196+ walkcnt = 0;
1197+ runcnt += 1;
1198+ }
1199+ else if( GetFlag(MoveFlag, (MOVEFLAG_FORWARD | MOVEFLAG_BACK | MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) == (MOVEFLAG_FORWARD | MOVEFLAG_RIGHT) ){
1200+ move_rx = (float)M_PI/4 * -1;
1201+ AddPosOrder(rotation_x*-1 + move_rx + (float)M_PI/2, 0.0f, HUMAN_PROGRESSRUN_SIDEWAYSRUN_ACCELERATION);
1202+ walkcnt = 0;
1203+ runcnt += 1;
1204+ }
1205+ else{
1206+ move_rx = 0.0f;
1207+ walkcnt = 0;
1208+ runcnt = 0;
1209+ }
1210+
1211+ //フラグをバックアップ
1212+ MoveFlag_lt = MoveFlag;
1213+
1214+ //キーフラグを元に戻す
1215+ MoveFlag = 0x00;
1216+}
1217+
1218+//! @brief 特定の方向(ベクトル)に対して、ブロックの面が表面か裏面か調べる
1219+//! @param inblockdata BlockDataInterfaceクラスのポインタ
1220+//! @param bid 判定するブロック番号
1221+//! @param fid 判定する面番号
1222+//! @param vx X軸ベクトルのポインタ
1223+//! @param vz Z軸ベクトルのポインタ
1224+//! @return 表向き:true 裏向き:false
1225+bool human::CheckBlockAngle(class BlockDataInterface *inblockdata, int bid, int fid, float vx, float vz)
1226+{
1227+ if( inblockdata == NULL ){ return false; }
1228+ if( (bid < 0)||(inblockdata->GetTotaldatas() <= bid) ){ return false; }
1229+
1230+ float costheta;
1231+ struct blockdata bdata;
1232+
1233+ inblockdata->Getdata(&bdata, bid);
1234+ 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));
1235+ if( acos(costheta) > (float)M_PI/2 ){
1236+ return true;
1237+ }
1238+ return false;
1239+}
1240+
1241+//! @brief マップとの当たり判定
1242+//! @param CollD Collisionクラスのポインタ
1243+//! @param inblockdata BlockDataInterfaceクラスのポインタ
1244+//! @param FallDist Y軸の移動量を取得するポインタ
1245+//! @return ブロックに埋まっている:true 埋まっていない:false
1246+bool human::MapCollisionDetection(class Collision *CollD, class BlockDataInterface *inblockdata, float *FallDist)
1247+{
1248+ bool inside = false;
1249+ int id;
1250+ int face;
1251+ float vx, vz;
1252+ float vy = 0.1f;
1253+ float speed;
1254+ float Dist;
1255+ float FallDistance;
1256+ float offset;
1257+
1258+ //足元ギリギリは当たり判定から除外する
1259+ offset = 0.1f;
1260+
1261+ // 上下方向のあたり判定(ジャンプ・自然落下)
1262+ //--------------------------------------------------
1263+
1264+ //足元がブロックに埋まっていなければ
1265+ if( CollD->CheckALLBlockInside(pos_x, pos_y + offset, pos_z) == false ){
1266+ //落下速度を計算
1267+ move_y -= HUMAN_DAMAGE_SPEED;
1268+ if( move_y < HUMAN_DAMAGE_MAXSPEED ){ move_y = HUMAN_DAMAGE_MAXSPEED; }
1269+
1270+ if( move_y > 0.0f ){
1271+ //上方向へ当たり判定
1272+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, 0, 1, 0, NULL, NULL, &Dist, move_y) == true ){
1273+ CollD->CheckALLBlockIntersectRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, 0, 1, 0, NULL, NULL, &Dist, move_y);
1274+
1275+ FallDistance = Dist;
1276+ move_y = 0.0f;
1277+ }
1278+ else{
1279+ FallDistance = move_y;
1280+ }
1281+ FallDistance = move_y;
1282+ move_y_flag = true;
1283+ }
1284+ else{
1285+ int id, face;
1286+ struct blockdata bdata;
1287+
1288+ //下方向へ当たり判定
1289+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + offset, pos_z, 0, -1, 0, NULL, NULL, &Dist, move_y*-1 + offset) == true ){
1290+ CollD->CheckALLBlockIntersectRay(pos_x, pos_y + offset, pos_z, 0, -1, 0, &id, &face, &Dist, move_y + offset);
1291+
1292+ if( Invincible == false ){
1293+ //ダメージ計算
1294+ if( move_y > HUMAN_DAMAGE_MINSPEED ){ hp -= 0; }
1295+ else{ hp -= (int)((float)HUMAN_DAMAGE_MAXFALL / abs(HUMAN_DAMAGE_MAXSPEED - (HUMAN_DAMAGE_MINSPEED)) * abs(move_y - (HUMAN_DAMAGE_MINSPEED))); }
1296+ }
1297+
1298+ FallDistance = (Dist - offset) * -1;
1299+ move_y = 0.0f;
1300+
1301+ inblockdata->Getdata(&bdata, id);
1302+
1303+ //斜面に立っているなら
1304+ if( acos(bdata.material[face].vy) > HUMAN_MAPCOLLISION_SLOPEANGLE ){
1305+ //地面と認めない (ジャンプ対策)
1306+ move_y_flag = true;
1307+
1308+ //押し出す
1309+ move_x += bdata.material[face].vx * HUMAN_MAPCOLLISION_SLOPEFORCE;
1310+ move_z += bdata.material[face].vz * HUMAN_MAPCOLLISION_SLOPEFORCE;
1311+ }
1312+ else{
1313+ move_y_flag = false;
1314+ }
1315+ }
1316+ else{
1317+ FallDistance = move_y;
1318+ move_y_flag = true;
1319+ }
1320+ }
1321+ }
1322+ else{ //埋まっている
1323+ FallDistance = move_y;
1324+ move_y = 0.0f;
1325+ move_y_flag = false;
1326+ }
1327+
1328+
1329+ // 水平方向のあたり判定(移動)
1330+ //--------------------------------------------------
1331+
1332+ if( (move_x*move_x + move_z*move_z) ){
1333+ int surface;
1334+ float ang = atan2(move_z, move_x);
1335+ float newpos_x, newpos_y, newpos_z;
1336+
1337+ //腰付近を当たり判定
1338+ for(int i=0; i<MAX_BLOCKS; i++){
1339+ surface = -1;
1340+ CollD->CheckBlockInside(i, pos_x, pos_y + HUMAN_MAPCOLLISION_HEIGTH, pos_z, false, &surface);
1341+
1342+ if( surface != -1 ){
1343+ //HUMAN_MAPCOLLISION_R 分の先を調べる
1344+ 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 ){
1345+ CollD->ScratchVector(inblockdata, i, surface, move_x, vy, move_z, &move_x, &vy, &move_z);
1346+ }
1347+
1348+ //左右90度づつを調べる
1349+ 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 ){
1350+ if( CheckBlockAngle(inblockdata, i, surface, cos(ang), sin(ang)) == true ){ //進行方向に対して表向きなら〜
1351+ CollD->ScratchVector(inblockdata, i, surface, move_x, vy, move_z, &move_x, &vy, &move_z);
1352+ }
1353+ }
1354+ 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 ){
1355+ if( CheckBlockAngle(inblockdata, i, surface, cos(ang), sin(ang)) == true ){ //進行方向に対して表向きなら〜
1356+ CollD->ScratchVector(inblockdata, i, surface, move_x, vy, move_z, &move_x, &vy, &move_z);
1357+ }
1358+ }
1359+ }
1360+ }
1361+
1362+ //進行方向を示すベクトルを算出
1363+ vx = move_x;
1364+ vz = move_z;
1365+ speed = sqrt(vx*vx + vz*vz);
1366+ if( speed > 0.0f ){
1367+ vx = vx / speed;
1368+ vz = vz / speed;
1369+ }
1370+
1371+ //頭を当たり判定
1372+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + HUMAN_HEIGTH, pos_z, vx, 0, vz, NULL, NULL, &Dist, speed) == true ){
1373+ CollD->CheckALLBlockIntersectRay(pos_x, pos_y + FallDistance + HUMAN_HEIGTH, pos_z, vx, 0, vz, &id, &face, &Dist, speed);
1374+ CollD->ScratchVector(inblockdata, id, face, move_x, vy, move_z, &move_x, &vy, &move_z);
1375+ }
1376+
1377+ //足元がブロックに埋まっていなければ
1378+ if( CollD->CheckALLBlockInside(pos_x, pos_y + offset, pos_z) == false ){
1379+
1380+ //進行方向を示すベクトルを算出
1381+ vx = move_x;
1382+ vz = move_z;
1383+ speed = sqrt(vx*vx + vz*vz);
1384+ if( speed > 0.0f ){
1385+ vx = vx / speed;
1386+ vz = vz / speed;
1387+ }
1388+
1389+ //足元を当たり判定
1390+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + offset, pos_z, vx, 0, vz, NULL, NULL, &Dist, speed) == true ){
1391+ CollD->CheckALLBlockIntersectRay(pos_x, pos_y + offset, pos_z, vx, 0, vz, &id, &face, &Dist, speed);
1392+
1393+ struct blockdata bdata;
1394+ inblockdata->Getdata(&bdata, id);
1395+
1396+ if( acos(bdata.material[face].vy) > HUMAN_MAPCOLLISION_SLOPEANGLE ){ //斜面〜壁なら
1397+ //乗り越えられる高さか調べる
1398+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y + 3.5f + offset, pos_z, vx, 0, vz, NULL, NULL, &Dist, speed) == false ){
1399+ //人を上に持ち上げる
1400+ FallDistance = 0.4f;
1401+ move_y = 0.0f;
1402+ }
1403+
1404+ //足元を当たり判定
1405+ CollD->ScratchVector(inblockdata, id, face, move_x, vy, move_z, &move_x, &vy, &move_z);
1406+ }
1407+ else{ //水平〜斜面なら
1408+ //地面と認めない (ジャンプ対策)
1409+ move_y_flag = true;
1410+
1411+ //移動先の位置を計算
1412+ newpos_x = pos_x + move_x;
1413+ newpos_y = pos_y + FallDistance;
1414+ newpos_z = pos_z + move_z;
1415+
1416+ //移動先の高さを調べる
1417+ if( CollD->CheckALLBlockInside(newpos_x, newpos_y + HUMAN_HEIGTH, newpos_z) == false ){
1418+ if( CollD->CheckALLBlockIntersectRay(newpos_x, newpos_y + HUMAN_HEIGTH, newpos_z, 0, -1, 0, NULL, NULL, &Dist, HUMAN_HEIGTH) == true ){
1419+ float height = HUMAN_HEIGTH - Dist;
1420+
1421+ //人を上に持ち上げる
1422+ if( height > 0.9f ){
1423+ FallDistance = 0.4f;
1424+ }
1425+ else{
1426+ FallDistance = height;
1427+ }
1428+
1429+ move_y = 0.0f;
1430+ }
1431+ }
1432+ }
1433+ }
1434+ }
1435+
1436+ //移動先の位置を計算
1437+ newpos_x = pos_x + move_x;
1438+ newpos_y = pos_y + FallDistance;
1439+ newpos_z = pos_z + move_z;
1440+
1441+ //全身を改めて確認
1442+ if(
1443+ (CollD->CheckALLBlockInside(newpos_x, newpos_y + offset, newpos_z) == true)||
1444+ (CollD->CheckALLBlockIntersectRay(newpos_x, newpos_y + offset, newpos_z, 0, 1, 0, NULL, NULL, &Dist, HUMAN_HEIGTH - offset - 1.0f) == true)
1445+ ){
1446+ //めり込むなら移動しない
1447+ move_x = 0.0f;
1448+ move_z = 0.0f;
1449+ inside = true;
1450+ }
1451+ }
1452+
1453+ *FallDist = FallDistance;
1454+ return inside;
1455+}
1456+
1457+//! @brief 計算を実行(当たり判定)
1458+//! @param CollD Collisionのポインタ
1459+//! @param inblockdata BlockDataInterfaceのポインタ
1460+//! @param F5mode 上昇機能(F5裏技)のフラグ (有効:true 無効:false)
1461+//! @return 処理なし:0 通常処理:1 死亡して倒れ終わった直後:2 静止した死体:3
1462+int human::RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata, bool F5mode)
1463+{
1464+ if( CollD == NULL ){ return 0; }
1465+ if( RenderFlag == false ){ return 0; }
1466+
1467+#ifdef HUMAN_DEADBODY_COLLISION
1468+ if( deadstate == 5 ){ return 3; }
1469+#else
1470+ if( hp <= 0 ){ return 3; }
1471+#endif
1472+
1473+ float FallDistance;
1474+ int CheckDead;
1475+
1476+ //武器切り替えカウント
1477+ if( selectweaponcnt > 0 ){
1478+ selectweaponcnt -= 1;
1479+ }
1480+
1481+ //発砲による反動
1482+ if( reaction_y > 0.0f ){
1483+ if( reaction_y > (float)M_PI/180*2 ){ reaction_y -= (float)M_PI/180*2; }
1484+ else{ reaction_y = 0.0f; }
1485+ }
1486+ if( reaction_y < 0.0f ){
1487+ if( reaction_y < (float)M_PI/180*2 ){ reaction_y += (float)M_PI/180*2; }
1488+ else{ reaction_y = 0.0f; }
1489+ }
1490+
1491+ //リロード中なら腕の角度を再設定
1492+ if( weapon[selectweapon] != NULL ){
1493+ if( weapon[selectweapon]->GetReloadCnt() > 0 ){
1494+ reaction_y = ARMRAD_RELOADWEAPON;
1495+ }
1496+ }
1497+
1498+ //足の角度を、-90度〜90度の範囲に設定
1499+ if( hp <= 0 ){
1500+ legrotation_x = 0.0f;
1501+ }
1502+ else{
1503+ float add_legrx;
1504+
1505+ //目標値を設定
1506+ if( fabs(move_rx) > (float)M_PI/2 ){
1507+ add_legrx = move_rx + (float)M_PI - legrotation_x;
1508+ }
1509+ else{
1510+ add_legrx = move_rx - legrotation_x;
1511+ }
1512+ for(; add_legrx > (float)M_PI; add_legrx -= (float)M_PI*2){}
1513+ for(; add_legrx < (float)M_PI*-1; add_legrx += (float)M_PI*2){}
1514+
1515+ //補正していく
1516+ if( add_legrx > (float)M_PI/18 ){ legrotation_x += (float)M_PI/18; }
1517+ else if( add_legrx < (float)M_PI/18*-1 ){ legrotation_x -= (float)M_PI/18; }
1518+ else{ legrotation_x += add_legrx; }
1519+ }
1520+
1521+ //照準の状態誤差の処理
1522+ GunsightErrorRange();
1523+
1524+ //死亡判定と倒れる処理
1525+ CheckDead = CheckAndProcessDead(CollD);
1526+ if( CheckDead == 3 ){ return 2; }
1527+ if( CheckDead != 0 ){ return 3; }
1528+
1529+ //進行方向と速度を決定
1530+ ControlProcess();
1531+
1532+ //マップとの当たり判定
1533+ MapCollisionDetection(CollD, inblockdata, &FallDistance);
1534+
1535+ //移動するなら
1536+ if( (move_x*move_x + move_z*move_z) > 0.0f * 0.0f ){
1537+ totalmove += sqrt(move_x*move_x + move_z*move_z);
1538+ }
1539+
1540+ //座標移動
1541+ pos_x += move_x;
1542+ pos_z += move_z;
1543+
1544+ //移動量を減衰
1545+ move_x *= HUMAN_ATTENUATION;
1546+ move_z *= HUMAN_ATTENUATION;
1547+
1548+ //F5を使用していなければ、計算結果を反映
1549+ if( F5mode == false ){
1550+ pos_y += FallDistance;
1551+ }
1552+ else{
1553+ move_y = 0.0f;
1554+ pos_y += 5.0f; //使用していれば、強制的に上昇
1555+ }
1556+
1557+
1558+ //-100.0より下に落ちたら、死亡
1559+ if( pos_y < HUMAN_DEADLINE ){
1560+ pos_y = HUMAN_DEADLINE;
1561+ hp = 0;
1562+ }
1563+
1564+ return 1;
1565+}
1566+
1567+//! @brief 標準誤差を取得
1568+int human::GetGunsightErrorRange()
1569+{
1570+ return StateGunsightErrorRange + ReactionGunsightErrorRange;
1571+}
1572+
1573+//! @brief 描画
1574+//! @param d3dg D3DGraphicsのポインタ
1575+//! @param Resource ResourceManagerのポインタ
1576+//! @param DrawArm 腕と武器のみ描画する
1577+//! @param player 対象の人物がプレイヤーかどうか
1578+//! @todo 腕の位置を行列で求める
1579+//! @todo 死体の部位の高さ(Y軸)がおかしい
1580+void human::Render(class D3DGraphics *d3dg, class ResourceManager *Resource, bool DrawArm, bool player)
1581+{
1582+ //正しく初期化されていなければ、処理しない
1583+ if( d3dg == NULL ){ return; }
1584+ if( RenderFlag == false ){ return; }
1585+
1586+ //現在装備する武器のクラスを取得
1587+ class weapon *nowweapon;
1588+ nowweapon = weapon[selectweapon];
1589+
1590+ if( DrawArm == false ){
1591+ int legmodelid;
1592+
1593+ //上半身を描画
1594+ d3dg->SetWorldTransform(pos_x, pos_y - 1.0f, pos_z, rotation_x + (float)M_PI, rotation_y, upmodel_size);
1595+ d3dg->RenderModel(id_upmodel, id_texture);
1596+
1597+ //足のモデルを設定
1598+ legmodelid = id_legmodel; //立ち止まり
1599+ if( GetFlag(MoveFlag_lt, MOVEFLAG_WALK) ){
1600+ legmodelid = id_walkmodel[ (walkcnt/3 % TOTAL_WALKMODE) ]; //歩き
1601+ }
1602+ if( GetFlag(MoveFlag_lt, (MOVEFLAG_LEFT | MOVEFLAG_RIGHT)) ){
1603+ legmodelid = id_runmodel[ (runcnt/3 % TOTAL_RUNMODE) ]; //左右走り
1604+ }
1605+ if( GetFlag(MoveFlag_lt, MOVEFLAG_FORWARD) ){
1606+ legmodelid = id_runmodel[ (runcnt/2 % TOTAL_RUNMODE) ]; //前走り
1607+ }
1608+ if( GetFlag(MoveFlag_lt, MOVEFLAG_BACK) ){
1609+ legmodelid = id_runmodel[ (runcnt/4 % TOTAL_RUNMODE) ]; //後ろ走り
1610+ }
1611+
1612+ //足を描画
1613+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x + (float)M_PI + legrotation_x*-1, rotation_y, legmodel_size);
1614+ d3dg->RenderModel(legmodelid, id_texture);
1615+ }
1616+
1617+ //腕を描画
1618+ if( rotation_y != 0.0f ){ //死亡して倒れている or 倒れ始めた
1619+ float x = pos_x + cos(rotation_x*-1 - (float)M_PI/2)*sin(rotation_y)*16.0f;
1620+ float y = pos_y + cos(rotation_y)*16.0f;
1621+ float z = pos_z + sin(rotation_x*-1 - (float)M_PI/2)*sin(rotation_y)*16.0f;
1622+ d3dg->SetWorldTransform(x, y, z, rotation_x + (float)M_PI, armrotation_y + rotation_y, armmodel_size);
1623+ d3dg->RenderModel(id_armmodel[0], id_texture);
1624+ }
1625+ else if( nowweapon == NULL ){ //手ぶら
1626+ float ry;
1627+ if( player == true ){
1628+ ry = ARMRAD_NOWEAPON;
1629+ }
1630+ else{
1631+ ry = armrotation_y;
1632+ }
1633+ d3dg->SetWorldTransform(pos_x, pos_y + 16.0f, pos_z, rotation_x + (float)M_PI, ry, armmodel_size);
1634+ d3dg->RenderModel(id_armmodel[0], id_texture);
1635+ }
1636+ else{ //何か武器を持っている
1637+ //武器のモデルとテクスチャを取得
1638+ int id_param;
1639+ int armmodelid = 0;
1640+ WeaponParameter paramdata;
1641+ int model, texture;
1642+ float ry = 0.0f;
1643+ nowweapon->GetParamData(&id_param, NULL, NULL);
1644+ Param->GetWeapon(id_param, &paramdata);
1645+ Resource->GetWeaponModelTexture(id_param, &model, &texture);
1646+
1647+ //腕の形と角度を決定
1648+ if( paramdata.WeaponP == 0 ){
1649+ armmodelid = 1;
1650+ ry = armrotation_y + reaction_y;
1651+ }
1652+ if( paramdata.WeaponP == 1 ){
1653+ armmodelid = 2;
1654+ ry = armrotation_y + reaction_y;
1655+ }
1656+ if( paramdata.WeaponP == 2 ){
1657+ armmodelid = 0;
1658+ ry = ARMRAD_NOWEAPON;
1659+ }
1660+
1661+ //腕を描画
1662+ d3dg->SetWorldTransform(pos_x, pos_y + 16.0f, pos_z, rotation_x + (float)M_PI, ry, armmodel_size);
1663+ d3dg->RenderModel(id_armmodel[armmodelid], id_texture);
1664+
1665+ //武器を描画
1666+ 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);
1667+ d3dg->RenderModel(model, texture);
1668+ }
1669+}
1670+
1671+//! @brief コンストラクタ
1672+weapon::weapon(class ParameterInfo *in_Param, float x, float y, float z, float rx, int id_param, int nbs, bool flag)
1673+{
1674+ Param = in_Param;
1675+ pos_x = x;
1676+ pos_y = y;
1677+ pos_z = z;
1678+ move_x = 0.0f;
1679+ move_y = 0.0f;
1680+ move_z = 0.0f;
1681+ rotation_x = rx;
1682+ RenderFlag = flag;
1683+
1684+ id_parameter = id_param;
1685+ usingflag = false;
1686+ bullets = nbs;
1687+ Loadbullets = 0;
1688+ shotcnt = 0;
1689+ motionflag = true;
1690+
1691+ if( Param != NULL ){
1692+ WeaponParameter ParamData;
1693+ if( Param->GetWeapon(id_param, &ParamData) == 0 ){
1694+ model_size = ParamData.size;
1695+ //id_model = ParamData.id_model;
1696+ //id_texture = ParamData.id_texture;
1697+ }
1698+ }
1699+ id_model = -1;
1700+ id_texture = -1;
1701+}
1702+
1703+//! @brief ディストラクタ
1704+weapon::~weapon()
1705+{}
1706+
1707+//! @brief 座標と角度を設定
1708+//! @param x X座標
1709+//! @param y Y座標
1710+//! @param z Z座標
1711+//! @param rx 横軸回転
1712+void weapon::SetPosData(float x, float y, float z, float rx)
1713+{
1714+ pos_x = x;
1715+ pos_y = y;
1716+ pos_z = z;
1717+ move_x = 0.0f;
1718+ move_y = 0.0f;
1719+ move_z = 0.0f;
1720+ rotation_x = rx;
1721+}
1722+
1723+//! @brief 設定値を設定
1724+//! @param id_param 武器の種類番号
1725+//! @param lnbs 装弾数
1726+//! @param nbs 合計弾数
1727+//! @param init オブジェクトを初期化
1728+void weapon::SetParamData(int id_param, int lnbs, int nbs, bool init)
1729+{
1730+ id_parameter = id_param;
1731+ bullets = nbs;
1732+ Loadbullets = lnbs;
1733+
1734+ if( init == true ){
1735+ usingflag = false;
1736+ shotcnt = 0;
1737+ reloadcnt = 0;
1738+ motionflag = true;
1739+ }
1740+}
1741+
1742+//! @brief 設定値を取得
1743+//! @param id_param 武器の種類番号を受け取るポインタ(NULL可)
1744+//! @param lnbs 装弾数を受け取るポインタ(NULL可)
1745+//! @param nbs 合計弾数を受け取るポインタ(NULL可)
1746+void weapon::GetParamData(int *id_param, int *lnbs, int *nbs)
1747+{
1748+ if( id_param != NULL ){ *id_param = id_parameter; }
1749+ if( lnbs != NULL ){ *lnbs = Loadbullets; }
1750+ if( nbs != NULL ){ *nbs = bullets; }
1751+}
1752+
1753+//! @brief 武器の使用状況の取得
1754+//! @return 使用中:true 未使用:false
1755+bool weapon::GetUsingFlag()
1756+{
1757+ return usingflag;
1758+}
1759+
1760+//! @brief 武器を拾う
1761+//! @return 成功:0 失敗:1
1762+int weapon::Pickup()
1763+{
1764+ if( usingflag == true ){ return 1; }
1765+ usingflag = true;
1766+ return 0;
1767+}
1768+
1769+//! @brief 武器を捨てる
1770+//! @param x X座標
1771+//! @param y Y座標
1772+//! @param z Z座標
1773+//! @param rx 横軸回転
1774+//! @param speed 捨てる初速
1775+void weapon::Dropoff(float x, float y, float z, float rx, float speed)
1776+{
1777+ //表示する座標と角度を設定
1778+ move_x = cos(rx*-1 + (float)M_PI/2) * speed;
1779+ move_y = 0.0f;
1780+ move_z = sin(rx*-1 + (float)M_PI/2) * speed;
1781+ pos_x = x + cos(rx*-1 + (float)M_PI/2) * 5.0f;
1782+ pos_y = y + 16.0f + move_y;
1783+ pos_z = z + sin(rx*-1 + (float)M_PI/2) * 5.0f;
1784+ rotation_x = rx + (float)M_PI;
1785+
1786+ //未使用(未装備)に設定し、座標移動を有効に
1787+ usingflag = false;
1788+ motionflag = true;
1789+}
1790+
1791+//! @brief 発砲
1792+//! @return 成功:0 失敗:1
1793+//! @attention 連射間隔も考慮されます。
1794+//! @attention 関数が失敗するのは、いずれかの条件です。 「連射間隔に満たない」「リロード実行中」「弾がない」「無効な武器の種類が設定されている」
1795+int weapon::Shot()
1796+{
1797+ //クラスが設定されていなければ失敗
1798+ if( Param == NULL ){ return 1; }
1799+
1800+ //発射間隔に満たないか、リロード中か、弾が無ければ失敗
1801+ if( shotcnt > 0 ){ return 1; }
1802+ if( reloadcnt > 0 ){ return 1; }
1803+ if( Loadbullets == 0 ){ return 1; }
1804+
1805+ //設定値を取得
1806+ WeaponParameter ParamData;
1807+ if( Param->GetWeapon(id_parameter, &ParamData) == 1 ){ return 1; }
1808+
1809+ //武器が手榴弾ならば〜
1810+ if( id_parameter == ID_WEAPON_GRENADE ){
1811+ //弾を減らし、連射カウントを設定
1812+ bullets -= 1;
1813+ Loadbullets -= 1;
1814+ shotcnt = ParamData.blazings;
1815+
1816+ if( (bullets - Loadbullets) <= 0 ){ //(リロードしていない)弾が無くなれば、武器ごと消滅させる。
1817+ RenderFlag = false;
1818+ usingflag = false;
1819+ }
1820+ else if( Loadbullets <= 0 ){ //自動リロード
1821+ Loadbullets = 1;
1822+ }
1823+ return 0;
1824+ }
1825+
1826+ //弾を減らし、連射カウントを設定
1827+ Loadbullets -= 1;
1828+ bullets -= 1;
1829+ shotcnt = ParamData.blazings;
1830+ return 0;
1831+}
1832+
1833+//! @brief リロードを開始
1834+//! @return 成功:0 失敗:1
1835+//! @attention リロード時間も考慮されます。
1836+//! @attention 関数が失敗するのは、いずれかの条件です。 「リロード実行中」「弾がない」「無効な武器の種類が設定されている」
1837+int weapon::StartReload()
1838+{
1839+ //クラスが設定されていなければ失敗
1840+ if( Param == NULL ){ return 1; }
1841+
1842+ //リロード中か、弾が無ければ失敗
1843+ if( reloadcnt > 0 ){ return 1; }
1844+ if( (bullets - Loadbullets) == 0 ){ return 1; }
1845+
1846+ //武器の性能値を取得
1847+ WeaponParameter ParamData;
1848+ if( Param->GetWeapon(id_parameter, &ParamData) != 0 ){ return 1; }
1849+
1850+ //リロードカウントを設定
1851+ reloadcnt = ParamData.reloads + 1;
1852+ return 0;
1853+}
1854+
1855+//! @brief リロードを実行
1856+//! @attention StartReload()関数と異なり、瞬時に弾を補充します。リロード時間は考慮されません。
1857+//! @attention リロード時間を考慮する場合、StartReload()関数を呼び出してください。この関数は自動的に実行されます。
1858+int weapon::RunReload()
1859+{
1860+ //クラスが設定されていなければ失敗
1861+ if( Param == NULL ){ return 1; }
1862+
1863+ //弾が無ければ失敗
1864+ if( (bullets - Loadbullets) == 0 ){ return 1; }
1865+
1866+ //武器の性能値から、装填する弾数を取得
1867+ WeaponParameter ParamData;
1868+ int nbsmax = 0;
1869+ if( Param->GetWeapon(id_parameter, &ParamData) == 0 ){
1870+ nbsmax = ParamData.nbsmax;
1871+ }
1872+
1873+ if( (bullets - Loadbullets) < nbsmax ){ //残りの弾数より装填する弾数が多ければ
1874+ bullets = (bullets - Loadbullets);
1875+ Loadbullets = bullets;
1876+ }
1877+ else{ //残りの弾数の方が多ければ
1878+ bullets -= Loadbullets;
1879+ Loadbullets = nbsmax;
1880+ }
1881+
1882+ return 0;
1883+}
1884+
1885+//! @brief リロードカウントを取得
1886+//! @return カウント数 (リロード中:1以上)
1887+int weapon::GetReloadCnt()
1888+{
1889+ return reloadcnt;
1890+}
1891+
1892+//! @brief 武器の種類・装弾数の変更
1893+//! @param Resource ResourceManagerのポインタ
1894+//! @param id_param 種類番号
1895+//! @param lnbs 装弾数
1896+//! @param nbs 合計弾数
1897+//! @return 成功:1 失敗:0
1898+//! @attention プレイヤーによる裏技(F6・F7)用に用意された関数です。手榴弾が選択された場合、自動的に弾を補充します。
1899+//! @attention 使用されていない武器オブジェクトに対して実行すると、この関数は失敗します。
1900+bool weapon::ResetWeaponParam(class ResourceManager *Resource, int id_param, int lnbs, int nbs)
1901+{
1902+ //初期化されていなければ、失敗
1903+ if( RenderFlag == false ){ return 0; }
1904+
1905+ //指定された設定値へ上書き
1906+ id_parameter = id_param;
1907+ bullets = nbs;
1908+ Loadbullets = lnbs;
1909+
1910+ //もし手榴弾ならば、自動リロード
1911+ if( id_param == ID_WEAPON_GRENADE ){
1912+ if( (bullets > 0)&&(Loadbullets == 0) ){
1913+ Loadbullets = 1;
1914+ }
1915+ }
1916+
1917+ //モデルとテクスチャを設定
1918+ Resource->GetWeaponModelTexture(id_param, &id_model, &id_texture);
1919+ WeaponParameter param;
1920+ if( Param->GetWeapon(id_param, &param) == 0 ){
1921+ model_size = param.size;
1922+ }
1923+
1924+ return 1;
1925+}
1926+
1927+//! @brief 計算を実行(自由落下)
1928+//! @param CollD Collisionのポインタ
1929+int weapon::RunFrame(class Collision *CollD)
1930+{
1931+ //クラスが設定されていなければ失敗
1932+ if( CollD == NULL ){ return 0; }
1933+
1934+ //初期化されていなければ、失敗
1935+ if( RenderFlag == false ){ return 0; }
1936+
1937+ //連射カウントが残っていれば、1 減らす
1938+ if( shotcnt > 0 ){
1939+ shotcnt -= 1;
1940+ }
1941+ else if( reloadcnt > 0 ){
1942+ //リロードカウントが残っていれば 1 減らし、カウントが 0 ならばリロード処理を実行
1943+ reloadcnt -= 1;
1944+ if( reloadcnt == 0 ){
1945+ RunReload();
1946+ }
1947+ }
1948+
1949+ //誰にも使われておらず、移動フラグが有効ならば〜
1950+ if( (usingflag == false)&&(motionflag == true) ){
1951+ float Dist;
1952+ float maxDist;
1953+
1954+ //移動速度を更新
1955+ move_x *= 0.96f;
1956+ move_z *= 0.96f;
1957+ if( move_y > -1.8f ){
1958+ move_y -= 0.3f;
1959+ }
1960+
1961+ //ブロックに埋まっていれば処理しない
1962+ if( CollD->CheckALLBlockInside(pos_x, pos_y, pos_z) == true ){
1963+ motionflag = false;
1964+ return 0;
1965+ }
1966+
1967+ //水平の移動速度を求める
1968+ maxDist = sqrt(move_x*move_x + move_z*move_z);
1969+ if( maxDist < 0.1f ){
1970+ maxDist = 0.0f;
1971+ move_x = 0.0f;
1972+ move_z = 0.0f;
1973+ }
1974+
1975+ //ブロックに接していれば、それ以上は水平移動しない。
1976+ if( maxDist > 0.0f ){
1977+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y, pos_z, move_x/maxDist, 0, move_z/maxDist, NULL, NULL, &Dist, maxDist) == true ){
1978+ //ブロックに埋まらないように手前に
1979+ Dist -= 0.1f;
1980+
1981+ //接している座標まで移動
1982+ pos_x += move_x/maxDist * Dist;
1983+ pos_z += move_z/maxDist * Dist;
1984+
1985+ //移動量を 0 に
1986+ move_x = 0.0f;
1987+ move_z = 0.0f;
1988+ }
1989+ }
1990+
1991+ //ブロックに接していれば、そこまで落下する
1992+ if( CollD->CheckALLBlockIntersectDummyRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, abs(move_y)) == true ){
1993+ CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, abs(move_y));
1994+ pos_y -= Dist - 0.2f;
1995+ motionflag = false;
1996+ return 0;
1997+ }
1998+
1999+ //座標を反映
2000+ pos_x += move_x;
2001+ pos_y += move_y;
2002+ pos_z += move_z;
2003+ }
2004+
2005+ return 0;
2006+}
2007+
2008+//! @brief 描画
2009+//! @param d3dg D3DGraphicsのポインタ
2010+void weapon::Render(class D3DGraphics *d3dg)
2011+{
2012+ //クラスが設定されていなければ失敗
2013+ if( d3dg == NULL ){ return; }
2014+
2015+ //初期化されてないか、誰かに使われていれば処理しない
2016+ if( RenderFlag == false ){ return; }
2017+ if( usingflag == true ){ return; }
2018+
2019+ //武器を描画
2020+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, 0.0f, (float)M_PI/2, model_size);
2021+ d3dg->RenderModel(id_model, id_texture);
2022+}
2023+
2024+//! @brief コンストラクタ
2025+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)
2026+{
2027+ Param = in_Param;
2028+ MIFdata = in_MIFdata;
2029+ pos_x = x;
2030+ pos_y = y;
2031+ pos_z = z;
2032+ rotation_x = rx;
2033+ rotation_y = 0.0f;
2034+ RenderFlag = flag;
2035+ model_size = 5.0f;
2036+
2037+ id_parameter = id_param;
2038+ point_p4 = p4;
2039+
2040+ hp = 0; //暫定
2041+ jump_rx = 0.0f;
2042+ move_rx = 0.0f;
2043+ add_rx = 0.0f;
2044+ add_ry = 0.0f;
2045+ jump_cnt = 0;
2046+
2047+ if( Param != NULL ){
2048+ SmallObjectParameter ParamData;
2049+ if( Param->GetSmallObject(id_param, &ParamData) == 0 ){
2050+ hp = ParamData.hp;
2051+ }
2052+ }
2053+ id_model = -1;
2054+ id_texture = -1;
2055+}
2056+
2057+//! @brief ディストラクタ
2058+smallobject::~smallobject()
2059+{}
2060+
2061+//! @brief MIFデータを管理するクラスを設定
2062+//! @param in_MIFdata MIFInterfaceクラスのポインタ
2063+void smallobject::SetMIFInterfaceClass(class MIFInterface *in_MIFdata)
2064+{
2065+ MIFdata = in_MIFdata;
2066+}
2067+
2068+//! @brief 設定値を設定
2069+//! @param id_param 小物の種類番号
2070+//! @param p4 第4パラメータ
2071+//! @param init オブジェクトを初期化
2072+void smallobject::SetParamData(int id_param, signed char p4, bool init)
2073+{
2074+ rotation_y = 0.0f;
2075+ id_parameter = id_param;
2076+ point_p4 = p4;
2077+
2078+ if( init == true ){
2079+ hp = 0; //暫定
2080+ jump_rx = 0.0f;
2081+ move_rx = 0.0f;
2082+ add_rx = 0.0f;
2083+ add_ry = 0.0f;
2084+ jump_cnt = 0;
2085+
2086+ if( id_param == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
2087+ if( MIFdata != NULL ){
2088+ hp = MIFdata->GetAddSmallobjectHP();
2089+ }
2090+ }
2091+ else{
2092+ if( Param != NULL ){
2093+ SmallObjectParameter ParamData;
2094+ if( Param->GetSmallObject(id_param, &ParamData) == 0 ){
2095+ hp = ParamData.hp;
2096+ }
2097+ }
2098+ }
2099+ }
2100+}
2101+
2102+//! @brief 設定値を取得
2103+//! @param id_param 小物の種類番号を受け取るポインタ(NULL可)
2104+//! @param p4 第4パラメータを受け取るポインタ(NULL可)
2105+void smallobject::GetParamData(int *id_param, signed char *p4)
2106+{
2107+ if( id_param != NULL ){ *id_param = id_parameter; }
2108+ if( p4 != NULL ){ *p4 = point_p4; }
2109+}
2110+
2111+//! @brief 体力を取得
2112+//! @return 体力値
2113+int smallobject::GetHP()
2114+{
2115+ return hp;
2116+}
2117+
2118+//! @brief ブロックの上に移動
2119+//! @param CollD Collisionのポインタ
2120+//! @return 元の座標からの移動量(0で移動なし)
2121+float smallobject::CollisionMap(class Collision *CollD)
2122+{
2123+ //クラスが設定されていなければ失敗
2124+ if( CollD == NULL ){ return 0.0f; }
2125+
2126+ float Dist;
2127+ SmallObjectParameter ParamData;
2128+
2129+ //ブロックに埋まっていれば、そのまま
2130+ if( CollD->CheckALLBlockInside(pos_x, pos_y, pos_z) == true ){ return 0.0f; }
2131+
2132+ //下方向に当たり判定
2133+ if( CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, 0, -1, 0, NULL, NULL, &Dist, 1000.0f) == true ){
2134+ //当たり判定の大きさを取得
2135+ if( id_parameter == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
2136+ Dist -= (float)MIFdata->GetAddSmallobjectDecide()/10.0f;
2137+ }
2138+ else{
2139+ if( Param->GetSmallObject(id_parameter, &ParamData) == 0 ){
2140+ Dist -= (float)ParamData.decide/10.0f;
2141+ }
2142+ }
2143+
2144+ //座標を移動する
2145+ pos_y -= Dist;
2146+ return Dist;
2147+ }
2148+
2149+ return 0.0f;
2150+}
2151+
2152+//! @brief 弾がヒットした
2153+//! @param attacks 弾の攻撃力
2154+void smallobject::HitBullet(int attacks)
2155+{
2156+ hp -= attacks;
2157+ if( hp <= 0 ){
2158+ Destruction();
2159+ }
2160+}
2161+
2162+//! @brief 手榴弾の爆風がヒットした
2163+//! @param attacks 爆風の攻撃力
2164+//! @attention 距離による計算を事前に済ませてください。
2165+void smallobject::HitGrenadeExplosion(int attacks)
2166+{
2167+ hp -= attacks;
2168+ if( hp <= 0 ){
2169+ Destruction();
2170+ }
2171+}
2172+
2173+//! @brief 小物を破壊する
2174+//! @attention 通常は HitBullet()関数 および GrenadeExplosion()関数 から自動的に実行されるため、直接呼び出す必要はありません。
2175+void smallobject::Destruction()
2176+{
2177+ //RenderFlag = false;
2178+ //return;
2179+
2180+ //小物の設定値を取得
2181+ SmallObjectParameter paramdata;
2182+ Param->GetSmallObject(id_parameter, &paramdata);
2183+
2184+ //飛ばす
2185+ hp = 0;
2186+ jump_cnt = paramdata.jump;
2187+
2188+ //姿勢設定
2189+ jump_rx = (float)M_PI/18 * GetRand(36);
2190+ move_rx = (float)paramdata.jump * 0.04243f;
2191+ add_rx = (float)M_PI/180 * GetRand(20);
2192+ add_ry = (float)M_PI/180 * GetRand(20);
2193+}
2194+
2195+//! @brief 計算を実行(破壊時の移動など)
2196+int smallobject::RunFrame()
2197+{
2198+ //描画されていないか、体力が残っていなければ処理しない。
2199+ if( RenderFlag == false ){ return 0; }
2200+ if( hp > 0 ){ return 0; }
2201+
2202+ int cnt;
2203+ SmallObjectParameter paramdata;
2204+
2205+ //吹き飛んでいるカウント数を計算
2206+ cnt = Param->GetSmallObject(id_parameter, &paramdata) - jump_cnt;
2207+
2208+ //姿勢から座標・角度を計算
2209+ pos_x += cos(jump_rx) * move_rx;
2210+ pos_y += jump_cnt * 0.1f;
2211+ pos_z += sin(jump_rx) * move_rx;
2212+ rotation_x += add_rx;
2213+ rotation_y += add_ry;
2214+
2215+ jump_cnt -= 1;
2216+
2217+ //1秒飛んでいたら描画終了
2218+ if( cnt > (int)GAMEFPS ){
2219+ RenderFlag = false;
2220+ return 2;
2221+ }
2222+
2223+ return 1;
2224+}
2225+
2226+//! @brief 描画
2227+//! @param d3dg D3DGraphicsのポインタ
2228+void smallobject::Render(D3DGraphics *d3dg)
2229+{
2230+ //クラスが設定されていなければ失敗
2231+ if( d3dg == NULL ){ return; }
2232+
2233+ //初期化されていなければ処理しない。
2234+ if( RenderFlag == false ){ return; }
2235+
2236+ //描画
2237+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, rotation_y, model_size);
2238+ d3dg->RenderModel(id_model, id_texture);
2239+}
2240+
2241+//! @brief コンストラクタ
2242+bullet::bullet(int modelid, int textureid)
2243+{
2244+ model_size = 1.0f;
2245+ id_model = modelid;
2246+ id_texture = textureid;
2247+ RenderFlag = false;
2248+}
2249+
2250+//! @brief ディストラクタ
2251+bullet::~bullet()
2252+{}
2253+
2254+//! @brief 座標と角度を設定
2255+//! @param x X座標
2256+//! @param y Y座標
2257+//! @param z Z座標
2258+//! @param rx 横軸回転
2259+//! @param ry 縦軸回転
2260+void bullet::SetPosData(float x, float y, float z, float rx, float ry)
2261+{
2262+ pos_x = x;
2263+ pos_y = y;
2264+ pos_z = z;
2265+ rotation_x = rx;
2266+ rotation_y = ry;
2267+}
2268+
2269+//! @brief 設定値を設定
2270+//! @param _attacks 攻撃力
2271+//! @param _penetration 貫通力
2272+//! @param _speed 弾速
2273+//! @param _teamid チーム番号
2274+//! @param _humanid 人のデータ番号
2275+//! @param init オブジェクトを初期化
2276+void bullet::SetParamData(int _attacks, int _penetration, int _speed, int _teamid, int _humanid, bool init)
2277+{
2278+ attacks = _attacks;
2279+ penetration = _penetration;
2280+ speed = _speed;
2281+ teamid = _teamid;
2282+ humanid = _humanid;
2283+
2284+ if( init == true ){
2285+ cnt = 0;
2286+ }
2287+}
2288+
2289+//! @brief 座標と角度を取得
2290+//! @param x X座標を受け取るポインタ(NULL可)
2291+//! @param y Y座標を受け取るポインタ(NULL可)
2292+//! @param z Z座標を受け取るポインタ(NULL可)
2293+//! @param rx 横軸回転を受け取るポインタ(NULL可)
2294+//! @param ry 縦軸回転を受け取るポインタ(NULL可)
2295+void bullet::GetPosData(float *x, float *y, float *z, float *rx, float *ry)
2296+{
2297+ if( x != NULL ){ *x = pos_x; }
2298+ if( y != NULL ){ *y = pos_y; }
2299+ if( z != NULL ){ *z = pos_z; }
2300+ if( rx != NULL ){ *rx = rotation_x; }
2301+ if( ry != NULL ){ *ry = rotation_y; }
2302+}
2303+
2304+//! @brief 設定値を取得
2305+//! @param _attacks 攻撃力を受け取るポインタ(NULL可)
2306+//! @param _penetration 貫通力を受け取るポインタ(NULL可)
2307+//! @param _speed 弾速を受け取るポインタ(NULL可)
2308+//! @param _teamid チーム番号を受け取るポインタ(NULL可)
2309+//! @param _humanid 人のデータ番号を受け取るポインタ(NULL可)
2310+void bullet::GetParamData(int *_attacks, int *_penetration, int *_speed, int *_teamid, int *_humanid)
2311+{
2312+ if( _attacks != NULL ){ *_attacks = attacks; }
2313+ if( _penetration != NULL ){ *_penetration = penetration; }
2314+ if( _speed != NULL ){ *_speed = speed; }
2315+ if( _teamid != NULL ){ *_teamid = teamid; }
2316+ if( _humanid != NULL ){ *_humanid = humanid; }
2317+}
2318+
2319+//! @brief 計算を実行(弾の進行・時間消滅)
2320+int bullet::RunFrame()
2321+{
2322+ //初期化されていなければ処理しない
2323+ if( RenderFlag == false ){ return 0; }
2324+
2325+ //消滅時間を過ぎていれば、オブジェクトを無効化
2326+ if( cnt > BULLET_DESTROYFRAME ){
2327+ RenderFlag = false;
2328+ return 0;
2329+ }
2330+
2331+ //移動処理
2332+ pos_x += cos(rotation_x)*cos(rotation_y)*speed;
2333+ pos_y += sin(rotation_y)*speed;
2334+ pos_z += sin(rotation_x)*cos(rotation_y)*speed;
2335+ cnt += 1;
2336+
2337+ return 0;
2338+}
2339+
2340+//! @brief 描画
2341+//! @param d3dg D3DGraphicsのポインタ
2342+void bullet::Render(class D3DGraphics *d3dg)
2343+{
2344+ //クラスが設定されていなければ失敗
2345+ if( d3dg == NULL ){ return; }
2346+
2347+ //初期化されていなければ処理しない。
2348+ if( RenderFlag == false ){ return; }
2349+
2350+ //弾を移動前だったら描画しない
2351+ // 弾が頭から突き抜けて見える対策
2352+ if( cnt == 0 ){ return; }
2353+
2354+ //描画
2355+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), rotation_y, model_size);
2356+ d3dg->RenderModel(id_model, id_texture);
2357+}
2358+
2359+//! @brief コンストラクタ
2360+grenade::grenade(int modelid, int textureid) : bullet(modelid, textureid)
2361+{
2362+ if( Param != NULL ){
2363+ WeaponParameter ParamData;
2364+ if( Param->GetWeapon(ID_WEAPON_GRENADE, &ParamData) == 0 ){
2365+ model_size = ParamData.size;
2366+ }
2367+ }
2368+}
2369+
2370+//! @brief ディストラクタ
2371+grenade::~grenade()
2372+{}
2373+
2374+//! @brief 座標と情報を設定
2375+//! @param speed 初速
2376+//! @param _humanid 人のデータ番号
2377+//! @param init オブジェクトを初期化
2378+//! @attention 先に SetPosData() を実行してください。
2379+void grenade::SetParamData(float speed, int _humanid, bool init)
2380+{
2381+ move_x = cos(rotation_x) * cos(rotation_y) * speed;
2382+ move_y = sin(rotation_y) * speed;
2383+ move_z = sin(rotation_x) * cos(rotation_y) * speed;
2384+ humanid = _humanid;
2385+
2386+ if( init == true ){
2387+ cnt = 0;
2388+ }
2389+}
2390+
2391+//! @brief 速度を取得
2392+//! @return 速度
2393+float grenade::GetSpeed()
2394+{
2395+ return sqrt(move_x*move_x + move_y*move_y + move_z*move_z);
2396+}
2397+
2398+//! @brief 計算を実行(手榴弾の進行・爆発)
2399+//! @return 爆発:2 バウンド・跳ね返り:1 それ以外:0
2400+int grenade::RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata)
2401+{
2402+ //初期化されていなければ処理しない
2403+ if( RenderFlag == false ){ return 0; }
2404+
2405+ //時間を過ぎていれば、オブジェクトを無効化し、「爆発」として返す。
2406+ if( cnt > GRENADE_DESTROYFRAME ){
2407+ RenderFlag = false;
2408+ return 2;
2409+ }
2410+
2411+ //静止していれば処理しない
2412+ if( (move_x == 0.0f)&&(move_y == 0.0f)&&(move_z == 0.0f) ){
2413+ cnt += 1;
2414+ return 0;
2415+ }
2416+
2417+ /*
2418+ //静止に近い状態ならば、移動処理をしない。
2419+ if( (move_x*move_x + move_y*move_y + move_z*move_z) < 0.1f*0.1f ){
2420+ cnt += 1;
2421+ return 0;
2422+ }
2423+ */
2424+
2425+ //移動速度を計算
2426+ move_x *= 0.98f;
2427+ move_y = (move_y - 0.17f) * 0.98f;
2428+ move_z *= 0.98f;
2429+
2430+ int id, face;
2431+ float Dist;
2432+ float maxDist = sqrt(move_x*move_x + move_y*move_y + move_z*move_z);
2433+
2434+ //マップに対して当たり判定を実行
2435+ if( CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, move_x/maxDist, move_y/maxDist, move_z/maxDist, &id, &face, &Dist, maxDist) == true ){
2436+ float vx, vy, vz;
2437+
2438+ //マップと衝突する座標まで移動
2439+ pos_x += move_x/maxDist * (Dist - 0.1f);
2440+ pos_y += move_y/maxDist * (Dist - 0.1f);
2441+ pos_z += move_z/maxDist * (Dist - 0.1f);
2442+
2443+ //反射するベクトルを求める
2444+ CollD->ReflectVector(inblockdata, id, face, move_x, move_y, move_z, &vx, &vy, &vz);
2445+
2446+ //減速
2447+ move_x = vx * GRENADE_BOUND_ACCELERATION;
2448+ move_y = vy * GRENADE_BOUND_ACCELERATION;
2449+ move_z = vz * GRENADE_BOUND_ACCELERATION;
2450+
2451+ cnt += 1;
2452+ return 1;
2453+ }
2454+
2455+ //座標を移動
2456+ pos_x += move_x;
2457+ pos_y += move_y;
2458+ pos_z += move_z;
2459+
2460+ cnt += 1;
2461+ return 0;
2462+}
2463+
2464+//! @brief 描画
2465+//! @param d3dg D3DGraphicsのポインタ
2466+void grenade::Render(class D3DGraphics *d3dg)
2467+{
2468+ //クラスが設定されていなければ失敗
2469+ if( d3dg == NULL ){ return; }
2470+
2471+ //初期化されていなければ処理しない。
2472+ if( RenderFlag == false ){ return; }
2473+
2474+ //描画
2475+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), 0.0f, (float)M_PI/2, model_size);
2476+ d3dg->RenderModel(id_model, id_texture);
2477+}
2478+
2479+//! @brief コンストラクタ
2480+effect::effect(float x, float y, float z, float size, float rotation, int count, int texture, int settype)
2481+{
2482+ pos_x = x;
2483+ pos_y = y;
2484+ pos_z = z;
2485+ model_size = size;
2486+ camera_rx = 0.0f;
2487+ camera_ry = 0.0f;
2488+ rotation_x = rotation;
2489+ cnt = count;
2490+ setcnt = count;
2491+ id_texture = texture;
2492+ type = settype;
2493+ if( cnt > 0 ){
2494+ RenderFlag = true;
2495+ }
2496+ else{
2497+ RenderFlag = false;
2498+ }
2499+ alpha = 1.0f;
2500+}
2501+
2502+//! @brief ディストラクタ
2503+effect::~effect()
2504+{}
2505+
2506+//! @brief 設定値を設定
2507+//! @param in_move_x X軸移動量
2508+//! @param in_move_y Y軸移動量
2509+//! @param in_move_z Z軸移動量
2510+//! @param size 表示倍率
2511+//! @param rotation 回転角度
2512+//! @param count 表示フレーム数
2513+//! @param texture テクスチャの認識番号
2514+//! @param settype エフェクトの種類 (Effect_Type を組み合せる)
2515+//! @param init オブジェクトを初期化
2516+void effect::SetParamData(float in_move_x, float in_move_y, float in_move_z, float size, float rotation, int count, int texture, int settype, bool init)
2517+{
2518+ move_x = in_move_x;
2519+ move_y = in_move_y;
2520+ move_z = in_move_z;
2521+ model_size = size;
2522+ rotation_texture = rotation;
2523+ cnt = count;
2524+ setcnt = count;
2525+ id_texture = texture;
2526+ type = settype;
2527+ alpha = 1.0f;
2528+
2529+ if( init == true ){
2530+ camera_rx = 0.0f;
2531+ camera_ry = 0.0f;
2532+ }
2533+}
2534+
2535+//! @brief 計算を実行(ビルボード化)
2536+//! @param in_camera_rx カメラの横軸角度
2537+//! @param in_camera_ry カメラの縦軸角度
2538+//! @return 処理実行:1 描画最終フレーム:2 処理なし:0
2539+int effect::RunFrame(float in_camera_rx, float in_camera_ry)
2540+{
2541+ //初期化されていなければ処理しない
2542+ if( RenderFlag == false ){ return 0; }
2543+
2544+ //カウントが終了したら、処理しないように設定
2545+ if( cnt <= 0 ){
2546+ RenderFlag = false;
2547+ return 2;
2548+ }
2549+
2550+ //カメラ座標を適用
2551+ camera_rx = in_camera_rx;
2552+ camera_ry = in_camera_ry;
2553+
2554+ //座標移動
2555+ pos_x += move_x;
2556+ pos_y += move_y;
2557+ pos_z += move_z;
2558+
2559+ //特殊処理を実行
2560+ if( type & EFFECT_DISAPPEAR ){ //消す
2561+ alpha -= 1.0f/setcnt;
2562+ }
2563+ if( type & EFFECT_MAGNIFY ){ //拡大
2564+ model_size += model_size/50;
2565+ }
2566+ if( type & EFFECT_ROTATION ){ //回転
2567+ if( rotation_texture > 0.0f ){
2568+ rotation_texture += (float)M_PI/180*1;
2569+ }
2570+ else{
2571+ rotation_texture -= (float)M_PI/180*1;
2572+ }
2573+ }
2574+ if( type & EFFECT_FALL ){ //落下
2575+ move_y = (move_y - 0.17f) * 0.98f;
2576+ }
2577+
2578+ //カウントを 1 引く
2579+ cnt -= 1;
2580+ return 1;
2581+}
2582+
2583+//! @brief 描画
2584+//! @param d3dg D3DGraphicsのポインタ
2585+void effect::Render(class D3DGraphics *d3dg)
2586+{
2587+ //クラスが設定されていなければ失敗
2588+ if( d3dg == NULL ){ return; }
2589+
2590+ //初期化されていなければ処理しない。
2591+ if( RenderFlag == false ){ return; }
2592+
2593+ //描画
2594+ d3dg->SetWorldTransformEffect(pos_x, pos_y, pos_z, camera_rx*-1, camera_ry, rotation_texture, model_size);
2595+ d3dg->RenderBoard(id_texture, alpha);
2596+}
\ No newline at end of file
--- tags/v1.010-20150220/objectmanager.h (nonexistent)
+++ tags/v1.010-20150220/objectmanager.h (revision 45)
@@ -0,0 +1,152 @@
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+ bool *Human_ShotFlag; //!< 発砲フラグ(マズルフラッシュ用)
77+
78+ int Player_HumanID; //!< プレイヤーが操作する人オブジェクトのID
79+
80+ int AddHumanIndex_TextureID; //!< 前回読み込んだテクスチャID
81+
82+ ParameterInfo *GameParamInfo; //!< ゲームの設定値
83+ D3DGraphics *d3dg; //!< 描画クラス
84+ ResourceManager *Resource; //!< リソース管理
85+ BlockDataInterface *BlockData; //!< ブロックデータ管理クラス
86+ PointDataInterface *PointData; //!< ポイントデータ管理クラス
87+ Collision *CollD; //!< 当たり判定管理クラス
88+ SoundManager *GameSound; //!< ゲーム効果音管理クラス
89+ MIFInterface *MIFdata; //!< MIFコントロールクラス
90+
91+ int AddHumanIndex(pointdata data, pointdata infodata);
92+ int AddWeaponIndex(pointdata data);
93+ int AddSmallObjectIndex(pointdata data);
94+ void SetHumanBlood(float x, float y, float z);
95+ bool CollideHuman(human *in_humanA, human *in_humanB);
96+ bool CollideBullet(bullet *in_bullet);
97+ void HitBulletMap(float x, float y, float z);
98+ void HitBulletHuman(int HitHuman_id, int Hit_id, float x, float y, float z, float brx, int attacks, int humanid);
99+ void HitBulletSmallObject(int HitSmallObject_id, float x, float y, float z, int attacks);
100+ bool GrenadeExplosion(grenade *in_grenade);
101+ void DeadEffect(human *in_human);
102+ void PickupWeapon(human *in_human, weapon *in_weapon);
103+ void CleanupPointDataToObject();
104+ int SortEffect(float camera_x, float camera_y, float camera_z, effectdata data[]);
105+ void ShotWeaponEffect(int humanid);
106+
107+public:
108+ ObjectManager();
109+ ~ObjectManager();
110+ 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);
111+ int AddHumanIndex(float px, float py, float pz, float rx, int CharacterID, int TeamID, int WeaponID[]);
112+ int AddVisualWeaponIndex(int WeaponID, bool loadbullet);
113+ int AddSmallObjectIndex(float px, float py, float pz, float rx, int paramID, bool MapColl);
114+ int AddEffect(float pos_x, float pos_y, float pos_z, float move_x, float move_y, float move_z, float size, float rotation, int count, int texture, int settype);
115+ void LoadPointData();
116+ int GetPlayerID();
117+ void SetPlayerID(int id);
118+ human* GeHumanObject(int id);
119+ human* GetPlayerHumanObject();
120+ weapon* GetWeaponObject(int id);
121+ smallobject* GetSmallObject(int id);
122+ bullet* GetBulletObject(int id);
123+ bullet* GetNewBulletObject();
124+ grenade* GetNewGrenadeObject();
125+ human* SearchHuman(signed char p4);
126+ smallobject* SearchSmallobject(signed char p4);
127+ void MoveForward(int human_id);
128+ void MoveBack(int human_id);
129+ void MoveLeft(int human_id);
130+ void MoveRight(int human_id);
131+ void MoveWalk(int human_id);
132+ void MoveJump(int human_id);
133+ int ShotWeapon(int human_id);
134+ void ReloadWeapon(int human_id);
135+ void ChangeWeapon(int human_id, int id = -1);
136+ bool DumpWeapon(int human_id);
137+ void ChangeScopeMode(int human_id);
138+ int ChangeShotMode(int human_id);
139+ bool CheatAddBullet(int human_id);
140+ bool CheatNewWeapon(int human_id, int new_weaponID);
141+ bool CheckZombieAttack(human* MyHuman, human* EnemyHuman);
142+ void HitZombieAttack(human* EnemyHuman);
143+ bool HumanResuscitation(int id);
144+ int CheckGameOverorComplete();
145+ bool GetObjectInfoTag(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, int *color, char *infostr);
146+ int Process(int cmdF5id, float camera_rx, float camera_ry);
147+ bool GetHumanShotInfo(int id, int *ontarget, int *kill, int *headshot);
148+ void Render(float camera_x, float camera_y, float camera_z, int HidePlayer);
149+ void Cleanup();
150+};
151+
152+#endif
\ No newline at end of file
--- tags/v1.010-20150220/object.h (nonexistent)
+++ tags/v1.010-20150220/object.h (revision 45)
@@ -0,0 +1,362 @@
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_ACCELERATION 0.7f //!< 人の前進(走り)加速度
37+#define HUMAN_SIDEWAYSRUN_ACCELERATION 0.5f //!< 人の横走り加速度
38+#define HUMAN_REGRESSRUN_ACCELERATION 0.38f //!< 人の後退加速度
39+//! 人が斜め前に進む加速度
40+#define HUMAN_PROGRESSRUN_SIDEWAYSRUN_ACCELERATION ((HUMAN_PROGRESSRUN_ACCELERATION + HUMAN_SIDEWAYSRUN_ACCELERATION) / 2)
41+//! 人が斜め後ろに進む加速度
42+#define HUMAN_REGRESSRUN_SIDEWAYSRUN_ACCELERATION (HUMAN_REGRESSRUN_ACCELERATION)
43+#define HUMAN_PROGRESSWALK_ACCELERATION 0.35f //!< 人が歩く加速度
44+#define HUMAN_ATTENUATION 0.5f //!< 人の1フレーム当たりの減衰率 (0.0 < x < 1.0)
45+
46+#define HUMAN_JUMP_SPEED (2.2f + (HUMAN_DAMAGE_SPEED)) //!< ジャンプする速度
47+
48+#define HUMAN_HEIGTH 20.0f //!< 人の高さ
49+#define HUMAN_DAMAGE_HEAD 2.0f //!< 弾が 頭 に当たった場合のダメージ倍率
50+#define HUMAN_DAMAGE_UP 1.0f //!< 弾が 上半身 に当たった場合のダメージ倍率
51+#define HUMAN_DAMAGE_LEG 0.7f //!< 弾が 下半身 に当たった場合のダメージ倍率
52+#define HUMAN_DAMAGE_ZOMBIEU 15 //!< ゾンビの攻撃を受けた場合の最低ダメージ
53+#define HUMAN_DAMAGE_ZOMBIEA 5 //!< ゾンビの攻撃を受けた場合の追加ダメージ量
54+#define HUMAN_DAMAGE_SPEED (0.066f + 0.132f) //!< 落下量
55+#define HUMAN_DAMAGE_MINSPEED -3.8f //!< 落下によりダメージを受けない速度
56+#define HUMAN_DAMAGE_MAXSPEED -7.0f //!< 最大落下速度
57+#define HUMAN_DAMAGE_MAXFALL 120 //!< 落下による最大ダメージ
58+#define MAX_DAMAGE_GRENADE_DISTANCE 80.0f //!< 手榴弾によりダメージを受ける最大距離
59+#define HUMAN_DAMAGE_GRENADE_HEAD 100 //!< 手榴弾による 頭 への最大ダメージ
60+#define HUMAN_DAMAGE_GRENADE_LEG 80 //!< 手榴弾による 足 への最大ダメージ
61+#define SMALLOBJECT_DAMAGE_GRENADE 80 //!< 手榴弾による 小物 への最大ダメージ
62+
63+#define WEAPONERRORRANGE_SCALE 0.25f //!< 武器の反動角度の倍率(×0.25 = ÷4)
64+
65+#define ARMRAD_NOWEAPON ((float)M_PI/2*-1 + (float)M_PI/9) //!< 手ぶら時の腕の表示角度
66+#define ARMRAD_RELOADWEAPON ((float)M_PI/18*2 * -1) //!< リロード時の腕の表示角度
67+
68+#define HUMAN_MAPCOLLISION_R 5.0f //!< 人とマップの当たり判定 半径
69+#define HUMAN_MAPCOLLISION_HEIGTH 10.2f //!< 人とマップの当たり判定 高さ(注:腰程度)
70+#define HUMAN_MAPCOLLISION_SLOPEANGLE ((float)M_PI/18*5) //!< 人とマップの当たり判定 登れない斜面の角度
71+#define HUMAN_MAPCOLLISION_SLOPEFORCE 1.0f //!< 人とマップの当たり判定 登れない斜面が人を押し出す力
72+#define HUMAN_DEADLINE -100.0f //!< 人が死亡するY座標(デッドライン)
73+
74+#define BULLET_SPEEDSCALE 3 //!< 弾速の倍率
75+#define BULLET_DESTROYFRAME 40 //!< 弾の消滅フレーム数
76+#define GRENADE_DESTROYFRAME 100 //!< 手榴弾の爆発フレーム数
77+#define GRENADE_BOUND_ACCELERATION ((0.63662f * 0.4f - 0.7f) * -1) //!< 手榴弾の反射減衰率
78+
79+#ifndef H_LAYERLEVEL
80+ #define H_LAYERLEVEL 2 //!< Select include file.
81+#endif
82+#include "main.h"
83+
84+#define HUMAN_DEADBODY_COLLISION //!< @brief 人が倒れる際にマップと当たり判定を実施するか @details 定数宣言有効:当たり判定を実施 定数宣言無効(コメント化):そのまま倒すだけ
85+
86+//! @brief オブジェクト管理クラス(基底クラス)
87+//! @details 3Dで座標管理や描画を行うオブジェクト全般を管理するクラス群の基底クラスです。
88+class object
89+{
90+protected:
91+ class ParameterInfo *Param; //!< 設定値を管理するクラスへのポインタ
92+ float pos_x; //!< X座標
93+ float pos_y; //!< Y座標
94+ float pos_z; //!< Z座標
95+ float rotation_x; //!< 回転角度
96+ float model_size; //!< 表示サイズ
97+ int id_parameter; //!< データの種類
98+ int id_model; //!< モデル認識番号
99+ int id_texture; //!< テクスチャ認識番号
100+ bool RenderFlag; //!< 表示フラグ
101+
102+public:
103+ 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);
104+ ~object();
105+ virtual void SetParameterInfoClass(class ParameterInfo *in_Param);
106+ virtual void SetPosData(float x, float y, float z, float rx);
107+ virtual void GetPosData(float *x, float *y, float *z, float *rx);
108+ virtual void SetDrawFlag(bool flag);
109+ virtual bool GetDrawFlag();
110+ virtual void SetModel(int id, float size);
111+ virtual void SetTexture(int id);
112+ virtual int RunFrame();
113+ virtual void Render(class D3DGraphics *d3dg);
114+};
115+
116+//! @brief 人管理クラス
117+class human : public object
118+{
119+protected:
120+ int point_dataid; //!< ポイントのデータ番号
121+ signed char point_p4; //!< ポイントの認識番号
122+ int teamid; //!< チーム番号
123+ float move_x; //!< X軸速度
124+ float move_y; //!< Y軸(落下)速度
125+ float move_z; //!< Z軸速度
126+ bool move_y_flag; //!< Y軸移動フラグ
127+ float rotation_y; //!< 全体の回転角度
128+ float armrotation_y; //!< 腕の回転角度
129+ float reaction_y; //!< 腕を上げ下げする角度
130+ float legrotation_x; //!< 足の回転角度
131+ float upmodel_size; //!< 上半身表示サイズ
132+ float armmodel_size; //!< 腕表示サイズ
133+ float legmodel_size; //!< 足表示サイズ
134+ class weapon *weapon[TOTAL_HAVEWEAPON]; //!< 武器
135+ int selectweapon; //!< 武器A/Bの選択
136+ int selectweaponcnt; //!< 武器の切り替えカウント
137+ int hp; //!< 体力
138+#ifdef HUMAN_DEADBODY_COLLISION
139+ int deadstate; //!< 死体になっているか
140+#endif
141+ int id_upmodel; //!< 上半身
142+ int id_armmodel[TOTAL_ARMMODE]; //!< 腕
143+ int id_legmodel; //!< 足(静止)
144+ int id_walkmodel[TOTAL_WALKMODE]; //!< 足(歩く)
145+ int id_runmodel[TOTAL_RUNMODE]; //!< 足(走る)
146+ float move_rx; //!< 移動角度
147+ int MoveFlag; //!< 移動方向を表すフラグ
148+ int MoveFlag_lt; //!< (前回の)移動方向を表すフラグ
149+ int scopemode; //!< スコープ使用モード
150+ bool HitFlag; //!< 被弾を表すフラグ
151+ int walkcnt; //!< 歩くモーションのカウント
152+ int runcnt; //!< 走るモーションのカウント
153+ float totalmove; //!< 合計移動量
154+ int StateGunsightErrorRange; //!< 照準の状態誤差
155+ int ReactionGunsightErrorRange; //!< 照準の反動誤差
156+ bool Invincible; //!< 無敵フラグ
157+
158+ void GunsightErrorRange();
159+ int CheckAndProcessDead(class Collision *CollD);
160+ void ControlProcess();
161+ bool CheckBlockAngle(class BlockDataInterface *inblockdata, int bid, int fid, float vx, float vz);
162+ bool MapCollisionDetection(class Collision *CollD, class BlockDataInterface *inblockdata, float *FallDist);
163+
164+public:
165+ 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);
166+ ~human();
167+ virtual void SetParamData(int id_param, int dataid, signed char p4, int team, bool init);
168+ virtual void GetParamData(int *id_param, int *dataid, signed char *p4, int *team);
169+ virtual void GetMovePos(float *x, float *y, float *z);
170+ virtual void SetModel(int upmodel, int armmodel[], int legmodel, int walkmodel[], int runmodel[]);
171+ virtual int GetHP();
172+ virtual bool SetHP(int in_hp);
173+ virtual bool GetDeadFlag();
174+ virtual void SetTeamID(int id);
175+ virtual bool GetInvincibleFlag();
176+ virtual void SetInvincibleFlag(bool flag);
177+ virtual void SetWeapon(class weapon *in_weapon[]);
178+ virtual int PickupWeapon(class weapon *in_weapon);
179+ virtual void ChangeWeapon(int id = -1);
180+ virtual int GetChangeWeaponCnt();
181+ virtual void GetWeapon(int *out_selectweapon, class weapon *out_weapon[]);
182+ virtual int GetMainWeaponTypeNO();
183+ virtual bool GetWeaponBlazingmode();
184+ virtual bool ShotWeapon(int *weapon_paramid, int *GunsightErrorRange);
185+ virtual bool ReloadWeapon();
186+ virtual bool DumpWeapon();
187+ virtual int ChangeShotMode();
188+ virtual void SetMoveForward();
189+ virtual void SetMoveBack();
190+ virtual void SetMoveLeft();
191+ virtual void SetMoveRight();
192+ virtual void SetMoveWalk();
193+ virtual int GetMovemode(bool nowdata);
194+ virtual bool SetEnableScope();
195+ virtual void SetDisableScope();
196+ virtual int GetScopeMode();
197+ virtual void GetRxRy(float *rx, float *ry);
198+ virtual void SetRxRy(float rx, float ry);
199+ virtual float GetDeadRy();
200+ virtual int Jump();
201+ virtual void AddPosOrder(float rx, float ry, float speed);
202+ virtual void HitBulletHead(int attacks);
203+ virtual void HitBulletUp(int attacks);
204+ virtual void HitBulletLeg(int attacks);
205+ virtual void HitZombieAttack();
206+ virtual void HitGrenadeExplosion(int attacks);
207+ virtual bool CheckHit();
208+ virtual float GetTotalMove();
209+ virtual int RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata, bool F5mode);
210+ virtual int GetGunsightErrorRange();
211+ virtual void Render(class D3DGraphics *d3dg, class ResourceManager *Resource, bool DrawArm, bool player);
212+};
213+
214+//! @brief 武器管理クラス
215+class weapon : public object
216+{
217+protected:
218+ float move_x; //!< X軸移動量
219+ float move_y; //!< Y軸移動量
220+ float move_z; //!< Z軸移動量
221+ bool usingflag; //!< 使用中を表すフラグ
222+ int bullets; //!< 合計弾数
223+ int Loadbullets; //!< 装弾数
224+ int shotcnt; //!< 連射カウント
225+ int reloadcnt; //!< リロードカウント
226+ bool motionflag; //!< 座標移動中を表すフラグ
227+
228+public:
229+ 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);
230+ ~weapon();
231+ virtual void SetPosData(float x, float y, float z, float rx);
232+ virtual void SetParamData(int id_param, int lnbs, int nbs, bool init);
233+ virtual void GetParamData(int *id_param, int *lnbs, int *nbs);
234+ virtual bool GetUsingFlag();
235+ virtual int Pickup();
236+ virtual void Dropoff(float x, float y, float z, float rx, float speed);
237+ virtual int Shot();
238+ virtual int StartReload();
239+ virtual int RunReload();
240+ virtual int GetReloadCnt();
241+ virtual bool ResetWeaponParam(class ResourceManager *Resource, int id_param, int lnbs, int nbs);
242+ virtual int RunFrame(class Collision *CollD);
243+ virtual void Render(class D3DGraphics *d3dg);
244+};
245+
246+//! @brief 小物管理クラス
247+class smallobject : public object
248+{
249+protected:
250+ class MIFInterface *MIFdata; //!< 設定値を管理するクラスへのポインタ
251+ float rotation_y; //!< 回転角度
252+ signed char point_p4; //!< ポイントの認識番号
253+ int hp; //!< 体力
254+ float jump_rx; //!< 飛ばす横軸角度
255+ float move_rx; //!< 飛ばす横軸移動量
256+ float add_rx; //!< 飛ばす横軸回転量
257+ float add_ry; //!< 飛ばす縦軸回転量
258+ int jump_cnt; //!< 飛ばす上昇カウント
259+
260+public:
261+ 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);
262+ ~smallobject();
263+ virtual void SetMIFInterfaceClass(class MIFInterface *in_MIFdata);
264+ virtual void SetParamData(int id_param, signed char p4, bool init);
265+ virtual void GetParamData(int *id_param, signed char *p4);
266+ virtual int GetHP();
267+ virtual float CollisionMap(class Collision *CollD);
268+ virtual void HitBullet(int attacks);
269+ virtual void HitGrenadeExplosion(int attacks);
270+ virtual void Destruction();
271+ virtual int RunFrame();
272+ virtual void Render(D3DGraphics *d3dg);
273+};
274+
275+//! @brief 弾丸管理クラス
276+class bullet : public object
277+{
278+protected:
279+ float rotation_y; //!< 回転角度
280+ int attacks; //!< 攻撃力
281+ int penetration; //!< 貫通力
282+ int speed; //!< 弾速
283+ int teamid; //!< チーム番号
284+ int humanid; //!< 人のデータ番号
285+ int cnt; //!< カウント
286+
287+public:
288+ bullet(int modelid = -1, int textureid = -1);
289+ ~bullet();
290+ virtual void SetPosData(float x, float y, float z, float rx, float ry);
291+ virtual void SetParamData(int _attacks, int _penetration, int _speed, int _teamid, int _humanid, bool init);
292+ virtual void GetPosData(float *x, float *y, float *z, float *rx, float *ry);
293+ virtual void GetParamData(int *_attacks, int *_penetration, int *_speed, int *_teamid, int *_humanid);
294+ virtual int RunFrame();
295+ virtual void Render(class D3DGraphics *d3dg);
296+};
297+
298+//! @brief 手榴弾管理クラス
299+class grenade : public bullet
300+{
301+ float move_x; //!< X軸移動量
302+ float move_y; //!< Y軸移動量
303+ float move_z; //!< Y軸移動量
304+
305+public:
306+ grenade(int modelid = -1, int textureid = -1);
307+ ~grenade();
308+ void SetParamData(float speed, int _humanid, bool init);
309+ float GetSpeed();
310+ int RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata);
311+ virtual void Render(D3DGraphics *d3dg);
312+};
313+
314+//! @brief エフェクト管理クラス
315+class effect : public object
316+{
317+protected:
318+ int type; //!< 種類
319+ float camera_rx; //!< カメラ角度
320+ float camera_ry; //!< カメラ角度
321+ float move_x; //!< X軸移動量
322+ float move_y; //!< Y軸移動量
323+ float move_z; //!< Z軸移動量
324+ float rotation_texture; //!< 回転角度
325+ float alpha; //!< 透明度
326+ int cnt; //!< カウント
327+ int setcnt; //!< 設定されたカウント
328+
329+public:
330+ 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);
331+ ~effect();
332+ virtual void SetParamData(float in_move_x, float in_move_y, float in_move_z, float size, float rotation, int count, int texture, int settype, bool init);
333+ virtual int RunFrame(float in_camera_rx, float in_camera_ry);
334+ virtual void Render(class D3DGraphics *d3dg);
335+};
336+
337+//! 人の足の状態を示す定数
338+enum Human_LegState {
339+ LEG_STOP = 0,
340+ LEG_WALK,
341+ LEG_RUN
342+};
343+
344+//! 人の移動操作を表すフラグ
345+enum Human_MoveFlag {
346+ MOVEFLAG_FORWARD = 0x01,
347+ MOVEFLAG_BACK = 0x02,
348+ MOVEFLAG_LEFT = 0x04,
349+ MOVEFLAG_RIGHT = 0x08,
350+ MOVEFLAG_WALK = 0x10,
351+};
352+
353+//! エフェクトの種類を表す定数
354+enum Effect_Type {
355+ EFFECT_NORMAL = 0x00, //!< ノーマル
356+ EFFECT_DISAPPEAR = 0x01, //!< 消す
357+ EFFECT_MAGNIFY = 0x02, //!< 拡大
358+ EFFECT_ROTATION = 0x04, //!< 回転
359+ EFFECT_FALL = 0x08 //!< 落下
360+};
361+
362+#endif
\ No newline at end of file
--- tags/v1.010-20150220/statemachine.cpp (nonexistent)
+++ tags/v1.010-20150220/statemachine.cpp (revision 45)
@@ -0,0 +1,165 @@
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+//! @brief コンストラクタ
35+StateMachine::StateMachine()
36+{
37+ NowState = STATE_CREATE_OPENING;
38+ back = false;
39+ f12 = false;
40+}
41+
42+//! @brief ディストラクタ
43+StateMachine::~StateMachine()
44+{}
45+
46+//! @brief 次の状態へ移行
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+ if( f12 == true ){
58+ NowState = STATE_CREATE_OPENING;
59+ }
60+ else{
61+ NowState = STATE_CREATE_MENU;
62+ }
63+ break;
64+ case STATE_CREATE_MENU:
65+ NowState = STATE_NOW_MENU;
66+ break;
67+ case STATE_NOW_MENU:
68+ NowState = STATE_DESTROY_MENU;
69+ break;
70+ case STATE_DESTROY_MENU:
71+ if( f12 == true ){
72+ NowState = STATE_CREATE_MENU;
73+ }
74+ else if( back == false ){
75+ NowState = STATE_CREATE_BRIEFING;
76+ }
77+ else{
78+ NowState = STATE_EXIT;
79+ }
80+ break;
81+ case STATE_CREATE_BRIEFING:
82+ NowState = STATE_NOW_BRIEFING;
83+ break;
84+ case STATE_NOW_BRIEFING:
85+ NowState = STATE_DESTROY_BRIEFING;
86+ break;
87+ case STATE_DESTROY_BRIEFING:
88+ if( f12 == true ){
89+ NowState = STATE_CREATE_BRIEFING;
90+ }
91+ else if( back == false ){
92+ NowState = STATE_CREATE_MAINGAME;
93+ }
94+ else{
95+ NowState = STATE_CREATE_MENU;
96+ }
97+ break;
98+ case STATE_CREATE_MAINGAME:
99+ NowState = STATE_NOW_MAINGAME;
100+ break;
101+ case STATE_NOW_MAINGAME:
102+ NowState = STATE_DESTROY_MAINGAME;
103+ break;
104+ case STATE_DESTROY_MAINGAME:
105+ if( f12 == true ){
106+ NowState = STATE_CREATE_MAINGAME;
107+ }
108+ else if( back == false ){
109+ NowState = STATE_CREATE_RESULT;
110+ }
111+ else{
112+ NowState = STATE_CREATE_MENU;
113+ }
114+ break;
115+ case STATE_CREATE_RESULT:
116+ NowState = STATE_NOW_RESULT;
117+ break;
118+ case STATE_NOW_RESULT:
119+ NowState = STATE_DESTROY_RESULT;
120+ break;
121+ case STATE_DESTROY_RESULT:
122+ if( f12 == true ){
123+ NowState = STATE_CREATE_RESULT;
124+ }
125+ else{
126+ NowState = STATE_CREATE_MENU;
127+ }
128+ break;
129+ case STATE_EXIT:
130+ NowState = STATE_EXIT;
131+ break;
132+ default:
133+ NowState = STATE_NULL;
134+ }
135+}
136+
137+//! @brief マウスクリック を受けた
138+void StateMachine::PushMouseButton()
139+{
140+ back = false;
141+ f12 = false;
142+ NextState();
143+}
144+
145+//! @brief BackSpace キーを受けた
146+void StateMachine::PushBackSpaceKey()
147+{
148+ back = true;
149+ f12 = false;
150+ NextState();
151+}
152+
153+//! @brief F12 キーを受けた
154+void StateMachine::PushF12Key()
155+{
156+ back = false;
157+ f12 = true;
158+ NextState();
159+}
160+
161+//! @brief 現在の状態を返す
162+int StateMachine::GetState()
163+{
164+ return NowState;
165+}
\ No newline at end of file
--- tags/v1.010-20150220/scene.h (nonexistent)
+++ tags/v1.010-20150220/scene.h (revision 45)
@@ -0,0 +1,105 @@
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 bool RenderMain();
56+ virtual void Destroy();
57+ float GetEffectAlpha(unsigned int tframecnt, float MaxAlpha, float timingsec, float offsetsec, bool reversal);
58+ float GetEffectAlphaLoop(unsigned int tframecnt, float MaxAlpha, float timingsec, bool reversal);
59+};
60+
61+//! @brief 2D画面管理クラス(基底クラス)
62+//! @details ゲーム画面の中で、2D描画のみを行うシーンを管理する基底のクラスです。
63+class D2Dscene : public scene
64+{
65+protected:
66+ int gametitle; //!< ゲームタイトル画像
67+ virtual void Render2D();
68+
69+public:
70+ D2Dscene();
71+ ~D2Dscene();
72+ virtual int Create();
73+ virtual bool RenderMain();
74+ virtual void Destroy();
75+};
76+
77+//! @brief 3D画面管理クラス(基底クラス)
78+//! @details ゲーム画面の中で、3D描画を行うシーンを管理する基底のクラスです。
79+class D3Dscene : public scene
80+{
81+protected:
82+ class SoundManager *GameSound; //!< ゲーム効果音管理クラス
83+ float camera_x; //!< カメラ座標
84+ float camera_y; //!< カメラ座標
85+ float camera_z; //!< カメラ座標
86+ float camera_rx; //!< カメラ座標
87+ float camera_ry; //!< カメラ座標
88+ virtual void Render3D();
89+ virtual void Render2D();
90+
91+public:
92+ D3Dscene();
93+ ~D3Dscene();
94+ virtual void SetClass(StateMachine *in_GameState, D3DGraphics *in_d3dg, InputControl *in_inputCtrl, SoundManager *in_GameSound);
95+ virtual void Process();
96+ virtual void Sound();
97+ virtual bool RenderMain();
98+};
99+
100+#ifndef H_LAYERLEVEL
101+ #define H_LAYERLEVEL 3 //!< Select include file.
102+#endif
103+#include "main.h"
104+
105+#endif
\ No newline at end of file
--- tags/v1.010-20150220/input.cpp (nonexistent)
+++ tags/v1.010-20150220/input.cpp (revision 45)
@@ -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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
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+//! @brief 初期化@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+//! @brief 入力デバイスの状態を更新
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+//! @brief マウスを中心に移動
205+void InputControl::MoveMouseCenter()
206+{
207+ POINT point;
208+
209+ //ウインドウ座標の中央を求める
210+ point.x = SCREEN_WIDTH/2;
211+ point.y = SCREEN_HEIGHT/2;
212+
213+ //前回の座標を書き換え
214+ point_lt = point;
215+
216+ //スクリーン座標に変換し、座標変更
217+ ClientToScreen(hWnd, &point);
218+ SetCursorPos(point.x, point.y);
219+}
220+
221+//! @brief キーボードの入力をチェック(リアルタイム)
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+//! @brief キーボードの入力をチェック(押された瞬間)
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+//! @brief キーボードの入力をチェック(離された瞬間)
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+//! @brief マウスの入力をチェック
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+//! @brief マウス・左ボタンの入力をチェック(リアルタイム)
260+//! @return 押されてない:false 押されている:true
261+bool InputControl::CheckMouseButtonNowL()
262+{
263+ //現在の情報を返す
264+ return mbl;
265+}
266+
267+//! @brief マウス・左ボタンの入力をチェック(押された瞬間)
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+//! @brief マウス・左ボタンの入力をチェック(離された瞬間)
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+//! @brief マウス・右ボタンの入力をチェック(リアルタイム)
286+//! @return 押されてない:false 押されている:true
287+bool InputControl::CheckMouseButtonNowR()
288+{
289+ //現在の情報を返す
290+ return mbr;
291+}
292+
293+//! @brief マウス・右ボタンの入力をチェック(押された瞬間)
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+//! @brief マウス・右ボタンの入力をチェック(離された瞬間)
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+//! @brief オリジナルキーコードを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+//! @brief 左右キーのキーコード取得
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+//! @brief 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+//! @brief 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+//! @brief ファンクションキー(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
--- tags/v1.010-20150220/config.cpp (nonexistent)
+++ tags/v1.010-20150220/config.cpp (revision 45)
@@ -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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
53+Config::~Config()
54+{}
55+
56+//! @brief 設定ファイルを読み込む
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+//! @brief オリジナルキーコードを取得
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+//! @brief マウス感度取得
133+//! @return 生の値
134+int Config::GetMouseSensitivity()
135+{
136+ return MouseSensitivity;
137+}
138+
139+//! @brief 画面表示モード取得
140+//! @return ウィンドウ:false フルスクリーン:true
141+bool Config::GetFullscreenFlag()
142+{
143+ return FullscreenFlag;
144+}
145+
146+//! @brief 効果音設定取得
147+//! @return 無効:false 有効:true
148+bool Config::GetSoundFlag()
149+{
150+ return SoundFlag;
151+}
152+
153+//! @brief 出血設定取得
154+//! @return 無効:false 有効:true
155+bool Config::GetBloodFlag()
156+{
157+ return BloodFlag;
158+}
159+
160+//! @brief 画面の明るさ設定取得
161+//! @return 生の値
162+int Config::GetBrightness()
163+{
164+ return Brightness;
165+}
166+
167+//! @brief マウス反転設定取得
168+//! @return 無効:false 有効:true
169+bool Config::GetInvertMouseFlag()
170+{
171+ return InvertMouseFlag;
172+}
173+
174+//! @brief フレームスキップ設定取得
175+//! @return 無効:false 有効:true
176+bool Config::GetFrameskipFlag()
177+{
178+ return FrameskipFlag;
179+}
180+
181+//! @brief 別の照準を使用設定取得
182+//! @return 無効:false 有効:true
183+bool Config::GetAnotherGunsightFlag()
184+{
185+ return AnotherGunsightFlag;
186+}
187+
188+//! @brief プレイヤー名取得
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+}
--- tags/v1.010-20150220/datafile.cpp (nonexistent)
+++ tags/v1.010-20150220/datafile.cpp (revision 45)
@@ -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+//! @brief コンストラクタ
35+DataInterface::DataInterface()
36+{
37+ datas = 0;
38+}
39+
40+//! @brief ディストラクタ
41+DataInterface::~DataInterface()
42+{}
43+
44+//! @brief データファイルを読みこむ
45+//! @param fname ファイル名
46+//! @return 成功:0 失敗:1
47+int DataInterface::LoadFiledata(char *fname)
48+{
49+ return 0;
50+}
51+
52+//! @brief 合計データ数の取得
53+//! @return 合計データ数
54+int DataInterface::GetTotaldatas()
55+{
56+ return datas;
57+}
58+
59+//! @brief データを取得
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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
81+BlockDataInterface::~BlockDataInterface()
82+{
83+ //blockdata構造体解放
84+ if( data != NULL ) delete [] data;
85+}
86+
87+//! @brief ブロックデータファイルを読みこむ
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+//! @brief ブロックデータの法線・影を算出する
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+//! @brief ブロックデータに設定されたテクスチャのファイル名を取得
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+//! @brief ブロックデータを取得
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+//! @brief ブロック頂点データの関連付けを取得
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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
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+//! @brief ポイントデータファイルを読みこむ
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+//! @brief ポイントデータを取得
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+//! @brief ポイントのパラメーターを書き換え
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+//! @brief メッセージ(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+//! @brief ポイントデータを検索
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+//! @brief ポイントデータを検索
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+//! @brief コンストラクタ
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+//! @brief ディストラクタ
578+MIFInterface::~MIFInterface()
579+{}
580+
581+//! @brief データファイルを読みこむ
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+//! @brief 読み込んだデータファイルの形式を取得
771+//! @return 標準形式:false MIF形式:true
772+//! @attention ファイルを正常に読み込んだ後に実行してください。
773+bool MIFInterface::GetFiletype()
774+{
775+ return mif;
776+}
777+
778+//! @brief ミッション識別名を取得
779+//! @return 識別名のポインタ(最大:24)
780+char* MIFInterface::GetMissionName()
781+{
782+ return mission_name;
783+}
784+
785+//! @brief ミッション正式名称を取得
786+//! @return 正式名称のポインタ(最大:64)
787+char* MIFInterface::GetMissionFullname()
788+{
789+ return mission_fullname;
790+}
791+
792+//! @brief ブロックデータとポイントデータのパスを取得
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+//! @brief 背景空を取得
802+//! @return 空の番号(0〜5)
803+//! @attention 番号 0 は「背景なし」を意味します。
804+int MIFInterface::GetSkynumber()
805+{
806+ return skynumber;
807+}
808+
809+//! @brief ブリーフィング画像ファイルのパスを取得
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+//! @brief ブリーフィング文章(本文)を取得
821+//! @return 文章のポインタ(最大:816)
822+//! @attention 改行コードも含めて、最大17行分が一度に返されます。
823+//! @attention 行数は GetTotaldatas() で取得できます。
824+char* MIFInterface::GetBriefingText()
825+{
826+ return briefingtext;
827+}
828+
829+//! @brief 追加のあたり判定を示すフラグを取得
830+//! @return 有効:true 無効:false
831+bool MIFInterface::GetCollisionFlag()
832+{
833+ return collision;
834+}
835+
836+//! @brief 画面を暗くを示すフラグを取得
837+//! @return 有効:true 無効:false
838+bool MIFInterface::GetScreenFlag()
839+{
840+ return screen;
841+}
842+
843+//! @brief 追加小物のモデルデータパスを取得
844+//! @return モデルデータパスのポインタ(最大:_MAX_PATH)
845+char* MIFInterface::GetAddSmallobjectModelPath()
846+{
847+ return addsmallobject_modelpath;
848+}
849+
850+//! @brief 追加小物のテクスチャパスを取得
851+//! @return テクスチャパスのポインタ(最大:_MAX_PATH)
852+char* MIFInterface::GetAddSmallobjectTexturePath()
853+{
854+ return addsmallobject_texturepath;
855+}
856+
857+//! @brief 追加小物の当たり判定の大きさを取得
858+//! @return 当たり判定の大きさ
859+int MIFInterface::GetAddSmallobjectDecide()
860+{
861+ return addsmallobject_decide;
862+}
863+
864+//! @brief 追加小物の耐久力を取得
865+//! @return 耐久力
866+int MIFInterface::GetAddSmallobjectHP()
867+{
868+ return addsmallobject_hp;
869+}
870+
871+//! @brief 追加小物のサウンドデータパスを取得
872+//! @return サウンドデータパスのポインタ(最大:_MAX_PATH)
873+char* MIFInterface::GetAddSmallobjectSoundPath()
874+{
875+ return addsmallobject_soundpath;
876+}
877+
878+//! @brief 追加小物の飛び具合を取得
879+//! @return 飛び具合
880+int MIFInterface::GetAddSmallobjectJump()
881+{
882+ return addsmallobject_jump;
883+}
884+
885+//! @brief コンストラクタ
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+//! @brief ディストラクタ
897+AddonList::~AddonList()
898+{}
899+
900+//! @brief .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+//! @brief ミッション名を取得
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+//! @brief ミッション名をソートする
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<(int)strlen(mission_name[i]); j++){
955+ mission_name_c[i][j] = (char)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+//! @brief 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+//! @brief ミッション名を取得
1002+//! @param id 認識番号
1003+//! @return ミッション名
1004+char* AddonList::GetMissionName(int id)
1005+{
1006+ return mission_name[id];
1007+}
1008+
1009+//! @brief ファイル名を取得
1010+//! @param id 認識番号
1011+//! @return ファイル名
1012+char* AddonList::GetFileName(int id)
1013+{
1014+ return filename[id];
1015+}
1016+
1017+
1018+//! @brief 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+}
--- tags/v1.010-20150220/resource.cpp (nonexistent)
+++ tags/v1.010-20150220/resource.cpp (revision 45)
@@ -0,0 +1,732 @@
1+//! @file resource.cpp
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+#include "resource.h"
33+
34+//! @brief コンストラクタ
35+ResourceManager::ResourceManager()
36+{
37+ ParamInfo = NULL;
38+ d3dg = NULL;
39+ SoundCtrl = NULL;
40+
41+ for(int i=0; i<TOTAL_UPMODE; i++){
42+ human_upmodel[i] = -1;
43+ }
44+ for(int i=0; i<TOTAL_ARMMODE; i++){
45+ human_armmodel[i] = -1;
46+ }
47+ human_legmodel = -1;
48+ for(int i=0; i<TOTAL_WALKMODE; i++){
49+ human_walkmodel[i] = -1;
50+ }
51+ for(int i=0; i<TOTAL_RUNMODE; i++){
52+ human_runmodel[i] = -1;
53+ }
54+ for(int i=0; i<MAX_LOADHUMANTEXTURE; i++){
55+ human_texture_Param[i] = -1;
56+ human_texture_d3dg[i] = -1;
57+ }
58+ for(int i=0; i<TOTAL_PARAMETERINFO_WEAPON; i++){
59+ weapon_model[i] = -1;
60+ weapon_texture[i] = -1;
61+ weapon_sound[i] = -1;
62+ }
63+ for(int i=0; i<TOTAL_PARAMETERINFO_SMALLOBJECT+1; i++){
64+ smallobject_model[i] = -1;
65+ smallobject_texture[i] = -1;
66+ smallobject_sound[i] = -1;
67+ }
68+
69+ scopetexture = -1;
70+ skymodel = -1;
71+ skytexture = -1;
72+ bulletmodel = -1;
73+ bullettexture = -1;
74+ bullet_hitsoundA = -1;
75+ bullet_hitsoundB = -1;
76+ bullet_humanhitsound = -1;
77+ bullet_passingsound = -1;
78+ grenade_bang = -1;
79+ grenade_cco = -1;
80+ effecttexture_blood = -1;
81+ effecttexture_mflash = -1;
82+ effecttexture_smoke = -1;
83+ effecttexture_yakkyou = -1;
84+}
85+
86+//! @brief ディストラクタ
87+ResourceManager::~ResourceManager()
88+{
89+ CleanupHumanModel();
90+ CleanupHumanTexture();
91+ CleanupWeaponModelTexture();
92+ CleanupSmallObjectModelTexture();
93+
94+ CleanupScopeTexture();
95+ CleanupSkyModelTexture();
96+ CleanupBulletModelTexture();
97+ CleanupEffectTexture();
98+}
99+
100+//! @brief 参照するParameterInfoクラスを設定
101+//! @param *_ParamInfo ParameterInfoクラスのポインタ
102+//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。
103+void ResourceManager::SetParameterInfo(ParameterInfo *_ParamInfo)
104+{
105+ ParamInfo = _ParamInfo;
106+}
107+
108+//! @brief 参照するD3DGraphicsクラスを設定
109+//! @param *_d3dg D3DGraphicsクラスのポインタ
110+//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。
111+void ResourceManager::SetD3DGraphics(D3DGraphics *_d3dg)
112+{
113+ d3dg = _d3dg;
114+}
115+
116+//! @brief 参照するSoundControlクラスを設定
117+//! @param *_SoundCtrl SoundControlクラスのポインタ
118+//! @attention この関数で設定を行わないと、クラス自体が正しく機能しません。
119+void ResourceManager::SetSoundControl(SoundControl *_SoundCtrl)
120+{
121+ SoundCtrl = _SoundCtrl;
122+}
123+
124+//! @brief 人のモデルを読み込み
125+//! @return 成功:0 失敗:1
126+int ResourceManager::LoadHumanModel()
127+{
128+ if( d3dg == NULL ){ return 1; }
129+
130+ human_upmodel[0] = d3dg->LoadModel("data\\model\\up0.x");
131+ human_upmodel[1] = d3dg->LoadModel("data\\model\\up1.x");
132+ human_upmodel[2] = d3dg->LoadModel("data\\model\\up2.x");
133+ human_upmodel[3] = d3dg->LoadModel("data\\model\\up3.x");
134+ human_upmodel[4] = d3dg->LoadModel("data\\model\\up4.x");
135+ human_upmodel[5] = d3dg->LoadModel("data\\model\\up5.x");
136+ human_armmodel[0] = d3dg->LoadModel("data\\model\\arm00.x");
137+ human_armmodel[1] = d3dg->LoadModel("data\\model\\arm01.x");
138+ human_armmodel[2] = d3dg->LoadModel("data\\model\\arm02.x");
139+ human_legmodel = d3dg->LoadModel("data\\model\\leg.x");
140+ human_walkmodel[0] = d3dg->LoadModel("data\\model\\walk01.x");
141+ human_walkmodel[2] = d3dg->LoadModel("data\\model\\walk02.x");
142+ human_walkmodel[4] = d3dg->LoadModel("data\\model\\walk03.x");
143+ human_walkmodel[6] = d3dg->LoadModel("data\\model\\walk04.x");
144+ human_runmodel[0] = d3dg->LoadModel("data\\model\\run01.x");
145+ human_runmodel[2] = d3dg->LoadModel("data\\model\\run02.x");
146+ human_runmodel[4] = d3dg->LoadModel("data\\model\\run03.x");
147+ human_runmodel[6] = d3dg->LoadModel("data\\model\\run04.x");
148+ human_runmodel[8] = d3dg->LoadModel("data\\model\\run05.x");
149+ human_runmodel[10] = d3dg->LoadModel("data\\model\\run06.x");
150+
151+ if( 1 ){
152+ //モーフィング処理を実行する
153+ human_walkmodel[1] = d3dg->MorphingModel(human_walkmodel[0], human_walkmodel[2]);
154+ human_walkmodel[3] = d3dg->MorphingModel(human_walkmodel[2], human_walkmodel[4]);
155+ human_walkmodel[5] = d3dg->MorphingModel(human_walkmodel[4], human_walkmodel[6]);
156+ human_walkmodel[7] = d3dg->MorphingModel(human_walkmodel[6], human_walkmodel[0]);
157+ human_runmodel[1] = d3dg->MorphingModel(human_runmodel[0], human_runmodel[2]);
158+ human_runmodel[3] = d3dg->MorphingModel(human_runmodel[2], human_runmodel[4]);
159+ human_runmodel[5] = d3dg->MorphingModel(human_runmodel[4], human_runmodel[6]);
160+ human_runmodel[7] = d3dg->MorphingModel(human_runmodel[6], human_runmodel[8]);
161+ human_runmodel[9] = d3dg->MorphingModel(human_runmodel[8], human_runmodel[10]);
162+ human_runmodel[11] = d3dg->MorphingModel(human_runmodel[10], human_runmodel[0]);
163+ }
164+ else{
165+ //モーフィング処理を実行しない
166+ human_walkmodel[1] = human_walkmodel[0];
167+ human_walkmodel[3] = human_walkmodel[2];
168+ human_walkmodel[5] = human_walkmodel[4];
169+ human_walkmodel[7] = human_walkmodel[6];
170+ human_runmodel[1] = human_runmodel[0];
171+ human_runmodel[3] = human_runmodel[2];
172+ human_runmodel[5] = human_runmodel[4];
173+ human_runmodel[7] = human_runmodel[6];
174+ human_runmodel[9] = human_runmodel[8];
175+ human_runmodel[11] = human_runmodel[10];
176+ }
177+
178+ return 0;
179+}
180+
181+//! @brief 人のモデル認識番号を取得
182+//! @param out_upmodel[] 上半身のモデル (配列数:TOTAL_UPMODE)
183+//! @param out_armmodel[] 腕のモデル (配列数:TOTAL_ARMMODE)
184+//! @param *legmodel 足(静止状態)のモデルのポインタ
185+//! @param out_walkmodel[] 足(歩き)のモデル (配列数:TOTAL_WALKMODE)
186+//! @param out_runmodel[] 足(走り)のモデル (配列数:TOTAL_RUNMODE)
187+void ResourceManager::GetHumanModel(int out_upmodel[], int out_armmodel[], int *legmodel, int out_walkmodel[], int out_runmodel[])
188+{
189+ for(int i=0; i<TOTAL_UPMODE; i++){
190+ out_upmodel[i] = human_upmodel[i];
191+ }
192+ for(int i=0; i<TOTAL_ARMMODE; i++){
193+ out_armmodel[i] = human_armmodel[i];
194+ }
195+ *legmodel = human_legmodel;
196+ for(int i=0; i<TOTAL_WALKMODE; i++){
197+ out_walkmodel[i] = human_walkmodel[i];
198+ }
199+ for(int i=0; i<TOTAL_RUNMODE; i++){
200+ out_runmodel[i] = human_runmodel[i];
201+ }
202+}
203+
204+//! @brief 人のモデルを解放
205+void ResourceManager::CleanupHumanModel()
206+{
207+ if( d3dg == NULL ){ return; }
208+
209+ for(int i=0; i<TOTAL_UPMODE; i++){
210+ d3dg->CleanupModel(human_upmodel[i]);
211+ human_upmodel[i] = -1;
212+ }
213+ for(int i=0; i<TOTAL_ARMMODE; i++){
214+ d3dg->CleanupModel(human_armmodel[i]);
215+ human_armmod

Part of diff was cut off due to size limit. Use your local client to view the full diff.