• R/O
  • SSH
  • HTTPS

Commit

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqt誰得windowscocoapythonphprubygameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

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


Commit MetaInfo

Revision49 (tree)
Zeit2015-02-22 01:41:56
Autorxops-mikan

Log Message

Version:1.011

Ändern Zusammenfassung

Diff

--- tags/v1.011-20150222/main.h (nonexistent)
+++ tags/v1.011-20150222/main.h (revision 49)
@@ -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.011" //!< ゲームのバージョン
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.011-20150222/event.cpp (nonexistent)
+++ tags/v1.011-20150222/event.cpp (revision 49)
@@ -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+ *SetMessageID = true;
198+ break;
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.011-20150222/parameter.cpp (nonexistent)
+++ tags/v1.011-20150222/parameter.cpp (revision 49)
@@ -0,0 +1,1614 @@
1+//! @file parameter.cpp
2+//! @brief ParameterInfoクラスの定義
3+
4+//--------------------------------------------------------------------------------
5+//
6+// OpenXOPS
7+// Copyright (c) 2014-2015, OpenXOPS Project / [-_-;](mikan) All rights reserved.
8+//
9+// Redistribution and use in source and binary forms, with or without
10+// modification, are permitted provided that the following conditions are met:
11+// * Redistributions of source code must retain the above copyright notice,
12+// this list of conditions and the following disclaimer.
13+// * Redistributions in binary form must reproduce the above copyright notice,
14+// this list of conditions and the following disclaimer in the documentation
15+// and/or other materials provided with the distribution.
16+// * Neither the name of the OpenXOPS Project nor the names of its contributors
17+// may be used to endorse or promote products derived from this software
18+// without specific prior written permission.
19+//
20+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+// DISCLAIMED. IN NO EVENT SHALL OpenXOPS Project BE LIABLE FOR ANY
24+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+//--------------------------------------------------------------------------------
31+
32+// 人・武器・小物 設定データの確認作業
33+//  Mandaさん (2014年12月〜)
34+
35+#include "parameter.h"
36+
37+//! @brief コンストラクタ
38+ParameterInfo::ParameterInfo()
39+{
40+ Human = NULL;
41+ for(int i=0; i<TOTAL_HUMANTEXTURE; i++){
42+ HumanTexturePath[i] = NULL;
43+ }
44+ Weapon = NULL;
45+ SmallObject = NULL;
46+ for(int i=0; i<TOTAL_OFFICIALMISSION; i++){
47+ missionname[i] = NULL;
48+ missionfullname[i] = NULL;
49+ missiondirectory[i] = NULL;
50+ missiontxt[i] = NULL;
51+ }
52+ AIlevel = NULL;
53+}
54+
55+//! @brief ディストラクタ
56+ParameterInfo::~ParameterInfo()
57+{
58+ //CleanupModelTextureWeapon();
59+ //CleanupModelTextureSmallObject();
60+
61+ if( Human != NULL ){ delete [] Human; }
62+ if( Weapon != NULL ){ delete [] Weapon; }
63+ if( SmallObject != NULL ){ delete [] SmallObject; }
64+ if( AIlevel != NULL ){ delete [] AIlevel; }
65+}
66+
67+//! @brief 初期化(パラメータの設定)
68+//! @attention この関数を呼び出さないと、クラス自体が正しく機能しません。
69+void ParameterInfo::InitInfo()
70+{
71+ Human = new HumanParameter[TOTAL_PARAMETERINFO_HUMAN];
72+ Weapon = new WeaponParameter[TOTAL_PARAMETERINFO_WEAPON];
73+ SmallObject = new SmallObjectParameter[TOTAL_PARAMETERINFO_SMALLOBJECT];
74+ AIlevel = new AIParameter[TOTAL_PARAMETERINFO_AILEVEL];
75+
76+ //特殊 黒 A
77+ Human[0].texture = 14;
78+ Human[0].model = 5;
79+ Human[0].hp = 120;
80+ Human[0].AIlevel = 3;
81+ Human[0].Weapon[0] = 21;
82+ Human[0].Weapon[1] = 8;
83+ Human[0].type = 0;
84+ //特殊 黒 B
85+ Human[1].texture = 14;
86+ Human[1].model = 5;
87+ Human[1].hp = 120;
88+ Human[1].AIlevel = 3;
89+ Human[1].Weapon[0] = 21;
90+ Human[1].Weapon[1] = 2;
91+ Human[1].type = 0;
92+ //特殊 緑 A
93+ Human[2].texture = 16;
94+ Human[2].model = 0;
95+ Human[2].hp = 110;
96+ Human[2].AIlevel = 2;
97+ Human[2].Weapon[0] = 3;
98+ Human[2].Weapon[1] = 6;
99+ Human[2].type = 0;
100+ //特殊 緑 B
101+ Human[3].texture = 16;
102+ Human[3].model = 0;
103+ Human[3].hp = 110;
104+ Human[3].AIlevel = 2;
105+ Human[3].Weapon[0] = 3;
106+ Human[3].Weapon[1] = 10;
107+ Human[3].type = 0;
108+ //特殊 緑 C
109+ Human[4].texture = 16;
110+ Human[4].model = 0;
111+ Human[4].hp = 110;
112+ Human[4].AIlevel = 2;
113+ Human[4].Weapon[0] = 3;
114+ Human[4].Weapon[1] = 2;
115+ Human[4].type = 0;
116+ //特殊 白 A
117+ Human[5].texture = 18;
118+ Human[5].model = 0;
119+ Human[5].hp = 110;
120+ Human[5].AIlevel = 2;
121+ Human[5].Weapon[0] = 4;
122+ Human[5].Weapon[1] = 7;
123+ Human[5].type = 0;
124+ //特殊 白 B
125+ Human[6].texture = 18;
126+ Human[6].model = 0;
127+ Human[6].hp = 110;
128+ Human[6].AIlevel = 2;
129+ Human[6].Weapon[0] = 4;
130+ Human[6].Weapon[1] = 2;
131+ Human[6].type = 0;
132+ //ハゲ
133+ Human[7].texture = 5;
134+ Human[7].model = 0;
135+ Human[7].hp = 100;
136+ Human[7].AIlevel = 3;
137+ Human[7].Weapon[0] = 4;
138+ Human[7].Weapon[1] = 0;
139+ Human[7].type = 0;
140+ //特殊 紫
141+ Human[8].texture = 17;
142+ Human[8].model = 0;
143+ Human[8].hp = 110;
144+ Human[8].AIlevel = 3;
145+ Human[8].Weapon[0] = 22;
146+ Human[8].Weapon[1] = 14;
147+ Human[8].type = 0;
148+ //特殊 青
149+ Human[9].texture = 15;
150+ Human[9].model = 5;
151+ Human[9].hp = 120;
152+ Human[9].AIlevel = 2;
153+ Human[9].Weapon[0] = 3;
154+ Human[9].Weapon[1] = 1;
155+ Human[9].type = 0;
156+ //戦闘用ロボット
157+ Human[10].texture = 13;
158+ Human[10].model = 0;
159+ Human[10].hp = 2500;
160+ Human[10].AIlevel = 4;
161+ Human[10].Weapon[0] = 6;
162+ Human[10].Weapon[1] = 12;
163+ Human[10].type = 1;
164+ //スーツ 黒 SG
165+ Human[11].texture = 4;
166+ Human[11].model = 1;
167+ Human[11].hp = 100;
168+ Human[11].AIlevel = 1;
169+ Human[11].Weapon[0] = 18;
170+ Human[11].Weapon[1] = 0;
171+ Human[11].type = 0;
172+ //スーツ 黒
173+ Human[12].texture = 4;
174+ Human[12].model = 0;
175+ Human[12].hp = 100;
176+ Human[12].AIlevel = 1;
177+ Human[12].Weapon[0] = 5;
178+ Human[12].Weapon[1] = 0;
179+ Human[12].type = 0;
180+ //スーツ 灰
181+ Human[13].texture = 11;
182+ Human[13].model = 0;
183+ Human[13].hp = 100;
184+ Human[13].AIlevel = 0;
185+ Human[13].Weapon[0] = 0;
186+ Human[13].Weapon[1] = 0;
187+ Human[13].type = 0;
188+ //警察官
189+ Human[14].texture = 8;
190+ Human[14].model = 2;
191+ Human[14].hp = 100;
192+ Human[14].AIlevel = 1;
193+ Human[14].Weapon[0] = 3;
194+ Human[14].Weapon[1] = 0;
195+ Human[14].type = 0;
196+ //スーツ 茶
197+ Human[15].texture = 9;
198+ Human[15].model = 0;
199+ Human[15].hp = 100;
200+ Human[15].AIlevel = 0;
201+ Human[15].Weapon[0] = 0;
202+ Human[15].Weapon[1] = 0;
203+ Human[15].type = 0;
204+ //シャツ男 1
205+ Human[16].texture = 23;
206+ Human[16].model = 0;
207+ Human[16].hp = 100;
208+ Human[16].AIlevel = 0;
209+ Human[16].Weapon[0] = 17;
210+ Human[16].Weapon[1] = 0;
211+ Human[16].type = 0;
212+ //中東兵
213+ Human[17].texture = 6;
214+ Human[17].model = 0;
215+ Human[17].hp = 100;
216+ Human[17].AIlevel = 1;
217+ Human[17].Weapon[0] = 17;
218+ Human[17].Weapon[1] = 10;
219+ Human[17].type = 0;
220+ //女
221+ Human[18].texture = 25;
222+ Human[18].model = 3;
223+ Human[18].hp = 90;
224+ Human[18].AIlevel = 0;
225+ Human[18].Weapon[0] = 0;
226+ Human[18].Weapon[1] = 0;
227+ Human[18].type = 0;
228+ //金髪男
229+ Human[19].texture = 0;
230+ Human[19].model = 0;
231+ Human[19].hp = 100;
232+ Human[19].AIlevel = 0;
233+ Human[19].Weapon[0] = 0;
234+ Human[19].Weapon[1] = 0;
235+ Human[19].type = 0;
236+ //市民 1
237+ Human[20].texture = 1;
238+ Human[20].model = 0;
239+ Human[20].hp = 100;
240+ Human[20].AIlevel = 0;
241+ Human[20].Weapon[0] = 0;
242+ Human[20].Weapon[1] = 0;
243+ Human[20].type = 0;
244+ //市民 2
245+ Human[21].texture = 2;
246+ Human[21].model = 0;
247+ Human[21].hp = 100;
248+ Human[21].AIlevel = 0;
249+ Human[21].Weapon[0] = 0;
250+ Human[21].Weapon[1] = 0;
251+ Human[21].type = 0;
252+ //シャツ男 1 SG
253+ Human[22].texture = 23;
254+ Human[22].model = 1;
255+ Human[22].hp = 100;
256+ Human[22].AIlevel = 0;
257+ Human[22].Weapon[0] = 0;
258+ Human[22].Weapon[1] = 0;
259+ Human[22].type = 0;
260+ //金髪男 SG
261+ Human[23].texture = 0;
262+ Human[23].model = 1;
263+ Human[23].hp = 100;
264+ Human[23].AIlevel = 0;
265+ Human[23].Weapon[0] = 0;
266+ Human[23].Weapon[1] = 0;
267+ Human[23].type = 0;
268+ //市民 1 SG
269+ Human[24].texture = 1;
270+ Human[24].model = 1;
271+ Human[24].hp = 100;
272+ Human[24].AIlevel = 0;
273+ Human[24].Weapon[0] = 0;
274+ Human[24].Weapon[1] = 0;
275+ Human[24].type = 0;
276+ //市民 2 SG
277+ Human[25].texture = 2;
278+ Human[25].model = 1;
279+ Human[25].hp = 100;
280+ Human[25].AIlevel = 0;
281+ Human[25].Weapon[0] = 0;
282+ Human[25].Weapon[1] = 0;
283+ Human[25].type = 0;
284+ //兵士 1 A
285+ Human[26].texture = 19;
286+ Human[26].model = 4;
287+ Human[26].hp = 115;
288+ Human[26].AIlevel = 2;
289+ Human[26].Weapon[0] = 5;
290+ Human[26].Weapon[1] = 9;
291+ Human[26].type = 0;
292+ //兵士 1 B
293+ Human[27].texture = 20;
294+ Human[27].model = 4;
295+ Human[27].hp = 115;
296+ Human[27].AIlevel = 2;
297+ Human[27].Weapon[0] = 5;
298+ Human[27].Weapon[1] = 12;
299+ Human[27].type = 0;
300+ //兵士 2
301+ Human[28].texture = 21;
302+ Human[28].model = 4;
303+ Human[28].hp = 115;
304+ Human[28].AIlevel = 2;
305+ Human[28].Weapon[0] = 13;
306+ Human[28].Weapon[1] = 10;
307+ Human[28].type = 0;
308+ //ゾンビ 1
309+ Human[29].texture = 26;
310+ Human[29].model = 0;
311+ Human[29].hp = 1000;
312+ Human[29].AIlevel = 0;
313+ Human[29].Weapon[0] = 0;
314+ Human[29].Weapon[1] = 0;
315+ Human[29].type = 2;
316+ //ゾンビ 2
317+ Human[30].texture = 27;
318+ Human[30].model = 0;
319+ Human[30].hp = 1000;
320+ Human[30].AIlevel = 0;
321+ Human[30].Weapon[0] = 0;
322+ Human[30].Weapon[1] = 0;
323+ Human[30].type = 2;
324+ //ゾンビ 3
325+ Human[31].texture = 28;
326+ Human[31].model = 0;
327+ Human[31].hp = 1000;
328+ Human[31].AIlevel = 0;
329+ Human[31].Weapon[0] = 0;
330+ Human[31].Weapon[1] = 0;
331+ Human[31].type = 2;
332+ //ゾンビ 4
333+ Human[32].texture = 29;
334+ Human[32].model = 3;
335+ Human[32].hp = 950;
336+ Human[32].AIlevel = 0;
337+ Human[32].Weapon[0] = 0;
338+ Human[32].Weapon[1] = 0;
339+ Human[32].type = 2;
340+ //スーツ 紺
341+ Human[33].texture = 12;
342+ Human[33].model = 0;
343+ Human[33].hp = 100;
344+ Human[33].AIlevel = 0;
345+ Human[33].Weapon[0] = 0;
346+ Human[33].Weapon[1] = 0;
347+ Human[33].type = 0;
348+ //スーツ 紺 SG
349+ Human[34].texture = 12;
350+ Human[34].model = 1;
351+ Human[34].hp = 100;
352+ Human[34].AIlevel = 1;
353+ Human[34].Weapon[0] = 17;
354+ Human[34].Weapon[1] = 0;
355+ Human[34].type = 0;
356+ //将軍
357+ Human[35].texture = 7;
358+ Human[35].model = 0;
359+ Human[35].hp = 95;
360+ Human[35].AIlevel = 1;
361+ Human[35].Weapon[0] = 17;
362+ Human[35].Weapon[1] = 0;
363+ Human[35].type = 0;
364+ //スーツ 青
365+ Human[36].texture = 10;
366+ Human[36].model = 0;
367+ Human[36].hp = 100;
368+ Human[36].AIlevel = 0;
369+ Human[36].Weapon[0] = 0;
370+ Human[36].Weapon[1] = 0;
371+ Human[36].type = 0;
372+ //スーツ 青 SG
373+ Human[37].texture = 10;
374+ Human[37].model = 1;
375+ Human[37].hp = 100;
376+ Human[37].AIlevel = 1;
377+ Human[37].Weapon[0] = 18;
378+ Human[37].Weapon[1] = 0;
379+ Human[37].type = 0;
380+ //シャツ男 2 SG
381+ Human[38].texture = 24;
382+ Human[38].model = 1;
383+ Human[38].hp = 100;
384+ Human[38].AIlevel = 1;
385+ Human[38].Weapon[0] = 6;
386+ Human[38].Weapon[1] = 0;
387+ Human[38].type = 0;
388+ //兵士 3
389+ Human[39].texture = 22;
390+ Human[39].model = 0;
391+ Human[39].hp = 105;
392+ Human[39].AIlevel = 3;
393+ Human[39].Weapon[0] = 5;
394+ Human[39].Weapon[1] = 20;
395+ Human[39].type = 0;
396+ //兵士 3 SG
397+ Human[40].texture = 22;
398+ Human[40].model = 1;
399+ Human[40].hp = 105;
400+ Human[40].AIlevel = 3;
401+ Human[40].Weapon[0] = 21;
402+ Human[40].Weapon[1] = 0;
403+ Human[40].type = 0;
404+ //ゲイツ
405+ Human[41].texture = 3;
406+ Human[41].model = 0;
407+ Human[41].hp = 100;
408+ Human[41].AIlevel = 0;
409+ Human[41].Weapon[0] = 0;
410+ Human[41].Weapon[1] = 0;
411+ Human[41].type = 0;
412+ //ゲイツ SG
413+ Human[42].texture = 3;
414+ Human[42].model = 1;
415+ Human[42].hp = 100;
416+ Human[42].AIlevel = 4;
417+ Human[42].Weapon[0] = 22;
418+ Human[42].Weapon[1] = 0;
419+ Human[42].type = 0;
420+
421+ HumanTexturePath[0] = "./data/model/civ1.bmp";
422+ HumanTexturePath[1] = "./data/model/civ2.bmp";
423+ HumanTexturePath[2] = "./data/model/civ3.bmp";
424+ HumanTexturePath[3] = "./data/model/gates.bmp";
425+ HumanTexturePath[4] = "./data/model/gs.bmp";
426+ HumanTexturePath[5] = "./data/model/hage.bmp";
427+ HumanTexturePath[6] = "./data/model/islam.bmp";
428+ HumanTexturePath[7] = "./data/model/islam2.bmp";
429+ HumanTexturePath[8] = "./data/model/police.bmp";
430+ HumanTexturePath[9] = "./data/model/riiman.bmp";
431+ HumanTexturePath[10] = "./data/model/riiman_b.bmp";
432+ HumanTexturePath[11] = "./data/model/riiman_g.bmp";
433+ HumanTexturePath[12] = "./data/model/riiman_k.bmp";
434+ HumanTexturePath[13] = "./data/model/robot.bmp";
435+ HumanTexturePath[14] = "./data/model/soldier_black.bmp";
436+ HumanTexturePath[15] = "./data/model/soldier_blue.bmp";
437+ HumanTexturePath[16] = "./data/model/soldier_green.bmp";
438+ HumanTexturePath[17] = "./data/model/soldier_violet.bmp";
439+ HumanTexturePath[18] = "./data/model/soldier_white.bmp";
440+ HumanTexturePath[19] = "./data/model/soldier0.bmp";
441+ HumanTexturePath[20] = "./data/model/soldier1.bmp";
442+ HumanTexturePath[21] = "./data/model/soldier2.bmp";
443+ HumanTexturePath[22] = "./data/model/soldier3.bmp";
444+ HumanTexturePath[23] = "./data/model/syatu.bmp";
445+ HumanTexturePath[24] = "./data/model/syatu2.bmp";
446+ HumanTexturePath[25] = "./data/model/woman.bmp";
447+ HumanTexturePath[26] = "./data/model/zombie1.bmp";
448+ HumanTexturePath[27] = "./data/model/zombie2.bmp";
449+ HumanTexturePath[28] = "./data/model/zombie3.bmp";
450+ HumanTexturePath[29] = "./data/model/zombie4.bmp";
451+
452+
453+ Weapon[0].name = "NONE"; // ID_WEAPON_NONE 定数を要設定
454+ Weapon[0].model = "";
455+ Weapon[0].texture= "";
456+ Weapon[0].attacks = 0;
457+ Weapon[0].penetration = 0;
458+ Weapon[0].blazings = 0;
459+ Weapon[0].speed = 0;
460+ Weapon[0].nbsmax = 0;
461+ Weapon[0].reloads = 0;
462+ Weapon[0].reaction = 0;
463+ Weapon[0].ErrorRangeMIN = 0;
464+ Weapon[0].ErrorRangeMAX = 0;
465+ Weapon[0].mx = 0.0f;
466+ Weapon[0].my = 0.0f;
467+ Weapon[0].mz = 0.0f;
468+ Weapon[0].flashx = 0.0f;
469+ Weapon[0].flashy = 0.0f;
470+ Weapon[0].flashz = 0.0f;
471+ Weapon[0].yakkyou_px = 0.0f;
472+ Weapon[0].yakkyou_py = 0.0f;
473+ Weapon[0].yakkyou_pz = 0.0f;
474+ Weapon[0].yakkyou_sx = 0.0f;
475+ Weapon[0].yakkyou_sy = 0.0f;
476+ Weapon[0].blazingmode = true;
477+ Weapon[0].scopemode = 0;
478+ Weapon[0].size = 9.0f;
479+ Weapon[0].soundid = 0;
480+ Weapon[0].soundvolume = 0;
481+ Weapon[0].silencer = false;
482+ Weapon[0].WeaponP = 2;
483+ Weapon[0].ChangeWeapon = -1;
484+ Weapon[0].burst = 0;
485+ Weapon[1].name = "MP5";
486+ Weapon[1].model = "./data/model/weapon/mp5.x";
487+ Weapon[1].texture= "./data/model/weapon/mp5.bmp";
488+ Weapon[1].attacks = 44;
489+ Weapon[1].penetration = 0;
490+ Weapon[1].blazings = 4;
491+ Weapon[1].speed = 10;
492+ Weapon[1].nbsmax = 30;
493+ Weapon[1].reloads = 50;
494+ Weapon[1].reaction = 6;
495+ Weapon[1].ErrorRangeMIN = 2;
496+ Weapon[1].ErrorRangeMAX = 21;
497+ Weapon[1].mx = 8.0f;
498+ Weapon[1].my = 9.0f;
499+ Weapon[1].mz = 35.0f;
500+ Weapon[1].flashx = 8.0f;
501+ Weapon[1].flashy = 15.0f;
502+ Weapon[1].flashz = 68.0f;
503+ Weapon[1].yakkyou_px = 8.0f;
504+ Weapon[1].yakkyou_py = 12.0f;
505+ Weapon[1].yakkyou_pz = 35.0f;
506+ Weapon[1].yakkyou_sx = 5.0f;
507+ Weapon[1].yakkyou_sy = 7.0f;
508+ Weapon[1].blazingmode = true;
509+ Weapon[1].scopemode = 0;
510+ Weapon[1].size = 7.5f;
511+ Weapon[1].soundid = 0;
512+ Weapon[1].soundvolume = 92;
513+ Weapon[1].silencer = false;
514+ Weapon[1].WeaponP = 0;
515+ Weapon[1].ChangeWeapon = -1;
516+ Weapon[1].burst = 1;
517+ Weapon[2].name = "PSG1";
518+ Weapon[2].model = "./data/model/weapon/psg1.x";
519+ Weapon[2].texture= "./data/model/weapon/psg1.bmp";
520+ Weapon[2].attacks = 70;
521+ Weapon[2].penetration = 2;
522+ Weapon[2].blazings = 7;
523+ Weapon[2].speed = 14;
524+ Weapon[2].nbsmax = 5;
525+ Weapon[2].reloads = 58;
526+ Weapon[2].reaction = 15;
527+ Weapon[2].ErrorRangeMIN = 0;
528+ Weapon[2].ErrorRangeMAX = 19;
529+ Weapon[2].mx = 8.0f;
530+ Weapon[2].my = 8.0f;
531+ Weapon[2].mz = 44.0f;
532+ Weapon[2].flashx = 8.0f;
533+ Weapon[2].flashy = 13.0f;
534+ Weapon[2].flashz = 108.0f;
535+ Weapon[2].yakkyou_px = 8.0f;
536+ Weapon[2].yakkyou_py = 13.0f;
537+ Weapon[2].yakkyou_pz = 38.0f;
538+ Weapon[2].yakkyou_sx = 6.0f;
539+ Weapon[2].yakkyou_sy = 6.0f;
540+ Weapon[2].blazingmode = false;
541+ Weapon[2].scopemode = 2;
542+ Weapon[2].size = 8.0f;
543+ Weapon[2].soundid = 1;
544+ Weapon[2].soundvolume = 98;
545+ Weapon[2].silencer = false;
546+ Weapon[2].WeaponP = 0;
547+ Weapon[2].ChangeWeapon = -1;
548+ Weapon[2].burst = 1;
549+ Weapon[3].name = "M92F";
550+ Weapon[3].model = "./data/model/weapon/m92f.x";
551+ Weapon[3].texture= "./data/model/weapon/m92f.bmp";
552+ Weapon[3].attacks = 41;
553+ Weapon[3].penetration = 0;
554+ Weapon[3].blazings = 5;
555+ Weapon[3].speed = 9;
556+ Weapon[3].nbsmax = 15;
557+ Weapon[3].reloads = 40;
558+ Weapon[3].reaction = 10;
559+ Weapon[3].ErrorRangeMIN = 4;
560+ Weapon[3].ErrorRangeMAX = 26;
561+ Weapon[3].mx = 2.0f;
562+ Weapon[3].my = 7.0f;
563+ Weapon[3].mz = 57.0f;
564+ Weapon[3].flashx = 2.0f;
565+ Weapon[3].flashy = 15.0f;
566+ Weapon[3].flashz = 73.0f;
567+ Weapon[3].yakkyou_px = 2.0f;
568+ Weapon[3].yakkyou_py = 15.0f;
569+ Weapon[3].yakkyou_pz = 56.0f;
570+ Weapon[3].yakkyou_sx = 4.0f;
571+ Weapon[3].yakkyou_sy = 4.0f;
572+ Weapon[3].blazingmode = false;
573+ Weapon[3].scopemode = 0;
574+ Weapon[3].size = 7.0f;
575+ Weapon[3].soundid = 1;
576+ Weapon[3].soundvolume = 90;
577+ Weapon[3].silencer = false;
578+ Weapon[3].WeaponP = 1;
579+ Weapon[3].ChangeWeapon = -1;
580+ Weapon[3].burst = 1;
581+ Weapon[4].name = "GLOCK18 SEMI";
582+ Weapon[4].model = "./data/model/weapon/glock18.x";
583+ Weapon[4].texture= "./data/model/weapon/glock18.bmp";
584+ Weapon[4].attacks = 38;
585+ Weapon[4].penetration = 0;
586+ Weapon[4].blazings = 5;
587+ Weapon[4].speed = 9;
588+ Weapon[4].nbsmax = 19;
589+ Weapon[4].reloads = 38;
590+ Weapon[4].reaction = 9;
591+ Weapon[4].ErrorRangeMIN = 4;
592+ Weapon[4].ErrorRangeMAX = 26;
593+ Weapon[4].mx = 2.0f;
594+ Weapon[4].my = 8.0f;
595+ Weapon[4].mz = 56.0f;
596+ Weapon[4].flashx = 2.0f;
597+ Weapon[4].flashy = 13.0f;
598+ Weapon[4].flashz = 70.0f;
599+ Weapon[4].yakkyou_px = 2.0f;
600+ Weapon[4].yakkyou_py = 14.0f;
601+ Weapon[4].yakkyou_pz = 54.0f;
602+ Weapon[4].yakkyou_sx = 4.0f;
603+ Weapon[4].yakkyou_sy = 4.0f;
604+ Weapon[4].blazingmode = false;
605+ Weapon[4].scopemode = 0;
606+ Weapon[4].size = 5.0f;
607+ Weapon[4].soundid = 0;
608+ Weapon[4].soundvolume = 90;
609+ Weapon[4].silencer = false;
610+ Weapon[4].WeaponP = 1;
611+ Weapon[4].ChangeWeapon = 16;
612+ Weapon[4].burst = 1;
613+ Weapon[5].name = "DESERT EAGLE";
614+ Weapon[5].model = "./data/model/weapon/de.x";
615+ Weapon[5].texture= "./data/model/weapon/de.bmp";
616+ Weapon[5].attacks = 68;
617+ Weapon[5].penetration = 1;
618+ Weapon[5].blazings = 5;
619+ Weapon[5].speed = 10;
620+ Weapon[5].nbsmax = 7;
621+ Weapon[5].reloads = 41;
622+ Weapon[5].reaction = 13;
623+ Weapon[5].ErrorRangeMIN = 4;
624+ Weapon[5].ErrorRangeMAX = 26;
625+ Weapon[5].mx = 2.0f;
626+ Weapon[5].my = 11.0f;
627+ Weapon[5].mz = 59.0f;
628+ Weapon[5].flashx = 2.0f;
629+ Weapon[5].flashy = 14.0f;
630+ Weapon[5].flashz = 75.0f;
631+ Weapon[5].yakkyou_px = 2.0f;
632+ Weapon[5].yakkyou_py = 15.0f;
633+ Weapon[5].yakkyou_pz = 56.0f;
634+ Weapon[5].yakkyou_sx = 5.0f;
635+ Weapon[5].yakkyou_sy = 4.0f;
636+ Weapon[5].blazingmode = false;
637+ Weapon[5].scopemode = 0;
638+ Weapon[5].size = 11.0f;
639+ Weapon[5].soundid = 2;
640+ Weapon[5].soundvolume = 96;
641+ Weapon[5].silencer = false;
642+ Weapon[5].WeaponP = 1;
643+ Weapon[5].ChangeWeapon = -1;
644+ Weapon[5].burst = 1;
645+ Weapon[6].name = "MAC10";
646+ Weapon[6].model = "./data/model/weapon/mac10.x";
647+ Weapon[6].texture= "./data/model/weapon/mac10.bmp";
648+ Weapon[6].attacks = 47;
649+ Weapon[6].penetration = 0;
650+ Weapon[6].blazings = 3;
651+ Weapon[6].speed = 10;
652+ Weapon[6].nbsmax = 30;
653+ Weapon[6].reloads = 45;
654+ Weapon[6].reaction = 9;
655+ Weapon[6].ErrorRangeMIN = 4;
656+ Weapon[6].ErrorRangeMAX = 25;
657+ Weapon[6].mx = 2.0f;
658+ Weapon[6].my = 4.0f;
659+ Weapon[6].mz = 54.0f;
660+ Weapon[6].flashx = 2.0f;
661+ Weapon[6].flashy = 15.0f;
662+ Weapon[6].flashz = 73.0f;
663+ Weapon[6].yakkyou_px = 2.0f;
664+ Weapon[6].yakkyou_py = 16.0f;
665+ Weapon[6].yakkyou_pz = 52.0f;
666+ Weapon[6].yakkyou_sx = 2.0f;
667+ Weapon[6].yakkyou_sy = 5.0f;
668+ Weapon[6].blazingmode = true;
669+ Weapon[6].scopemode = 0;
670+ Weapon[6].size = 5.5f;
671+ Weapon[6].soundid = 3;
672+ Weapon[6].soundvolume = 90;
673+ Weapon[6].silencer = false;
674+ Weapon[6].WeaponP = 1;
675+ Weapon[6].ChangeWeapon = -1;
676+ Weapon[6].burst = 1;
677+ Weapon[7].name = "UMP";
678+ Weapon[7].model = "./data/model/weapon/ump.x";
679+ Weapon[7].texture= "./data/model/weapon/ump.bmp";
680+ Weapon[7].attacks = 50;
681+ Weapon[7].penetration = 0;
682+ Weapon[7].blazings = 5;
683+ Weapon[7].speed = 10;
684+ Weapon[7].nbsmax = 25;
685+ Weapon[7].reloads = 50;
686+ Weapon[7].reaction = 7;
687+ Weapon[7].ErrorRangeMIN = 2;
688+ Weapon[7].ErrorRangeMAX = 19;
689+ Weapon[7].mx = 8.0f;
690+ Weapon[7].my = 6.0f;
691+ Weapon[7].mz = 28.0f;
692+ Weapon[7].flashx = 8.0f;
693+ Weapon[7].flashy = 13.0f;
694+ Weapon[7].flashz = 64.0f;
695+ Weapon[7].yakkyou_px = 8.0f;
696+ Weapon[7].yakkyou_py = 11.0f;
697+ Weapon[7].yakkyou_pz = 41.0f;
698+ Weapon[7].yakkyou_sx = 4.0f;
699+ Weapon[7].yakkyou_sy = 4.0f;
700+ Weapon[7].blazingmode = true;
701+ Weapon[7].scopemode = 0;
702+ Weapon[7].size = 6.0f;
703+ Weapon[7].soundid = 4;
704+ Weapon[7].soundvolume = 94;
705+ Weapon[7].silencer = false;
706+ Weapon[7].WeaponP = 0;
707+ Weapon[7].ChangeWeapon = -1;
708+ Weapon[7].burst = 1;
709+ Weapon[8].name = "P90";
710+ Weapon[8].model = "./data/model/weapon/p90.x";
711+ Weapon[8].texture= "./data/model/weapon/p90.bmp";
712+ Weapon[8].attacks = 42;
713+ Weapon[8].penetration = 1;
714+ Weapon[8].blazings = 4;
715+ Weapon[8].speed = 11;
716+ Weapon[8].nbsmax = 50;
717+ Weapon[8].reloads = 68;
718+ Weapon[8].reaction = 6;
719+ Weapon[8].ErrorRangeMIN = 3;
720+ Weapon[8].ErrorRangeMAX = 18;
721+ Weapon[8].mx = 8.0f;
722+ Weapon[8].my = 10.0f;
723+ Weapon[8].mz = 30.0f;
724+ Weapon[8].flashx = 8.0f;
725+ Weapon[8].flashy = 12.0f;
726+ Weapon[8].flashz = 59.0f;
727+ Weapon[8].yakkyou_px = 8.0f;
728+ Weapon[8].yakkyou_py = 4.0f;
729+ Weapon[8].yakkyou_pz = 18.0f;
730+ Weapon[8].yakkyou_sx = -1.0f;
731+ Weapon[8].yakkyou_sy = 0.0f;
732+ Weapon[8].blazingmode = true;
733+ Weapon[8].scopemode = 0;
734+ Weapon[8].size = 6.5f;
735+ Weapon[8].soundid = 3;
736+ Weapon[8].soundvolume = 92;
737+ Weapon[8].silencer = false;
738+ Weapon[8].WeaponP = 0;
739+ Weapon[8].ChangeWeapon = -1;
740+ Weapon[8].burst = 1;
741+ Weapon[9].name = "M4";
742+ Weapon[9].model = "./data/model/weapon/m4.x";
743+ Weapon[9].texture= "./data/model/weapon/m4.bmp";
744+ Weapon[9].attacks = 61;
745+ Weapon[9].penetration = 1;
746+ Weapon[9].blazings = 4;
747+ Weapon[9].speed = 11;
748+ Weapon[9].nbsmax = 30;
749+ Weapon[9].reloads = 54;
750+ Weapon[9].reaction = 8;
751+ Weapon[9].ErrorRangeMIN = 3;
752+ Weapon[9].ErrorRangeMAX = 19;
753+ Weapon[9].mx = 9.0f;
754+ Weapon[9].my = 6.0f;
755+ Weapon[9].mz = 37.0f;
756+ Weapon[9].flashx = 9.0f;
757+ Weapon[9].flashy = 13.0f;
758+ Weapon[9].flashz = 91.0f;
759+ Weapon[9].yakkyou_px = 10.0f;
760+ Weapon[9].yakkyou_py = 12.0f;
761+ Weapon[9].yakkyou_pz = 40.0f;
762+ Weapon[9].yakkyou_sx = 4.0f;
763+ Weapon[9].yakkyou_sy = 6.0f;
764+ Weapon[9].blazingmode = true;
765+ Weapon[9].scopemode = 0;
766+ Weapon[9].size = 6.8f;
767+ Weapon[9].soundid = 3;
768+ Weapon[9].soundvolume = 96;
769+ Weapon[9].silencer = false;
770+ Weapon[9].WeaponP = 0;
771+ Weapon[9].ChangeWeapon = -1;
772+ Weapon[9].burst = 1;
773+ Weapon[10].name = "AK47";
774+ Weapon[10].model = "./data/model/weapon/ak47.x";
775+ Weapon[10].texture= "./data/model/weapon/ak47.bmp";
776+ Weapon[10].attacks = 65;
777+ Weapon[10].penetration = 1;
778+ Weapon[10].blazings = 4;
779+ Weapon[10].speed = 11;
780+ Weapon[10].nbsmax = 30;
781+ Weapon[10].reloads = 52;
782+ Weapon[10].reaction = 9;
783+ Weapon[10].ErrorRangeMIN = 3;
784+ Weapon[10].ErrorRangeMAX = 20;
785+ Weapon[10].mx = 9.0f;
786+ Weapon[10].my = 11.0f;
787+ Weapon[10].mz = 39.0f;
788+ Weapon[10].flashx = 9.0f;
789+ Weapon[10].flashy = 9.0f;
790+ Weapon[10].flashz = 86.0f;
791+ Weapon[10].yakkyou_px = 9.0f;
792+ Weapon[10].yakkyou_py = 12.0f;
793+ Weapon[10].yakkyou_pz = 41.0f;
794+ Weapon[10].yakkyou_sx = 5.0f;
795+ Weapon[10].yakkyou_sy = 5.0f;
796+ Weapon[10].blazingmode = true;
797+ Weapon[10].scopemode = 0;
798+ Weapon[10].size = 6.0f;
799+ Weapon[10].soundid = 1;
800+ Weapon[10].soundvolume = 96;
801+ Weapon[10].silencer = false;
802+ Weapon[10].WeaponP = 0;
803+ Weapon[10].ChangeWeapon = -1;
804+ Weapon[10].burst = 1;
805+ Weapon[11].name = "AUG";
806+ Weapon[11].model = "./data/model/weapon/aug.x";
807+ Weapon[11].texture= "./data/model/weapon/aug.bmp";
808+ Weapon[11].attacks = 60;
809+ Weapon[11].penetration = 1;
810+ Weapon[11].blazings = 5;
811+ Weapon[11].speed = 11;
812+ Weapon[11].nbsmax = 30;
813+ Weapon[11].reloads = 56;
814+ Weapon[11].reaction = 7;
815+ Weapon[11].ErrorRangeMIN = 2;
816+ Weapon[11].ErrorRangeMAX = 18;
817+ Weapon[11].mx = 8.0f;
818+ Weapon[11].my = 10.0f;
819+ Weapon[11].mz = 37.0f;
820+ Weapon[11].flashx = 8.0f;
821+ Weapon[11].flashy = 12.0f;
822+ Weapon[11].flashz = 77.0f;
823+ Weapon[11].yakkyou_px = 8.0f;
824+ Weapon[11].yakkyou_py = 11.0f;
825+ Weapon[11].yakkyou_pz = 15.0f;
826+ Weapon[11].yakkyou_sx = 3.0f;
827+ Weapon[11].yakkyou_sy = 5.0f;
828+ Weapon[11].blazingmode = true;
829+ Weapon[11].scopemode = 1;
830+ Weapon[11].size = 7.8f;
831+ Weapon[11].soundid = 4;
832+ Weapon[11].soundvolume = 98;
833+ Weapon[11].silencer = false;
834+ Weapon[11].WeaponP = 0;
835+ Weapon[11].ChangeWeapon = -1;
836+ Weapon[11].burst = 1;
837+ Weapon[12].name = "M249";
838+ Weapon[12].model = "./data/model/weapon/m249.x";
839+ Weapon[12].texture= "./data/model/weapon/m249.bmp";
840+ Weapon[12].attacks = 59;
841+ Weapon[12].penetration = 1;
842+ Weapon[12].blazings = 4;
843+ Weapon[12].speed = 11;
844+ Weapon[12].nbsmax = 100;
845+ Weapon[12].reloads = 85;
846+ Weapon[12].reaction = 7;
847+ Weapon[12].ErrorRangeMIN = 4;
848+ Weapon[12].ErrorRangeMAX = 22;
849+ Weapon[12].mx = 8.0f;
850+ Weapon[12].my = 12.0f;
851+ Weapon[12].mz = 44.0f;
852+ Weapon[12].flashx = 9.0f;
853+ Weapon[12].flashy = 13.0f;
854+ Weapon[12].flashz = 102.0f;
855+ Weapon[12].yakkyou_px = 9.0f;
856+ Weapon[12].yakkyou_py = 11.0f;
857+ Weapon[12].yakkyou_pz = 45.0f;
858+ Weapon[12].yakkyou_sx = 5.0f;
859+ Weapon[12].yakkyou_sy = 4.0f;
860+ Weapon[12].blazingmode = true;
861+ Weapon[12].scopemode = 0;
862+ Weapon[12].size = 7.5f;
863+ Weapon[12].soundid = 3;
864+ Weapon[12].soundvolume = 98;
865+ Weapon[12].silencer = false;
866+ Weapon[12].WeaponP = 0;
867+ Weapon[12].ChangeWeapon = -1;
868+ Weapon[12].burst = 1;
869+ Weapon[13].name = "GRENADE"; // ID_WEAPON_GRENADE 定数を要設定
870+ Weapon[13].model = "./data/model/weapon/grenade.x";
871+ Weapon[13].texture= "./data/model/weapon/grenade.bmp";
872+ Weapon[13].attacks = 0;
873+ Weapon[13].penetration = 0;
874+ Weapon[13].blazings = 35;
875+ Weapon[13].speed = 0;
876+ Weapon[13].nbsmax = 1;
877+ Weapon[13].reloads = 0;
878+ Weapon[13].reaction = 0;
879+ Weapon[13].ErrorRangeMIN = 6;
880+ Weapon[13].ErrorRangeMAX = 20;
881+ Weapon[13].mx = 1.0f;
882+ Weapon[13].my = 6.0f;
883+ Weapon[13].mz = 57.0f;
884+ Weapon[13].flashx = 1.0f;
885+ Weapon[13].flashy = 6.0f;
886+ Weapon[13].flashz = 57.0f;
887+ Weapon[13].yakkyou_px = 0.0f;
888+ Weapon[13].yakkyou_py = 0.0f;
889+ Weapon[13].yakkyou_pz = 0.0f;
890+ Weapon[13].yakkyou_sx = 0.0f;
891+ Weapon[13].yakkyou_sy = 0.0f;
892+ Weapon[13].blazingmode = false;
893+ Weapon[13].scopemode = 0;
894+ Weapon[13].size = 8.0f;
895+ Weapon[13].soundid = 0;
896+ Weapon[13].soundvolume = 0;
897+ Weapon[13].silencer = false;
898+ Weapon[13].WeaponP = 1;
899+ Weapon[13].ChangeWeapon = -1;
900+ Weapon[13].burst = 1;
901+ Weapon[14].name = "MP5SD";
902+ Weapon[14].model = "./data/model/weapon/mp5sd.x";
903+ Weapon[14].texture= "./data/model/weapon/mp5sd.bmp";
904+ Weapon[14].attacks = 37;
905+ Weapon[14].penetration = 0;
906+ Weapon[14].blazings = 4;
907+ Weapon[14].speed = 9;
908+ Weapon[14].nbsmax = 30;
909+ Weapon[14].reloads = 50;
910+ Weapon[14].reaction = 6;
911+ Weapon[14].ErrorRangeMIN = 2;
912+ Weapon[14].ErrorRangeMAX = 21;
913+ Weapon[14].mx = 7.0f;
914+ Weapon[14].my = 8.0f;
915+ Weapon[14].mz = 35.0f;
916+ Weapon[14].flashx = 8.0f;
917+ Weapon[14].flashy = 12.0f;
918+ Weapon[14].flashz = 84.0f;
919+ Weapon[14].yakkyou_px = 8.0f;
920+ Weapon[14].yakkyou_py = 12.0f;
921+ Weapon[14].yakkyou_pz = 35.0f;
922+ Weapon[14].yakkyou_sx = 5.0f;
923+ Weapon[14].yakkyou_sy = 6.0f;
924+ Weapon[14].blazingmode = true;
925+ Weapon[14].scopemode = 0;
926+ Weapon[14].size = 7.5f;
927+ Weapon[14].soundid = 13;
928+ Weapon[14].soundvolume = 84;
929+ Weapon[14].silencer = true;
930+ Weapon[14].WeaponP = 0;
931+ Weapon[14].ChangeWeapon = -1;
932+ Weapon[14].burst = 1;
933+ Weapon[15].name = "CASE"; // ID_WEAPON_CASE 定数を要設定
934+ Weapon[15].model = "./data/model/weapon/case.x";
935+ Weapon[15].texture= "./data/model/weapon/case.bmp";
936+ Weapon[15].attacks = 0;
937+ Weapon[15].penetration = 0;
938+ Weapon[15].blazings = 0;
939+ Weapon[15].speed = 0;
940+ Weapon[15].nbsmax = 0;
941+ Weapon[15].reloads = 0;
942+ Weapon[15].reaction = 0;
943+ Weapon[15].ErrorRangeMIN = 0;
944+ Weapon[15].ErrorRangeMAX = 0;
945+ Weapon[15].mx = 15.0f;
946+ Weapon[15].my = -2.0f;
947+ Weapon[15].mz = 35.0f;
948+ Weapon[15].flashx = 0.0f;
949+ Weapon[15].flashy = 0.0f;
950+ Weapon[15].flashz = 0.0f;
951+ Weapon[15].yakkyou_px = 0.0f;
952+ Weapon[15].yakkyou_py = 0.0f;
953+ Weapon[15].yakkyou_pz = 0.0f;
954+ Weapon[15].yakkyou_sx = 0.0f;
955+ Weapon[15].yakkyou_sy = 0.0f;
956+ Weapon[15].blazingmode = true;
957+ Weapon[15].scopemode = 0;
958+ Weapon[15].size = 5.0f;
959+ Weapon[15].soundid = 0;
960+ Weapon[15].soundvolume = 0;
961+ Weapon[15].silencer = false;
962+ Weapon[15].WeaponP = 2;
963+ Weapon[15].ChangeWeapon = -1;
964+ Weapon[15].burst = 1;
965+ Weapon[16].name = "GLOCK18 FULL";
966+ Weapon[16].model = "./data/model/weapon/glock18.x";
967+ Weapon[16].texture= "./data/model/weapon/glock18.bmp";
968+ Weapon[16].attacks = 38;
969+ Weapon[16].penetration = 0;
970+ Weapon[16].blazings = 3;
971+ Weapon[16].speed = 9;
972+ Weapon[16].nbsmax = 19;
973+ Weapon[16].reloads = 38;
974+ Weapon[16].reaction = 9;
975+ Weapon[16].ErrorRangeMIN = 4;
976+ Weapon[16].ErrorRangeMAX = 26;
977+ Weapon[16].mx = 2.0f;
978+ Weapon[16].my = 8.0f;
979+ Weapon[16].mz = 56.0f;
980+ Weapon[16].flashx = 2.0f;
981+ Weapon[16].flashy = 13.0f;
982+ Weapon[16].flashz = 70.0f;
983+ Weapon[16].yakkyou_px = 2.0f;
984+ Weapon[16].yakkyou_py = 14.0f;
985+ Weapon[16].yakkyou_pz = 54.0f;
986+ Weapon[16].yakkyou_sx = 4.0f;
987+ Weapon[16].yakkyou_sy = 4.0f;
988+ Weapon[16].blazingmode = true;
989+ Weapon[16].scopemode = 0;
990+ Weapon[16].size = 5.0f;
991+ Weapon[16].soundid = 0;
992+ Weapon[16].soundvolume = 90;
993+ Weapon[16].silencer = false;
994+ Weapon[16].WeaponP = 1;
995+ Weapon[16].ChangeWeapon = 4;
996+ Weapon[16].burst = 1;
997+ Weapon[17].name = "M1911";
998+ Weapon[17].model = "./data/model/weapon/cg.x";
999+ Weapon[17].texture= "./data/model/weapon/cg.bmp";
1000+ Weapon[17].attacks = 46;
1001+ Weapon[17].penetration = 0;
1002+ Weapon[17].blazings = 5;
1003+ Weapon[17].speed = 9;
1004+ Weapon[17].nbsmax = 7;
1005+ Weapon[17].reloads = 35;
1006+ Weapon[17].reaction = 11;
1007+ Weapon[17].ErrorRangeMIN = 5;
1008+ Weapon[17].ErrorRangeMAX = 26;
1009+ Weapon[17].mx = 2.0f;
1010+ Weapon[17].my = 7.0f;
1011+ Weapon[17].mz = 61.0f;
1012+ Weapon[17].flashx = 2.0f;
1013+ Weapon[17].flashy = 14.0f;
1014+ Weapon[17].flashz = 74.0f;
1015+ Weapon[17].yakkyou_px = 2.0f;
1016+ Weapon[17].yakkyou_py = 16.0f;
1017+ Weapon[17].yakkyou_pz = 57.0f;
1018+ Weapon[17].yakkyou_sx = 4.0f;
1019+ Weapon[17].yakkyou_sy = 3.0f;
1020+ Weapon[17].blazingmode = false;
1021+ Weapon[17].scopemode = 0;
1022+ Weapon[17].size = 6.8f;
1023+ Weapon[17].soundid = 3;
1024+ Weapon[17].soundvolume = 94;
1025+ Weapon[17].silencer = false;
1026+ Weapon[17].WeaponP = 1;
1027+ Weapon[17].ChangeWeapon = -1;
1028+ Weapon[17].burst = 1;
1029+ Weapon[18].name = "GLOCK17";
1030+ Weapon[18].model = "./data/model/weapon/glock18.x";
1031+ Weapon[18].texture= "./data/model/weapon/glock17.bmp";
1032+ Weapon[18].attacks = 38;
1033+ Weapon[18].penetration = 0;
1034+ Weapon[18].blazings = 5;
1035+ Weapon[18].speed = 9;
1036+ Weapon[18].nbsmax = 17;
1037+ Weapon[18].reloads = 37;
1038+ Weapon[18].reaction = 9;
1039+ Weapon[18].ErrorRangeMIN = 4;
1040+ Weapon[18].ErrorRangeMAX = 26;
1041+ Weapon[18].mx = 2.0f;
1042+ Weapon[18].my = 8.0f;
1043+ Weapon[18].mz = 56.0f;
1044+ Weapon[18].flashx = 2.0f;
1045+ Weapon[18].flashy = 13.0f;
1046+ Weapon[18].flashz = 70.0f;
1047+ Weapon[18].yakkyou_px = 2.0f;
1048+ Weapon[18].yakkyou_py = 14.0f;
1049+ Weapon[18].yakkyou_pz = 54.0f;
1050+ Weapon[18].yakkyou_sx = 4.0f;
1051+ Weapon[18].yakkyou_sy = 4.0f;
1052+ Weapon[18].blazingmode = false;
1053+ Weapon[18].scopemode = 0;
1054+ Weapon[18].size = 5.0f;
1055+ Weapon[18].soundid = 0;
1056+ Weapon[18].soundvolume = 90;
1057+ Weapon[18].silencer = false;
1058+ Weapon[18].WeaponP = 1;
1059+ Weapon[18].ChangeWeapon = -1;
1060+ Weapon[18].burst = 1;
1061+ Weapon[19].name = "M1";
1062+ Weapon[19].model = "./data/model/weapon/m1.x";
1063+ Weapon[19].texture= "./data/model/weapon/m1.bmp";
1064+ Weapon[19].attacks = 90;
1065+ Weapon[19].penetration = 0;
1066+ Weapon[19].blazings = 8;
1067+ Weapon[19].speed = 9;
1068+ Weapon[19].nbsmax = 7;
1069+ Weapon[19].reloads = 100;
1070+ Weapon[19].reaction = 18;
1071+ Weapon[19].ErrorRangeMIN = 5;
1072+ Weapon[19].ErrorRangeMAX = 23;
1073+ Weapon[19].mx = 8.0f;
1074+ Weapon[19].my = 7.0f;
1075+ Weapon[19].mz = 45.0f;
1076+ Weapon[19].flashx = 8.0f;
1077+ Weapon[19].flashy = 11.0f;
1078+ Weapon[19].flashz = 94.0f;
1079+ Weapon[19].yakkyou_px = 8.0f;
1080+ Weapon[19].yakkyou_py = 11.0f;
1081+ Weapon[19].yakkyou_pz = 42.0f;
1082+ Weapon[19].yakkyou_sx = 2.0f;
1083+ Weapon[19].yakkyou_sy = 4.0f;
1084+ Weapon[19].blazingmode = false;
1085+ Weapon[19].scopemode = 0;
1086+ Weapon[19].size = 7.7f;
1087+ Weapon[19].soundid = 2;
1088+ Weapon[19].soundvolume = 98;
1089+ Weapon[19].silencer = false;
1090+ Weapon[19].WeaponP = 0;
1091+ Weapon[19].ChangeWeapon = -1;
1092+ Weapon[19].burst = 6;
1093+ Weapon[20].name = "FAMAS";
1094+ Weapon[20].model = "./data/model/weapon/famas.x";
1095+ Weapon[20].texture= "./data/model/weapon/famas.bmp";
1096+ Weapon[20].attacks = 55;
1097+ Weapon[20].penetration = 1;
1098+ Weapon[20].blazings = 3;
1099+ Weapon[20].speed = 11;
1100+ Weapon[20].nbsmax = 25;
1101+ Weapon[20].reloads = 55;
1102+ Weapon[20].reaction = 7;
1103+ Weapon[20].ErrorRangeMIN = 3;
1104+ Weapon[20].ErrorRangeMAX = 19;
1105+ Weapon[20].mx = 9.0f;
1106+ Weapon[20].my = 10.0f;
1107+ Weapon[20].mz = 32.0f;
1108+ Weapon[20].flashx = 9.0f;
1109+ Weapon[20].flashy = 12.0f;
1110+ Weapon[20].flashz = 70.0f;
1111+ Weapon[20].yakkyou_px = 9.0f;
1112+ Weapon[20].yakkyou_py = 11.0f;
1113+ Weapon[20].yakkyou_pz = 14.0f;
1114+ Weapon[20].yakkyou_sx = 3.0f;
1115+ Weapon[20].yakkyou_sy = 5.0f;
1116+ Weapon[20].blazingmode = true;
1117+ Weapon[20].scopemode = 0;
1118+ Weapon[20].size = 8.0f;
1119+ Weapon[20].soundid = 4;
1120+ Weapon[20].soundvolume = 96;
1121+ Weapon[20].silencer = false;
1122+ Weapon[20].WeaponP = 0;
1123+ Weapon[20].ChangeWeapon = -1;
1124+ Weapon[20].burst = 1;
1125+ Weapon[21].name = "MK23";
1126+ Weapon[21].model = "./data/model/weapon/mk23.x";
1127+ Weapon[21].texture= "./data/model/weapon/mk23.bmp";
1128+ Weapon[21].attacks = 48;
1129+ Weapon[21].penetration = 0;
1130+ Weapon[21].blazings = 5;
1131+ Weapon[21].speed = 9;
1132+ Weapon[21].nbsmax = 12;
1133+ Weapon[21].reloads = 42;
1134+ Weapon[21].reaction = 10;
1135+ Weapon[21].ErrorRangeMIN = 2;
1136+ Weapon[21].ErrorRangeMAX = 26;
1137+ Weapon[21].mx = 2.0f;
1138+ Weapon[21].my = 11.0f;
1139+ Weapon[21].mz = 60.0f;
1140+ Weapon[21].flashx = 2.0f;
1141+ Weapon[21].flashy = 15.0f;
1142+ Weapon[21].flashz = 74.0f;
1143+ Weapon[21].yakkyou_px = 1.0f;
1144+ Weapon[21].yakkyou_py = 16.0f;
1145+ Weapon[21].yakkyou_pz = 60.0f;
1146+ Weapon[21].yakkyou_sx = 5.0f;
1147+ Weapon[21].yakkyou_sy = 4.0f;
1148+ Weapon[21].blazingmode = false;
1149+ Weapon[21].scopemode = 0;
1150+ Weapon[21].size = 5.0f;
1151+ Weapon[21].soundid = 4;
1152+ Weapon[21].soundvolume = 92;
1153+ Weapon[21].silencer = false;
1154+ Weapon[21].WeaponP = 1;
1155+ Weapon[21].ChangeWeapon = -1;
1156+ Weapon[21].burst = 1;
1157+ Weapon[22].name = "MK23 SD";
1158+ Weapon[22].model = "./data/model/weapon/mk23sd.x";
1159+ Weapon[22].texture= "./data/model/weapon/mk23.bmp";
1160+ Weapon[22].attacks = 39;
1161+ Weapon[22].penetration = 0;
1162+ Weapon[22].blazings = 5;
1163+ Weapon[22].speed = 9;
1164+ Weapon[22].nbsmax = 12;
1165+ Weapon[22].reloads = 43;
1166+ Weapon[22].reaction = 9;
1167+ Weapon[22].ErrorRangeMIN = 3;
1168+ Weapon[22].ErrorRangeMAX = 26;
1169+ Weapon[22].mx = 2.0f;
1170+ Weapon[22].my = 11.0f;
1171+ Weapon[22].mz = 60.0f;
1172+ Weapon[22].flashx = 2.0f;
1173+ Weapon[22].flashy = 15.0f;
1174+ Weapon[22].flashz = 96.0f;
1175+ Weapon[22].yakkyou_px = 1.0f;
1176+ Weapon[22].yakkyou_py = 16.0f;
1177+ Weapon[22].yakkyou_pz = 60.0f;
1178+ Weapon[22].yakkyou_sx = 5.0f;
1179+ Weapon[22].yakkyou_sy = 4.0f;
1180+ Weapon[22].blazingmode = false;
1181+ Weapon[22].scopemode = 0;
1182+ Weapon[22].size = 5.0f;
1183+ Weapon[22].soundid = 13;
1184+ Weapon[22].soundvolume = 86;
1185+ Weapon[22].silencer = true;
1186+ Weapon[22].WeaponP = 1;
1187+ Weapon[22].ChangeWeapon = -1;
1188+ Weapon[22].burst = 1;
1189+
1190+
1191+ //缶
1192+ SmallObject[0].model = "./data/article/can.x";
1193+ SmallObject[0].texture = "./data/article/can.bmp";
1194+ SmallObject[0].decide = 10;
1195+ SmallObject[0].hp = 6;
1196+ SmallObject[0].sound = 0;
1197+ SmallObject[0].jump = 10;
1198+ //パソコン
1199+ SmallObject[1].model = "./data/article/pc.x";
1200+ SmallObject[1].texture = "./data/article/pc.bmp";
1201+ SmallObject[1].decide = 29;
1202+ SmallObject[1].hp = 60;
1203+ SmallObject[1].sound = 0;
1204+ SmallObject[1].jump = 5;
1205+ //パソコン キーボード上
1206+ SmallObject[2].model = "./data/article/pc2.x";
1207+ SmallObject[2].texture = "./data/article/pc.bmp";
1208+ SmallObject[2].decide = 29;
1209+ SmallObject[2].hp = 60;
1210+ SmallObject[2].sound = 0;
1211+ SmallObject[2].jump = 5;
1212+ //パソコン 本体逆
1213+ SmallObject[3].model = "./data/article/pc3.x";
1214+ SmallObject[3].texture = "./data/article/pc.bmp";
1215+ SmallObject[3].decide = 29;
1216+ SmallObject[3].hp = 60;
1217+ SmallObject[3].sound = 0;
1218+ SmallObject[3].jump = 5;
1219+ //パソコン ワイド
1220+ SmallObject[4].model = "./data/article/pc_w.x";
1221+ SmallObject[4].texture = "./data/article/pc.bmp";
1222+ SmallObject[4].decide = 29;
1223+ SmallObject[4].hp = 60;
1224+ SmallObject[4].sound = 0;
1225+ SmallObject[4].jump = 5;
1226+ //パソコン ワイド キーボード上
1227+ SmallObject[5].model = "./data/article/pc2_w.x";
1228+ SmallObject[5].texture = "./data/article/pc.bmp";
1229+ SmallObject[5].decide = 29;
1230+ SmallObject[5].hp = 60;
1231+ SmallObject[5].sound = 0;
1232+ SmallObject[5].jump = 5;
1233+ //パソコン ワイド 本体逆
1234+ SmallObject[6].model = "./data/article/pc3_w.x";
1235+ SmallObject[6].texture = "./data/article/pc.bmp";
1236+ SmallObject[6].decide = 29;
1237+ SmallObject[6].hp = 60;
1238+ SmallObject[6].sound = 0;
1239+ SmallObject[6].jump = 5;
1240+ //椅子
1241+ SmallObject[7].model = "./data/article/isu.x";
1242+ SmallObject[7].texture = "./data/article/isu.bmp";
1243+ SmallObject[7].decide = 56;
1244+ SmallObject[7].hp = 50;
1245+ SmallObject[7].sound = 1;
1246+ SmallObject[7].jump = 6;
1247+ //ダンボール
1248+ SmallObject[8].model = "./data/article/dan.x";
1249+ SmallObject[8].texture = "./data/article/dan.bmp";
1250+ SmallObject[8].decide = 28;
1251+ SmallObject[8].hp = 35;
1252+ SmallObject[8].sound = 1;
1253+ SmallObject[8].jump = 8;
1254+ //パソコン 起動中
1255+ SmallObject[9].model = "./data/article/pc.x";
1256+ SmallObject[9].texture = "./data/article/pc_sw.bmp";
1257+ SmallObject[9].decide = 29;
1258+ SmallObject[9].hp = 60;
1259+ SmallObject[9].sound = 0;
1260+ SmallObject[9].jump = 5;
1261+ //パソコン 起動中 暗
1262+ SmallObject[10].model = "./data/article/pc.x";
1263+ SmallObject[10].texture = "./data/article/pc_d.bmp";
1264+ SmallObject[10].decide = 29;
1265+ SmallObject[10].hp = 60;
1266+ SmallObject[10].sound = 0;
1267+ SmallObject[10].jump = 5;
1268+ //パイロン
1269+ SmallObject[11].model = "./data/article/cone.x";
1270+ SmallObject[11].texture = "./data/article/cone.bmp";
1271+ SmallObject[11].decide = 35;
1272+ SmallObject[11].hp = 30;
1273+ SmallObject[11].sound = 1;
1274+ SmallObject[11].jump = 7;
1275+
1276+
1277+ missionname[0] = "TRAINING YARD";
1278+ missionfullname[0] = "TRAINING YARD training";
1279+ missiondirectory[0] = "data\\map0\\";
1280+ missiontxt[0] = "tr";
1281+ missionname[1] = "UNDERGROUND_EXT";
1282+ missionfullname[1] = "UNDERGROUND extermination";
1283+ missiondirectory[1] = "data\\map5\\";
1284+ missiontxt[1] = "ext";
1285+ missionname[2] = "BUILDING_EXT";
1286+ missionfullname[2] = "BUILDING extermination";
1287+ missiondirectory[2] = "data\\map1\\";
1288+ missiontxt[2] = "ext";
1289+ missionname[3] = "SNOW BASE_EXT";
1290+ missionfullname[3] = "SNOW BASE extermination";
1291+ missiondirectory[3] = "data\\map2\\";
1292+ missiontxt[3] = "ext";
1293+ missionname[4] = "MBASE_EXT";
1294+ missionfullname[4] = "MILITARY BASE extermination";
1295+ missiondirectory[4] = "data\\map4\\";
1296+ missiontxt[4] = "ext";
1297+ missionname[5] = "WAREHOUSE_EXT";
1298+ missionfullname[5] = "WAREHOUSE AREA extermination";
1299+ missiondirectory[5] = "data\\map7\\";
1300+ missiontxt[5] = "ext";
1301+ missionname[6] = "DUEL_EXT";
1302+ missionfullname[6] = "DUEL extermination";
1303+ missiondirectory[6] = "data\\map9\\";
1304+ missiontxt[6] = "ext";
1305+ missionname[7] = "STATION_EXT";
1306+ missionfullname[7] = "SUBWAY STATION extermination";
1307+ missiondirectory[7] = "data\\map6\\";
1308+ missiontxt[7] = "ext";
1309+ missionname[8] = "MAZE_EXT";
1310+ missionfullname[8] = "MAZE extermination";
1311+ missiondirectory[8] = "data\\map13\\";
1312+ missiontxt[8] = "ext";
1313+ missionname[9] = "RUINS_EXT";
1314+ missionfullname[9] = "RUINS extermination";
1315+ missiondirectory[9] = "data\\map14\\";
1316+ missiontxt[9] = "ext";
1317+ missionname[10] = "URBAN_EXT";
1318+ missionfullname[10] = "URBAN extermination";
1319+ missiondirectory[10]= "data\\map8\\";
1320+ missiontxt[10] = "ext";
1321+ missionname[11] = "UNDERGROUND_EXT2";
1322+ missionfullname[11] = "UNDERGROUND extermination2";
1323+ missiondirectory[11]= "data\\map5\\";
1324+ missiontxt[11] = "ext2";
1325+ missionname[12] = "TUNNEL_EXT";
1326+ missionfullname[12] = "TUNNEL extermination";
1327+ missiondirectory[12]= "data\\map12\\";
1328+ missiontxt[12] = "ext";
1329+ missionname[13] = "URBAN_DEF";
1330+ missionfullname[13] = "URBAN defend target";
1331+ missiondirectory[13]= "data\\map8\\";
1332+ missiontxt[13] = "def";
1333+ missionname[14] = "DTOWN_EXT";
1334+ missionfullname[14] = "DESERT TOWN extermination";
1335+ missiondirectory[14]= "data\\map3\\";
1336+ missiontxt[14] = "ext";
1337+ missionname[15] = "URBAN_DEF2";
1338+ missionfullname[15] = "URBAN defend target2";
1339+ missiondirectory[15]= "data\\map8\\";
1340+ missiontxt[15] = "def2";
1341+ missionname[16] = "WAREHOUSE_KT";
1342+ missionfullname[16] = "WAREHOUSE AREA kill the target";
1343+ missiondirectory[16]= "data\\map7\\";
1344+ missiontxt[16] = "kt";
1345+ missionname[17] = "RUINS_RE";
1346+ missionfullname[17] = "RUINS release";
1347+ missiondirectory[17]= "data\\map14\\";
1348+ missiontxt[17] = "re";
1349+ missionname[18] = "RELIC_CAP";
1350+ missionfullname[18] = "RELIC capture";
1351+ missiondirectory[18]= "data\\map16\\";
1352+ missiontxt[18] = "cap";
1353+ missionname[19] = "MBASE_DE";
1354+ missionfullname[19] = "MILITARY BASE destroy";
1355+ missiondirectory[19]= "data\\map4\\";
1356+ missiontxt[19] = "de";
1357+ missionname[20] = "RUINS_CAP";
1358+ missionfullname[20] = "RUINS capture";
1359+ missiondirectory[20]= "data\\map14\\";
1360+ missiontxt[20] = "cap";
1361+ missionname[21] = "DTOWN_KT";
1362+ missionfullname[21] = "DESERT TOWN kill the target";
1363+ missiondirectory[21]= "data\\map3\\";
1364+ missiontxt[21] = "kt";
1365+ missionname[22] = "SNOW BASE_RE";
1366+ missionfullname[22] = "SNOW BASE release";
1367+ missiondirectory[22]= "data\\map2\\";
1368+ missiontxt[22] = "re";
1369+ missionname[23] = "UNDERGROUND_DEF";
1370+ missionfullname[23] = "UNDERGROUND defend target";
1371+ missiondirectory[23]= "data\\map5\\";
1372+ missiontxt[23] = "def";
1373+ missionname[24] = "TUNNEL_EXT2";
1374+ missionfullname[24] = "TUNNEL extermination2";
1375+ missiondirectory[24]= "data\\map12\\";
1376+ missiontxt[24] = "ext2";
1377+ missionname[25] = "RELIC_DEF";
1378+ missionfullname[25] = "RELIC defend target";
1379+ missiondirectory[25]= "data\\map16\\";
1380+ missiontxt[25] = "def";
1381+ missionname[26] = "URBAN_KT";
1382+ missionfullname[26] = "URBAN kill the target";
1383+ missiondirectory[26]= "data\\map8\\";
1384+ missiontxt[26] = "kt";
1385+ missionname[27] = "ALLEY_KT";
1386+ missionfullname[27] = "ALLEY kill the target";
1387+ missiondirectory[27]= "data\\map10\\";
1388+ missiontxt[27] = "kt";
1389+ missionname[28] = "STATION_KT";
1390+ missionfullname[28] = "SUBWAY STATION kill the target";
1391+ missiondirectory[28]= "data\\map6\\";
1392+ missiontxt[28] = "kt";
1393+ missionname[29] = "WAREHOUSE_DEF";
1394+ missionfullname[29] = "WAREHOUSE AREA defend target";
1395+ missiondirectory[29]= "data\\map7\\";
1396+ missiontxt[29] = "def";
1397+ missionname[30] = "URBAN_KT2";
1398+ missionfullname[30] = "URBAN kill the target2";
1399+ missiondirectory[30]= "data\\map8\\";
1400+ missiontxt[30] = "kt2";
1401+ missionname[31] = "OFFICE_DEF";
1402+ missionfullname[31] = "OFFICE defend target";
1403+ missiondirectory[31]= "data\\map15\\";
1404+ missiontxt[31] = "def";
1405+ missionname[32] = "URBAN_CAP";
1406+ missionfullname[32] = "URBAN capture";
1407+ missiondirectory[32]= "data\\map8\\";
1408+ missiontxt[32] = "cap";
1409+ missionname[33] = "ALLEY_EXT";
1410+ missionfullname[33] = "ALLEY extermination";
1411+ missiondirectory[33]= "data\\map10\\";
1412+ missiontxt[33] = "ext";
1413+ missionname[34] = "TUNNEL_ESC";
1414+ missionfullname[34] = "TUNNEL escape";
1415+ missiondirectory[34]= "data\\map12\\";
1416+ missiontxt[34] = "esc";
1417+ missionname[35] = "MAZE_CAP";
1418+ missionfullname[35] = "MAZE capture";
1419+ missiondirectory[35]= "data\\map13\\";
1420+ missiontxt[35] = "cap";
1421+ missionname[36] = "WAREHOUSE_DEF2";
1422+ missionfullname[36] = "WAREHOUSE AREA defend target2";
1423+ missiondirectory[36]= "data\\map7\\";
1424+ missiontxt[36] = "def2";
1425+ missionname[37] = "RUINS_DE";
1426+ missionfullname[37] = "RUINS destroy";
1427+ missiondirectory[37]= "data\\map14\\";
1428+ missiontxt[37] = "de";
1429+ missionname[38] = "URBAN_KT3";
1430+ missionfullname[38] = "URBAN kill the target3";
1431+ missiondirectory[38]= "data\\map8\\";
1432+ missiontxt[38] = "kt3";
1433+ missionname[39] = "DUEL_EXT2";
1434+ missionfullname[39] = "DUEL extermination2";
1435+ missiondirectory[39]= "data\\map9\\";
1436+ missiontxt[39] = "ext2";
1437+ missionname[40] = "RELIC_EXT";
1438+ missionfullname[40] = "RELIC extermination";
1439+ missiondirectory[40]= "data\\map16\\";
1440+ missiontxt[40] = "ext";
1441+ missionname[41] = "SNOW BASE_DEF";
1442+ missionfullname[41] = "SNOW BASE defend target";
1443+ missiondirectory[41]= "data\\map2\\";
1444+ missiontxt[41] = "def";
1445+ missionname[42] = "BUILDING_KT";
1446+ missionfullname[42] = "BUILDING kill the target";
1447+ missiondirectory[42]= "data\\map1\\";
1448+ missiontxt[42] = "kt";
1449+ missionname[43] = "MAZE_ESC";
1450+ missionfullname[43] = "MAZE escape";
1451+ missiondirectory[43]= "data\\map13\\";
1452+ missiontxt[43] = "esc";
1453+ missionname[44] = "ALLEY_EXT2";
1454+ missionfullname[44] = "ALLEY extermination2";
1455+ missiondirectory[44]= "data\\map10\\";
1456+ missiontxt[44] = "ext2";
1457+ missionname[45] = "MBASE_ESC";
1458+ missionfullname[45] = "MILITARY BASE escape";
1459+ missiondirectory[45]= "data\\map4\\";
1460+ missiontxt[45] = "esc";
1461+ missionname[46] = "DTOWN_DEF";
1462+ missionfullname[46] = "DESERT TOWN defend target";
1463+ missiondirectory[46]= "data\\map3\\";
1464+ missiontxt[46] = "def";
1465+ missionname[47] = "OFFICE_KT";
1466+ missionfullname[47] = "OFFICE kill the target";
1467+ missiondirectory[47]= "data\\map15\\";
1468+ missiontxt[47] = "kt";
1469+ missionname[48] = "BUILDING_DEF";
1470+ missionfullname[48] = "BUILDING defend target";
1471+ missiondirectory[48]= "data\\map1\\";
1472+ missiontxt[48] = "def";
1473+ missionname[49] = "OFFICE_KT2";
1474+ missionfullname[49] = "OFFICE kill the target2";
1475+ missiondirectory[49]= "data\\map15\\";
1476+ missiontxt[49] = "kt2";
1477+ missionname[50] = "MBASE_CAP";
1478+ missionfullname[50] = "MILITARY BASE capture";
1479+ missiondirectory[50]= "data\\map4\\";
1480+ missiontxt[50] = "cap";
1481+ missionname[51] = "TUNNEL_KT";
1482+ missionfullname[51] = "TUNNEL kill the target";
1483+ missiondirectory[51]= "data\\map12\\";
1484+ missiontxt[51] = "kt";
1485+ missionname[52] = "OFFICE_RE";
1486+ missionfullname[52] = "OFFICE release";
1487+ missiondirectory[52]= "data\\map15\\";
1488+ missiontxt[52] = "re";
1489+ missionname[53] = "URBAN_KT4";
1490+ missionfullname[53] = "URBAN kill the target4";
1491+ missiondirectory[53]= "data\\map8\\";
1492+ missiontxt[53] = "kt4";
1493+ missionname[54] = "UNDERGROUND_EXT3";
1494+ missionfullname[54] = "UNDERGROUND extermination3";
1495+ missiondirectory[54]= "data\\map5\\";
1496+ missiontxt[54] = "ext3";
1497+ missionname[55] = "SCHOOL_EXT";
1498+ missionfullname[55] = "SCHOOL extermination";
1499+ missiondirectory[55]= "data\\map11\\";
1500+ missiontxt[55] = "ext";
1501+ missionname[56] = "SCHOOL_EXT2";
1502+ missionfullname[56] = "SCHOOL extermination2";
1503+ missiondirectory[56]= "data\\map11\\";
1504+ missiontxt[56] = "ext2";
1505+ missionname[57] = "SCHOOL_DE";
1506+ missionfullname[57] = "SCHOOL destroy";
1507+ missiondirectory[57]= "data\\map11\\";
1508+ missiontxt[57] = "de";
1509+
1510+
1511+ AIlevel[0].aiming = 1;
1512+ AIlevel[0].attack = 99;
1513+ AIlevel[0].search = 1;
1514+ AIlevel[0].limitserror = 0;
1515+ AIlevel[1].aiming = 1;
1516+ AIlevel[1].attack = 18;
1517+ AIlevel[1].search = 2;
1518+ AIlevel[1].limitserror = 2;
1519+ AIlevel[2].aiming = 2;
1520+ AIlevel[2].attack = 16;
1521+ AIlevel[2].search = 3;
1522+ AIlevel[2].limitserror = 0;
1523+ AIlevel[3].aiming = 3;
1524+ AIlevel[3].attack = 14;
1525+ AIlevel[3].search = 4;
1526+ AIlevel[3].limitserror = 255;
1527+ AIlevel[4].aiming = 4;
1528+ AIlevel[4].attack = 12;
1529+ AIlevel[4].search = 5;
1530+ AIlevel[4].limitserror = 254;
1531+ AIlevel[5].aiming = 5;
1532+ AIlevel[5].attack = 10;
1533+ AIlevel[5].search = 6;
1534+ AIlevel[5].limitserror = 253;
1535+}
1536+
1537+//! @brief 人の設定を取得
1538+//! @param id 番号
1539+//! @param out_data 受け取るHumanParameter型ポインタ
1540+//! @return 成功:0 失敗:1
1541+int ParameterInfo::GetHuman(int id, HumanParameter *out_data)
1542+{
1543+ if( (id < 0)||((TOTAL_PARAMETERINFO_HUMAN -1) < id ) ){ return 1; }
1544+
1545+ *out_data = Human[id];
1546+ return 0;
1547+}
1548+
1549+//! @brief 人のテクスチャファイルのパスを取得
1550+//! @param id 番号
1551+//! @param *out_str 受け取るポインタ
1552+//! @return 成功:0 失敗:1
1553+int ParameterInfo::GetHumanTexturePath(int id, char *out_str)
1554+{
1555+ if( (id < 0)||((TOTAL_HUMANTEXTURE -1) < id ) ){ return 1; }
1556+
1557+ strcpy(out_str, HumanTexturePath[id]);
1558+ return 0;
1559+}
1560+
1561+//! @brief 武器の設定を取得
1562+//! @param id 番号
1563+//! @param out_data 受け取るWeaponParameter型ポインタ
1564+//! @return 成功:0 失敗:1
1565+int ParameterInfo::GetWeapon(int id, WeaponParameter *out_data)
1566+{
1567+ if( (id < 0)||((TOTAL_PARAMETERINFO_WEAPON -1) < id ) ){ return 1; }
1568+
1569+ *out_data = Weapon[id];
1570+ return 0;
1571+}
1572+
1573+//! @brief 小物の設定を取得
1574+//! @param id 番号
1575+//! @param out_data 受け取るSmallObjectParameter型ポインタ
1576+//! @return 成功:0 失敗:1
1577+//! @warning 追加小物の情報は取得できません。追加小物の情報は MIFInterfaceクラス から取得してください。
1578+int ParameterInfo::GetSmallObject(int id, SmallObjectParameter *out_data)
1579+{
1580+ if( (id < 0)||((TOTAL_PARAMETERINFO_SMALLOBJECT -1) < id ) ){ return 1; }
1581+
1582+ *out_data = SmallObject[id];
1583+ return 0;
1584+}
1585+
1586+//! @brief 標準ミッションを取得
1587+//! @param id 番号
1588+//! @param name ミッション識別名を受け取るポインタ (NULL可)
1589+//! @param fullname ミッション正式名称を受け取るポインタ (NULL可)
1590+//! @param directory データの格納先を受け取るポインタ (NULL可)
1591+//! @param txt ファイル名を受け取るポインタ (NULL可)
1592+//! @return 成功:0 失敗:1
1593+//! @note ファイル名・・・ミッション情報ファイル(.txt)とポイントデータファイル(.pd1)に使われる名前
1594+int ParameterInfo::GetOfficialMission(int id, char *name, char *fullname, char* directory, char *txt)
1595+{
1596+ if( (id < 0)||((TOTAL_OFFICIALMISSION -1) < id ) ){ return 1; }
1597+
1598+ if( name != NULL ){ strcpy(name, missionname[id]); }
1599+ if( fullname != NULL ){ strcpy(fullname, missionfullname[id]); }
1600+ if( directory != NULL ){ strcpy(directory, missiondirectory[id]); }
1601+ if( txt != NULL ){ strcpy(txt, missiontxt[id]); }
1602+ return 0;
1603+}
1604+
1605+//! @brief AIレベルの設定(性能値)を取得
1606+//! @param level AIレベル
1607+//! @param out_AIlevel 受け取るAIParameter型ポインタのポインタ(2重ポインタ)
1608+//! @return 成功:0 失敗:1
1609+int ParameterInfo::GetAIlevel(int level, AIParameter **out_AIlevel)
1610+{
1611+ if( (level < 0)||((TOTAL_PARAMETERINFO_AILEVEL -1) < level ) ){ return 1; }
1612+ *out_AIlevel = &(AIlevel[level]);
1613+ return 0;
1614+}
\ No newline at end of file
--- tags/v1.011-20150222/objectmanager.cpp (nonexistent)
+++ tags/v1.011-20150222/objectmanager.cpp (revision 49)
@@ -0,0 +1,2265 @@
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+ if( id == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
768+ decide = (int)( (float)MIFdata->GetAddSmallobjectDecide()*SMALLOBJECT_SCALE );
769+ }
770+ else{
771+ SmallObjectParameter Param;
772+ GameParamInfo->GetSmallObject(id, &Param);
773+ decide = (int)( (float)Param.decide*SMALLOBJECT_SCALE );
774+ }
775+
776+ //貫通力を計算
777+ for(int i=0; i<decide; i++){
778+ attacks = (int)((float)attacks * 0.7f);
779+ }
780+
781+ CheckDist = SmallObject_Dist + 1.0f;
782+ }
783+
784+ //設定を適用(特に攻撃力・貫通力)
785+ in_bullet->SetParamData(attacks, penetration, speed, teamid, humanid, false);
786+ }
787+
788+ return CollideFlag;
789+}
790+
791+//! @brief 弾がマップに当たった処理
792+//! @param x 着弾X座標
793+//! @param y 着弾Y座標
794+//! @param z 着弾Z座標
795+void ObjectManager::HitBulletMap(float x, float y, float z)
796+{
797+ //エフェクト(煙)を表示
798+ 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);
799+
800+ //効果音を再生
801+ GameSound->HitMap(x, y, z);
802+}
803+
804+//! @brief 弾が人に当たった処理
805+//! @param HitHuman_id 人の番号
806+//! @param Hit_id 被弾箇所(頭:0 胴体:1 足:2)
807+//! @param x 被弾X座標
808+//! @param y 被弾Y座標
809+//! @param z 被弾Z座標
810+//! @param brx 水平角度
811+//! @param attacks 攻撃力
812+//! @param Shothuman_id 発射した人の番号
813+void ObjectManager::HitBulletHuman(int HitHuman_id, int Hit_id, float x, float y, float z, float brx, int attacks, int Shothuman_id)
814+{
815+ //使用されていないか、死亡していれば処理しない。
816+ if( HumanIndex[HitHuman_id].GetDrawFlag() == false ){ return; }
817+ if( HumanIndex[HitHuman_id].GetHP() <= 0 ){ return; }
818+
819+ //人にダメージと衝撃を与える
820+ if( Hit_id == 0 ){ HumanIndex[HitHuman_id].HitBulletHead(attacks); }
821+ if( Hit_id == 1 ){ HumanIndex[HitHuman_id].HitBulletUp(attacks); }
822+ if( Hit_id == 2 ){ HumanIndex[HitHuman_id].HitBulletLeg(attacks); }
823+ HumanIndex[HitHuman_id].AddPosOrder(brx, 0.0f, 1.0f);
824+
825+ //エフェクト(血)を表示
826+ SetHumanBlood(x, y, z);
827+
828+ //効果音を再生
829+ GameSound->HitHuman(x, y, z);
830+
831+ //弾を発射した人の成果に加算
832+ Human_ontarget[Shothuman_id] += 1;
833+ if( Hit_id == 0 ){ Human_headshot[Shothuman_id] += 1; }
834+ if( HumanIndex[HitHuman_id].GetHP() <= 0 ){
835+ Human_kill[Shothuman_id] += 1;
836+ }
837+}
838+
839+//! @brief 弾が小物に当たった処理
840+//! @param HitSmallObject_id 小物の番号
841+//! @param x 着弾X座標
842+//! @param y 着弾Y座標
843+//! @param z 着弾Z座標
844+//! @param attacks 攻撃力
845+void ObjectManager::HitBulletSmallObject(int HitSmallObject_id, float x, float y, float z, int attacks)
846+{
847+ int hp;
848+
849+ //使用されていなければ処理しない。
850+ if( SmallObjectIndex[HitSmallObject_id].GetDrawFlag() == false ){ return; }
851+
852+ //体力がなければ処理しない
853+ hp = SmallObjectIndex[HitSmallObject_id].GetHP();
854+ if( hp <= 0 ){ return; }
855+
856+ //小物にダメージを与える
857+ SmallObjectIndex[HitSmallObject_id].HitBullet(attacks);
858+
859+ //エフェクト(煙)を表示
860+ 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);
861+
862+ //効果音を再生
863+ int id;
864+ SmallObjectIndex[HitSmallObject_id].GetParamData(&id, NULL);
865+ GameSound->HitSmallObject(x, y, z, id);
866+}
867+
868+//! @brief 手榴弾のダメージ判定と処理
869+//! @param in_grenade 対象の手榴弾オブジェクト
870+//! @return 当たった:true 当たっていない:false
871+//! @attention 判定を行う対象は「人」と「小物」です。
872+//! @attention ダメージ判定に限らず、ダメージ計算や効果音再生まで一貫して行います。
873+bool ObjectManager::GrenadeExplosion(grenade *in_grenade)
874+{
875+ bool returnflag = false;
876+
877+ //座標を取得
878+ float gx, gy, gz;
879+ int humanid;
880+ in_grenade->GetPosData(&gx, &gy, &gz, NULL, NULL);
881+ in_grenade->GetParamData(NULL, NULL, NULL, NULL, &humanid);
882+
883+ //人に爆風の当たり判定
884+ for(int i=0; i<MAX_HUMAN; i++){
885+ //初期化されていないか、死亡していれば処理しない。
886+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
887+ if( HumanIndex[i].GetHP() <= 0 ){ continue; }
888+
889+ float hx, hy, hz;
890+ float x, y, z, r;
891+
892+ //人の座標を取得し、距離を計算
893+ HumanIndex[i].GetPosData(&hx, &hy, &hz, NULL);
894+ x = hx - gx;
895+ y = hy - gy;
896+ z = hz - gz;
897+ r = sqrt(x*x + y*y + z*z);
898+
899+ //100.0より遠ければ計算しない
900+ if( r > MAX_DAMAGE_GRENADE_DISTANCE + HUMAN_HEIGTH ){ continue; }
901+
902+ float dummy = 0.0f;
903+ int total_damage = 0;
904+ int damage;
905+
906+ //足元に当たり判定
907+ y = hy + 2.0f - gy;
908+ r = sqrt(x*x + y*y + z*z);
909+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
910+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
911+ //ダメージ量を計算
912+ damage = HUMAN_DAMAGE_GRENADE_LEG - (int)((float)HUMAN_DAMAGE_GRENADE_LEG/MAX_DAMAGE_GRENADE_DISTANCE * r);
913+ if( damage > 0 ){
914+ total_damage += damage;
915+ }
916+ }
917+
918+ //頭に当たり判定
919+ y = hy + 18.0f - gy;
920+ r = sqrt(x*x + y*y + z*z);
921+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
922+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
923+ //ダメージ量を計算
924+ damage = HUMAN_DAMAGE_GRENADE_HEAD - (int)((float)HUMAN_DAMAGE_GRENADE_HEAD/MAX_DAMAGE_GRENADE_DISTANCE * r);
925+ if( damage > 0 ){
926+ total_damage += damage;
927+ }
928+ }
929+
930+ if( total_damage > 0 ){
931+ //ダメージを反映
932+ HumanIndex[i].HitGrenadeExplosion(total_damage);
933+
934+ float y2;
935+ float arx, ary;
936+
937+ //倒していれば、発射した人の成果に加算
938+ if( HumanIndex[i].GetHP() <= 0 ){
939+ Human_kill[humanid] += 1;
940+ }
941+
942+ //エフェクト(血)を表示
943+ SetHumanBlood(hx, hy+15.0f, hz);
944+
945+ //人と手榴弾の距離を算出
946+ x = gx - hx;
947+ y = gy - (hy + 1.0f);
948+ z = gz - hz;
949+
950+ //角度を求める
951+ arx = atan2(z, x);
952+
953+ if( sin(atan2(y, sqrt(x*x + z*z))) < 0.0f ){ //上方向に飛ぶなら、角度を計算
954+ y2 = gy - (hy + HUMAN_HEIGTH);
955+ ary = atan2(y2, sqrt(x*x + z*z)) + (float)M_PI;
956+ }
957+ else{ //下方向に飛ぶなら、垂直角度は無効。(爆風で地面にめり込むのを防止)
958+ ary = 0.0f;
959+ }
960+
961+ //爆風による風圧
962+ HumanIndex[i].AddPosOrder(arx, ary, 2.2f/MAX_DAMAGE_GRENADE_DISTANCE * (MAX_DAMAGE_GRENADE_DISTANCE - sqrt(x*x + y*y + z*z)));
963+
964+ returnflag = true;
965+ }
966+ }
967+
968+ //小物に爆風の当たり判定
969+ for(int i=0; i<MAX_SMALLOBJECT; i++){
970+ //使用されていれば処理しない
971+ if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; }
972+
973+ float sx, sy, sz;
974+ float x, y, z, r;
975+
976+ //小物の座標を取得し、距離を計算
977+ SmallObjectIndex[i].GetPosData(&sx, &sy, &sz, NULL);
978+ x = sx - gx;
979+ y = sy - gy;
980+ z = sz - gz;
981+ r = sqrt(x*x + y*y + z*z);
982+
983+ //100.0より遠ければ計算しない
984+ if( r > MAX_DAMAGE_GRENADE_DISTANCE ){ continue; }
985+
986+ float dummy = 0.0f;
987+
988+ //ブロックが遮っていなければ (レイで当たり判定を行い、当たっていなければ)
989+ if( CollD->CheckALLBlockIntersectRay(gx, gy, gz, x/r, y/r, z/r, NULL, NULL, &dummy, r) == false ){
990+ int id, damage;
991+ SmallObjectIndex[i].GetParamData(&id, NULL);
992+
993+ //ダメージ量を計算し、反映
994+ damage = SMALLOBJECT_DAMAGE_GRENADE - (int)((float)SMALLOBJECT_DAMAGE_GRENADE/MAX_DAMAGE_GRENADE_DISTANCE * r);
995+ SmallObjectIndex[i].HitGrenadeExplosion(damage);
996+
997+ //小物から効果音を発する
998+ GameSound->HitSmallObject(sx, sy, sz, id);
999+
1000+ returnflag = true;
1001+ }
1002+ }
1003+
1004+ //エフェクト(フラッシュ)の表示
1005+ AddEffect(gx, gy, gz, 0.0f, 0.0f, 0.0f, 30.0f, 0.0f, 2, Resource->GetEffectMflashTexture(), EFFECT_NORMAL);
1006+
1007+ //エフェクト(煙)の表示
1008+ float rnd = (float)M_PI/18*GetRand(18);
1009+ 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);
1010+ 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);
1011+ 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);
1012+ 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);
1013+
1014+ //効果音を再生
1015+ GameSound->GrenadeExplosion(gx, gy, gz);
1016+
1017+ return returnflag;
1018+}
1019+
1020+//! @brief 倒れた際のエフェクト設定
1021+//! @param in_human 対象の人オブジェクト
1022+void ObjectManager::DeadEffect(human *in_human)
1023+{
1024+ if( in_human == NULL ){ return; }
1025+
1026+ int paramid;
1027+ float hx, hy, hz, hrx, hry;
1028+ HumanParameter data;
1029+
1030+ //各種パラメーターを取得
1031+ in_human->GetParamData(&paramid, NULL, NULL, NULL);
1032+ in_human->GetPosData(&hx, &hy, &hz, &hrx);
1033+ hry = in_human->GetDeadRy();
1034+
1035+ //設定値を取得
1036+ if( GameParamInfo->GetHuman(paramid, &data) != 0 ){ return; }
1037+
1038+ //もしロボットならば
1039+ if( data.type == 1 ){
1040+
1041+ //腰辺りの座標を算出
1042+ hx += cos(hrx*-1 - (float)M_PI/2) * sin(hry) * HUMAN_HEIGTH/2;
1043+ hz += sin(hrx*-1 - (float)M_PI/2) * sin(hry) * HUMAN_HEIGTH/2;
1044+
1045+ //エフェクト(煙)の表示
1046+ float rnd = (float)M_PI/18*GetRand(18);
1047+ 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);
1048+ 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);
1049+ 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);
1050+ 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);
1051+ }
1052+}
1053+
1054+//! @brief 武器を拾う
1055+//! @param in_human 対象の人オブジェクト
1056+//! @param in_weapon 対象の武器オブジェクト
1057+void ObjectManager::PickupWeapon(human *in_human, weapon *in_weapon)
1058+{
1059+ //無効な人ならば処理しない
1060+ if( in_human->GetDrawFlag() == false ){ return; }
1061+ if( in_human->GetHP() <= 0 ){ return; }
1062+
1063+ //初期化されている武器で、かつ誰も使っていない武器ならば〜
1064+ if( (in_weapon->GetDrawFlag() == true)&&(in_weapon->GetUsingFlag() == false) ){
1065+ float human_x, human_y, human_z;
1066+ float weapon_x, weapon_y, weapon_z;
1067+ float x, z;
1068+ float r;
1069+
1070+ //人と武器の座標を取得
1071+ in_human->GetPosData(&human_x, &human_y, &human_z, NULL);
1072+ in_weapon->GetPosData(&weapon_x, &weapon_y, &weapon_z, NULL);
1073+
1074+ //高さが範囲内ならば
1075+ if( (human_y-2.0f <= weapon_y)&&(human_y+16.0f > weapon_y) ){
1076+ //距離を計算
1077+ x = human_x - weapon_x;
1078+ z = human_z - weapon_z;
1079+ r = x*x + z*z;
1080+ //距離も範囲内ならば、拾わせる。
1081+ if( r < (5.0f * 5.0f) ){
1082+ in_human->PickupWeapon(in_weapon);
1083+ }
1084+ }
1085+ }
1086+}
1087+
1088+//! @brief オブジェクトを解放
1089+void ObjectManager::CleanupPointDataToObject()
1090+{
1091+ for(int i=0; i<MAX_HUMAN; i++){
1092+ HumanIndex[i].SetDrawFlag(false);
1093+ }
1094+
1095+ for(int i=0; i<MAX_WEAPON; i++){
1096+ WeaponIndex[i].SetDrawFlag(false);
1097+ }
1098+
1099+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1100+ SmallObjectIndex[i].SetDrawFlag(false);
1101+ }
1102+
1103+ for(int i=0; i<MAX_BULLET; i++){
1104+ BulletIndex[i].SetDrawFlag(false);
1105+ }
1106+
1107+ for(int i=0; i<MAX_GRENADE; i++){
1108+ GrenadeIndex[i].SetDrawFlag(false);
1109+ }
1110+
1111+ for(int i=0; i<MAX_EFFECT; i++){
1112+ EffectIndex[i].SetDrawFlag(false);
1113+ }
1114+
1115+
1116+ if( Resource != NULL ){
1117+ Resource->CleanupHumanTexture();
1118+ }
1119+}
1120+
1121+//! @brief ポイントデータを元にオブジェクトを配置
1122+void ObjectManager::LoadPointData()
1123+{
1124+ Player_HumanID = 0;
1125+
1126+ /*
1127+ //人情報ポイントを探す
1128+ for(int i=0; i<PointData->GetTotaldatas(); i++){
1129+ pointdata data;
1130+ PointData->Getdata(&data, i);
1131+
1132+ if( data.p1 == 4 ){
1133+ //人のテクスチャを登録
1134+ Resource->AddHumanTexture(data.p2);
1135+ }
1136+ }
1137+ */
1138+
1139+ //人・武器・小物を探す
1140+ for(int i=0; i<PointData->GetTotaldatas(); i++){
1141+ pointdata data;
1142+ PointData->Getdata(&data, i);
1143+
1144+ //人ならば
1145+ if( (data.p1 == 1)||(data.p1 == 6) ){
1146+ pointdata humaninfodata;
1147+
1148+ //人情報ポイントを探す
1149+ if( PointData->SearchPointdata(&humaninfodata, 0x01 + 0x08, 4, 0, 0, data.p2, 0) == 0 ){
1150+ //continue;
1151+
1152+ //人情報ポイントが見つからなかったら、とりあえず「特殊 黒 A」として追加。(バグの再現)
1153+
1154+ HumanParameter HumanParam;
1155+ int Weapon[TOTAL_HAVEWEAPON];
1156+ GameParamInfo->GetHuman(0, &HumanParam);
1157+ for(int j=0; j<TOTAL_HAVEWEAPON; j++){
1158+ Weapon[j] = HumanParam.Weapon[j];
1159+ }
1160+
1161+ //人のテクスチャを登録
1162+ Resource->AddHumanTexture(0);
1163+
1164+ //人を追加
1165+ if( data.p1 == 6 ){
1166+ Weapon[1] = ID_WEAPON_NONE;
1167+ }
1168+
1169+ //プレイヤーならば、番号を記録
1170+ if( (data.p4 == 0)&&(Player_HumanID == 0) ){
1171+ Player_HumanID = AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon);
1172+ }
1173+ else{
1174+ AddHumanIndex(data.x, data.y, data.z, data.r, 0, i, Weapon);
1175+ }
1176+ }
1177+ else{
1178+ //人のテクスチャを登録
1179+ Resource->AddHumanTexture(humaninfodata.p2);
1180+
1181+ //人として追加
1182+ AddHumanIndex(data, humaninfodata);
1183+ }
1184+ }
1185+
1186+ //武器ならば
1187+ if( (data.p1 == 2)||(data.p1 == 7) ){
1188+ AddWeaponIndex(data);
1189+ }
1190+
1191+ //小物ならば
1192+ if( data.p1 == 5 ){
1193+ AddSmallObjectIndex(data);
1194+ }
1195+ }
1196+}
1197+
1198+//! @brief プレイヤー番号を取得
1199+//! @return プレイヤーのデータ番号
1200+int ObjectManager::GetPlayerID()
1201+{
1202+ return Player_HumanID;
1203+}
1204+
1205+//! @brief プレイヤー番号を設定
1206+//! @param id プレイヤーのデータ番号
1207+void ObjectManager::SetPlayerID(int id)
1208+{
1209+ Player_HumanID = id;
1210+}
1211+
1212+//! @brief 指定したデータ番号のhumanクラスを取得
1213+//! @param id データ番号
1214+//! @return 人オブジェクトのポインタ (無効なデータ番号で NULL)
1215+human* ObjectManager::GeHumanObject(int id)
1216+{
1217+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return NULL; }
1218+ return &(HumanIndex[id]);
1219+}
1220+
1221+//! @brief プレイヤーのhumanクラスを取得
1222+//! @return 人オブジェクト(プレイヤー)のポインタ
1223+human* ObjectManager::GetPlayerHumanObject()
1224+{
1225+ return GeHumanObject(Player_HumanID);
1226+}
1227+
1228+//! @brief 指定したデータ番号のweaponクラスを取得
1229+//! @param id データ番号
1230+//! @return 武器オブジェクトのポインタ (無効なデータ番号で NULL)
1231+weapon* ObjectManager::GetWeaponObject(int id)
1232+{
1233+ if( (id < 0)||(MAX_WEAPON-1 < id) ){ return NULL; }
1234+ return &(WeaponIndex[id]);
1235+}
1236+
1237+//! @brief 指定したデータ番号のsmallobjectクラスを取得
1238+//! @param id データ番号
1239+//! @return 小物オブジェクトのポインタ (無効なデータ番号で NULL)
1240+smallobject* ObjectManager::GetSmallObject(int id)
1241+{
1242+ if( (id < 0)||(MAX_SMALLOBJECT-1 < id) ){ return NULL; }
1243+ return &(SmallObjectIndex[id]);
1244+}
1245+
1246+//! @brief 指定したデータ番号のbulletクラスを取得
1247+//! @param id データ番号
1248+//! @return 弾オブジェクトのポインタ (無効なデータ番号で NULL)
1249+bullet* ObjectManager::GetBulletObject(int id)
1250+{
1251+ if( (id < 0)||(MAX_BULLET-1 < id) ){ return NULL; }
1252+ return &(BulletIndex[id]);
1253+}
1254+
1255+//! @brief 使用されていないbulletクラスを取得
1256+//! @return 現在未使用の弾オブジェクトのポインタ (失敗すると NULL)
1257+bullet* ObjectManager::GetNewBulletObject()
1258+{
1259+ for(int i=0; i<MAX_BULLET; i++){
1260+ if( BulletIndex[i].GetDrawFlag() == false ){
1261+ return &(BulletIndex[i]);
1262+ }
1263+ }
1264+ return NULL;
1265+}
1266+
1267+//! @brief 使用されていないgrenadeクラスを取得
1268+//! @return 現在未使用の手榴弾オブジェクトのポインタ (失敗すると NULL)
1269+grenade* ObjectManager::GetNewGrenadeObject()
1270+{
1271+ for(int i=0; i<MAX_GRENADE; i++){
1272+ if( GrenadeIndex[i].GetDrawFlag() == false ){
1273+ return &(GrenadeIndex[i]);
1274+ }
1275+ }
1276+ return NULL;
1277+}
1278+
1279+//! @brief 人を検索
1280+//! @param p4 検索対象の認識番号
1281+//! @return 該当したhumanクラスのポインタ (見つからない場合はNULL)
1282+//! @attention 複数該当する場合、最初に該当したデータを返します。
1283+human* ObjectManager::SearchHuman(signed char p4)
1284+{
1285+ signed char humanp4;
1286+
1287+ for(int i=0; i<MAX_HUMAN; i++){
1288+ //使われていない人ならば処理しない
1289+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
1290+
1291+ //第4パラメータを取得
1292+ HumanIndex[i].GetParamData(NULL, NULL, &humanp4, NULL);
1293+
1294+ //指定されたp4と一致すれば返す
1295+ if( humanp4 == p4 ){
1296+ return &(HumanIndex[i]);
1297+ }
1298+ }
1299+ return NULL;
1300+}
1301+
1302+//! @brief 小物を検索
1303+//! @param p4 検索対象の認識番号
1304+//! @return 該当したsmallobjectクラスのポインタ (見つからない場合はNULL)
1305+//! @attention 複数該当する場合、最初に該当したデータを返します。
1306+smallobject* ObjectManager::SearchSmallobject(signed char p4)
1307+{
1308+ signed char smallobjectp4;
1309+
1310+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1311+ //使われていない人ならば処理しない
1312+ // 【破壊積みのオブジェクトも判定するため、無効】
1313+ //if( SmallObjectIndex[i].GetDrawFlag() == false ){ continue; }
1314+
1315+ //第4パラメータを取得
1316+ SmallObjectIndex[i].GetParamData(NULL, &smallobjectp4);
1317+
1318+ //指定されたp4と一致すれば返す
1319+ if( smallobjectp4 == p4 ){
1320+ return &(SmallObjectIndex[i]);
1321+ }
1322+ }
1323+ return NULL;
1324+}
1325+
1326+//! @brief 前進(走り)を実行
1327+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1328+void ObjectManager::MoveForward(int human_id)
1329+{
1330+ //値の範囲をチェック
1331+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1332+
1333+ //オブジェクトにフラグを設定
1334+ HumanIndex[human_id].SetMoveForward();
1335+
1336+ //走る足音追加
1337+ float posx, posy, posz;
1338+ int teamid;
1339+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1340+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1341+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1342+}
1343+
1344+//! @brief 後退を実行
1345+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1346+void ObjectManager::MoveBack(int human_id)
1347+{
1348+ //値の範囲をチェック
1349+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1350+
1351+ //オブジェクトにフラグを設定
1352+ HumanIndex[human_id].SetMoveBack();
1353+
1354+ //走る足音追加
1355+ float posx, posy, posz;
1356+ int teamid;
1357+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1358+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1359+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1360+}
1361+
1362+//! @brief 左走りを実行
1363+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1364+void ObjectManager::MoveLeft(int human_id)
1365+{
1366+ //値の範囲をチェック
1367+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1368+
1369+ //オブジェクトにフラグを設定
1370+ HumanIndex[human_id].SetMoveLeft();
1371+
1372+ //走る足音追加
1373+ float posx, posy, posz;
1374+ int teamid;
1375+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1376+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1377+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1378+}
1379+
1380+//! @brief 右走りを実行
1381+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1382+void ObjectManager::MoveRight(int human_id)
1383+{
1384+ //値の範囲をチェック
1385+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1386+
1387+ //オブジェクトにフラグを設定
1388+ HumanIndex[human_id].SetMoveRight();
1389+
1390+ //走る足音追加
1391+ float posx, posy, posz;
1392+ int teamid;
1393+ HumanIndex[human_id].GetPosData(&posx, &posy, &posz, NULL);
1394+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &teamid);
1395+ GameSound->SetFootsteps(posx, posy, posz, teamid);
1396+}
1397+
1398+//! @brief 歩きを実行
1399+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1400+void ObjectManager::MoveWalk(int human_id)
1401+{
1402+ //値の範囲をチェック
1403+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1404+
1405+ //オブジェクトにフラグを設定
1406+ HumanIndex[human_id].SetMoveWalk();
1407+}
1408+
1409+//! @brief ジャンプ
1410+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1411+void ObjectManager::MoveJump(int human_id)
1412+{
1413+ //値の範囲をチェック
1414+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1415+
1416+ HumanIndex[human_id].Jump();
1417+}
1418+
1419+//! @brief 発砲
1420+//! @param human_id 発砲する人番号
1421+//! @return 通常弾発射:1 手榴弾発射:2 失敗:0
1422+int ObjectManager::ShotWeapon(int human_id)
1423+{
1424+ //値の範囲をチェック
1425+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return 0; }
1426+
1427+ human *MyHuman = &(HumanIndex[human_id]);
1428+
1429+ float pos_x, pos_y, pos_z;
1430+ int teamid;
1431+ float rotation_x, armrotation_y;
1432+ int weapon_paramid;
1433+ int GunsightErrorRange;
1434+ WeaponParameter ParamData;
1435+ bool playerflag;
1436+ bool grenadeflag;
1437+
1438+ //人の座標と角度を取得
1439+ MyHuman->GetPosData(&pos_x, &pos_y, &pos_z, NULL);
1440+ MyHuman->GetParamData(NULL, NULL, NULL, &teamid);
1441+ MyHuman->GetRxRy(&rotation_x, &armrotation_y);
1442+
1443+ //対象者がプレイヤー自身か判定
1444+ if( MyHuman == &(HumanIndex[Player_HumanID]) ){
1445+ playerflag = true;
1446+ }
1447+ else{
1448+ playerflag = false;
1449+ }
1450+
1451+ //弾の発射を要求
1452+ if( MyHuman->ShotWeapon(&weapon_paramid, &GunsightErrorRange) == false ){ return 0; }
1453+
1454+ //武器の情報を取得
1455+ if( GameParamInfo->GetWeapon(weapon_paramid, &ParamData) != 0 ){ return 0; }
1456+
1457+ //誤差の範囲を計算
1458+ int ErrorRange;
1459+ ErrorRange = GunsightErrorRange;
1460+ if( ErrorRange < ParamData.ErrorRangeMIN ){ ErrorRange = ParamData.ErrorRangeMIN; }
1461+
1462+ //手榴弾か判定
1463+ if( weapon_paramid == ID_WEAPON_GRENADE ){ grenadeflag = true; }
1464+ else{ grenadeflag = false; }
1465+
1466+ class bullet* newbullet;
1467+ class grenade* newgrenade;
1468+
1469+ //(ショットガンなど)発射する弾の数分繰り返す
1470+ for(int i=0; i<ParamData.burst; i++){
1471+ //発射角度を決定
1472+ float rx, ry;
1473+ rx = rotation_x*-1 + (float)M_PI/2;
1474+ ry = armrotation_y;
1475+
1476+ //誤差分 加算する
1477+ float a;
1478+ a = (float)M_PI/180 * GetRand(360);
1479+ rx += cos(a)*ErrorRange * ((float)M_PI/180*0.15f);
1480+ ry += sin(a)*ErrorRange * ((float)M_PI/180*0.15f);
1481+
1482+ //手榴弾でなければ
1483+ if( grenadeflag == false ){
1484+ int attacks;
1485+
1486+ //(ショットガンなど)発射する弾が複数あれば
1487+ if( ParamData.burst > 1 ){
1488+ //1個の弾当たりの攻撃力を算出
1489+ //  全弾合わせて、攻撃力の2倍になるようにする。
1490+ attacks = (int)( (float)ParamData.attacks / ((float)ParamData.burst/2) );
1491+ }
1492+ else{
1493+ //そのまま攻撃力へ反映
1494+ attacks = ParamData.attacks;
1495+ }
1496+
1497+ //発射する未使用のオブジェクトを取得
1498+ newbullet = GetNewBulletObject();
1499+ if( newbullet == NULL ){ break; }
1500+
1501+ //銃弾を発射
1502+ newbullet->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry);
1503+ newbullet->SetParamData(attacks, ParamData.penetration, ParamData.speed * BULLET_SPEEDSCALE, teamid, human_id, true);
1504+ newbullet->SetDrawFlag(true);
1505+ }
1506+ else{
1507+ //発射する未使用のオブジェクトを取得
1508+ newgrenade = GetNewGrenadeObject();
1509+ if( newgrenade == NULL ){ break; }
1510+
1511+ //手榴弾発射
1512+ newgrenade->SetPosData(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, rx, ry);
1513+ newgrenade->SetParamData(8.0f, human_id, true);
1514+ newgrenade->SetDrawFlag(true);
1515+ }
1516+
1517+ //誤差を加算(ショットガン用)
1518+ ErrorRange += ParamData.ErrorRangeMIN;
1519+ }
1520+
1521+ //手榴弾でなければ
1522+ if( grenadeflag == false ){
1523+ //発砲フラグを設定
1524+ Human_ShotFlag[human_id] = true;
1525+ }
1526+
1527+ if( ParamData.soundvolume > 0 ){
1528+ //銃声を再生
1529+ GameSound->ShotWeapon(pos_x, pos_y + WEAPONSHOT_HEIGHT, pos_z, weapon_paramid, teamid, playerflag);
1530+ }
1531+
1532+ if( grenadeflag == true ){
1533+ return 2;
1534+ }
1535+ return 1;
1536+}
1537+
1538+//! @brief マズルフラッシュを設定
1539+//! @param humanid 人の番号
1540+//! @attention この関数の呼び出しタイミングを誤ると、銃口に対してマズルフラッシュが合いません。
1541+void ObjectManager::ShotWeaponEffect(int humanid)
1542+{
1543+ float pos_x, pos_y, pos_z;
1544+ float rotation_x, armrotation_y;
1545+ int weapon_paramid;
1546+ WeaponParameter ParamData;
1547+ float x, y, z;
1548+ float flashsize, smokesize, yakkyousize;
1549+ float rx, mx, my, mz;
1550+
1551+ //人の座標と角度を取得
1552+ HumanIndex[humanid].GetPosData(&pos_x, &pos_y, &pos_z, NULL);
1553+ HumanIndex[humanid].GetRxRy(&rotation_x, &armrotation_y);
1554+
1555+ //武器の情報を取得
1556+ weapon_paramid = HumanIndex[humanid].GetMainWeaponTypeNO();
1557+ if( GameParamInfo->GetWeapon(weapon_paramid, &ParamData) != 0 ){ return; }
1558+
1559+ //マズルフラッシュと煙のサイズを決定
1560+ flashsize = 0.06f * ParamData.attacks;
1561+ smokesize = flashsize;
1562+ yakkyousize = 0.01f * ParamData.attacks;
1563+ if( ParamData.silencer == true ){
1564+ flashsize /= 2;
1565+ }
1566+
1567+ //薬莢の移動量を決定
1568+ rx = rotation_x*-1 + (float)M_PI/2;
1569+ mx = cos(rx - (float)M_PI/2) * ParamData.yakkyou_sx /10;
1570+ my = (ParamData.yakkyou_sy + (GetRand(3)-1)) /10;
1571+ mz = sin(rx - (float)M_PI/2) * ParamData.yakkyou_sx /10;
1572+
1573+ //行列でエフェクト座標を計算
1574+ 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);
1575+ d3dg->GetWorldTransformPos(&x, &y, &z);
1576+ d3dg->ResetWorldTransform();
1577+
1578+ //マズルフラッシュ描画
1579+ AddEffect(x, y, z, 0.0f, 0.0f, 0.0f, flashsize, (float)M_PI/18*GetRand(18), 1, Resource->GetEffectMflashTexture(), EFFECT_NORMAL);
1580+
1581+ //行列でエフェクト座標を計算
1582+ 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);
1583+ d3dg->GetWorldTransformPos(&x, &y, &z);
1584+ d3dg->ResetWorldTransform();
1585+
1586+ //エフェクト(煙)の表示
1587+ 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);
1588+
1589+ //行列でエフェクト座標を計算
1590+ 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);
1591+ d3dg->GetWorldTransformPos(&x, &y, &z);
1592+ d3dg->ResetWorldTransform();
1593+
1594+ //薬莢描画
1595+ AddEffect(x, y, z, mx, my, mz, yakkyousize, (float)M_PI/18*GetRand(18), (int)(GAMEFPS/2), Resource->GetEffectYakkyouTexture(), EFFECT_ROTATION | EFFECT_FALL);
1596+}
1597+
1598+//! @brief 武器をリロード
1599+//! @param human_id 対象の人番号
1600+void ObjectManager::ReloadWeapon(int human_id)
1601+{
1602+ //値の範囲をチェック
1603+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1604+
1605+ //無効な人ならば処理しない
1606+ if( HumanIndex[human_id].GetDrawFlag() == false ){ return; }
1607+ if( HumanIndex[human_id].GetHP() <= 0 ){ return; }
1608+
1609+ //リロードを実行
1610+ if( HumanIndex[human_id].ReloadWeapon() == true ){
1611+ float x, y, z;
1612+ int id;
1613+
1614+ //人の座標とチーム番号を取得
1615+ HumanIndex[human_id].GetPosData(&x, &y, &z, NULL);
1616+ HumanIndex[human_id].GetParamData(NULL, NULL, NULL, &id);
1617+ y += 16.0f;
1618+
1619+ //音源を配置
1620+ GameSound->ReloadWeapon(x, y, z, id);
1621+ }
1622+}
1623+
1624+//! @brief 武器を切り替える(持ち替える)
1625+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1626+//! @param id 持ち替える武器 (-1 で次の武器)
1627+void ObjectManager::ChangeWeapon(int human_id, int id)
1628+{
1629+ //値の範囲をチェック
1630+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1631+
1632+ HumanIndex[human_id].ChangeWeapon(id);
1633+}
1634+
1635+//! @brief 武器を捨てる
1636+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1637+//! @return 成功:true 失敗:false
1638+bool ObjectManager::DumpWeapon(int human_id)
1639+{
1640+ //値の範囲をチェック
1641+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1642+
1643+ return HumanIndex[human_id].DumpWeapon();
1644+}
1645+
1646+//! @brief スコープモードを切り替え
1647+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1648+void ObjectManager::ChangeScopeMode(int human_id)
1649+{
1650+ //値の範囲をチェック
1651+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return; }
1652+
1653+ if( HumanIndex[human_id].GetScopeMode() == 0 ){ //スコープを使用していなければ、スコープを設定
1654+ HumanIndex[human_id].SetEnableScope();
1655+ }
1656+ else{ //使用中なら、解除
1657+ HumanIndex[human_id].SetDisableScope();
1658+ }
1659+}
1660+
1661+//! @brief 武器のショットモード切り替え
1662+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1663+//! @return 成功:0 失敗:1
1664+int ObjectManager::ChangeShotMode(int human_id)
1665+{
1666+ //値の範囲をチェック
1667+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return 1; }
1668+
1669+ return HumanIndex[human_id].ChangeShotMode();
1670+}
1671+
1672+//! @brief 裏技・所持している武器の弾を追加
1673+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1674+//! @return 成功:true 失敗:false
1675+bool ObjectManager::CheatAddBullet(int human_id)
1676+{
1677+ //値の範囲をチェック
1678+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1679+
1680+ int selectweapon;
1681+ weapon *weapon[TOTAL_HAVEWEAPON];
1682+ int id_param, lnbs, nbs;
1683+ WeaponParameter ParamData;
1684+
1685+ //所持している武器を取得
1686+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1687+ weapon[i] = NULL;
1688+ }
1689+ HumanIndex[human_id].GetWeapon(&selectweapon, weapon);
1690+
1691+ //何かしらの武器を持っていれば
1692+ if( weapon[selectweapon] != NULL ){
1693+ //武器の種類と弾数、武器の設定値を取得
1694+ weapon[selectweapon]->GetParamData(&id_param, &lnbs, &nbs);
1695+ if( GameParamInfo->GetWeapon(id_param, &ParamData) == 0 ){
1696+ //最大弾数分加算し、適用
1697+ nbs += ParamData.nbsmax;
1698+ weapon[selectweapon]->ResetWeaponParam(Resource, id_param, lnbs, nbs);
1699+ return true;
1700+ }
1701+ }
1702+
1703+ return false;
1704+}
1705+
1706+//! @brief 裏技・所持している武器を変更
1707+//! @param human_id 人の番号(0〜MAX_HUMAN-1)
1708+//! @param new_weaponID 新たに設定する武器の種類番号
1709+//! @return 成功:true 失敗:false
1710+bool ObjectManager::CheatNewWeapon(int human_id, int new_weaponID)
1711+{
1712+ //値の範囲をチェック
1713+ if( (human_id < 0)||(MAX_HUMAN <= human_id) ){ return false; }
1714+ if( (new_weaponID < 0)||(TOTAL_PARAMETERINFO_WEAPON <= new_weaponID) ){ return false; }
1715+
1716+ human *myHuman = &(HumanIndex[human_id]);
1717+
1718+ int selectweapon;
1719+ weapon *weapon[TOTAL_HAVEWEAPON];
1720+ int lnbs, nbs;
1721+
1722+ //所持している武器を取得
1723+ for(int i=0; i<TOTAL_HAVEWEAPON; i++){
1724+ weapon[i] = NULL;
1725+ }
1726+ myHuman->GetWeapon(&selectweapon, weapon);
1727+
1728+ //現在武器を所有しておらず、新たに持たせる武器もないなら
1729+ if( (weapon[selectweapon] == NULL)&&(new_weaponID == ID_WEAPON_NONE) ){
1730+ return false; //処理自体が無意味
1731+ }
1732+
1733+ if( weapon[selectweapon] == NULL ){ //武器を所有していなければ
1734+ int dataid = -1;
1735+
1736+ //新しい武器を配置
1737+ dataid = AddVisualWeaponIndex(new_weaponID, false);
1738+
1739+ //武器が配置できれば、武器を持たせる
1740+ if( dataid != -1 ){
1741+ weapon[selectweapon] = &(WeaponIndex[dataid]);
1742+ myHuman->SetWeapon(weapon);
1743+ return true;
1744+ }
1745+ }
1746+ else{ //武器を所有していれば
1747+ if( new_weaponID == ID_WEAPON_NONE ){ //武器を消すなら
1748+ //一度武器を捨てた上で、その武器を削除
1749+ if( myHuman->DumpWeapon() == true ){
1750+ weapon[selectweapon]->SetDrawFlag(false);
1751+ return true;
1752+ }
1753+ }
1754+ else{ //武器を変更するなら
1755+ //武器設定を取得(弾数設定を引き継ぐため)
1756+ weapon[selectweapon]->GetParamData(NULL, &lnbs, &nbs);
1757+
1758+ //武器設定を適用
1759+ weapon[selectweapon]->ResetWeaponParam(Resource, new_weaponID, lnbs, nbs);
1760+
1761+ return true;
1762+ }
1763+ }
1764+
1765+ return false;
1766+}
1767+
1768+//! @brief ゾンビの攻撃を受けるか判定
1769+//! @param MyHuman 攻撃する人オブジェクト(ゾンビ側)のポインタ
1770+//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ
1771+//! @return 成立:true 不成立:false
1772+//! @warning MyHuman はゾンビ以外も指定できます。<b>ゾンビかどうかは判定しない</b>ため、ゾンビであるか予め確認しておく必要があります。
1773+//! @attention 判定のみを実施します。この判定が成立したら HitZombieAttack()関数 を呼び出してください。
1774+bool ObjectManager::CheckZombieAttack(human* MyHuman, human* EnemyHuman)
1775+{
1776+ if( MyHuman == NULL ){ return false; }
1777+ if( EnemyHuman == NULL ){ return false; }
1778+
1779+ //使用されていないか、死亡していれば処理しない。
1780+ if( MyHuman->GetDrawFlag() == false ){ return false; }
1781+ if( MyHuman->GetHP() <= 0 ){ return false; }
1782+ if( EnemyHuman->GetDrawFlag() == false ){ return false; }
1783+ if( EnemyHuman->GetHP() <= 0 ){ return false; }
1784+
1785+ float mx, my, mz, mrx, tx, ty, tz;
1786+ int mteam, tteam;
1787+ float AttackPoint_x, AttackPoint_y, AttackPoint_z;
1788+ float ax, az;
1789+
1790+ MyHuman->GetPosData(&mx, &my, &mz, &mrx);
1791+ MyHuman->GetParamData(NULL, NULL, NULL, &mteam);
1792+ my += VIEW_HEIGHT;
1793+ EnemyHuman->GetPosData(&tx, &ty, &tz, NULL);
1794+ EnemyHuman->GetParamData(NULL, NULL, NULL, &tteam);
1795+ ty += VIEW_HEIGHT;
1796+
1797+ //味方ならば処理しない
1798+ if( mteam == tteam ){ return false; }
1799+
1800+ //攻撃ポイント(腕の先端)を求める
1801+ AttackPoint_x = mx + cos(mrx*-1 + (float)M_PI/2) * 2.0f;
1802+ AttackPoint_y = my + VIEW_HEIGHT - 0.5f;
1803+ AttackPoint_z = mz + sin(mrx*-1 + (float)M_PI/2) * 2.0f;
1804+ ax = AttackPoint_x - tx;
1805+ az = AttackPoint_z - tz;
1806+
1807+ //敵(攻撃対象)が攻撃ポイントに触れていれば、当たっている
1808+ if( (ax*ax + az*az) < 3.3f*3.3f ){
1809+ if( (AttackPoint_y >= ty)&&(AttackPoint_y <= (ty + HUMAN_HEIGTH)) ){
1810+ return true;
1811+ }
1812+ }
1813+
1814+ return false;
1815+}
1816+
1817+//! @brief ゾンビの攻撃を受けた処理
1818+//! @param EnemyHuman 攻撃を受けた人オブジェクトのポインタ
1819+void ObjectManager::HitZombieAttack(human* EnemyHuman)
1820+{
1821+ if( EnemyHuman == NULL ){ return; }
1822+
1823+ //使用されていないか、死亡していれば処理しない。
1824+ if( EnemyHuman->GetDrawFlag() == false ){ return; }
1825+ if( EnemyHuman->GetHP() <= 0 ){ return; }
1826+
1827+ float tx, ty, tz;
1828+
1829+ EnemyHuman->GetPosData(&tx, &ty, &tz, NULL);
1830+ ty += VIEW_HEIGHT;
1831+
1832+ //ダメージなどを計算
1833+ EnemyHuman->HitZombieAttack();
1834+
1835+ //エフェクト(血)を表示
1836+ SetHumanBlood(tx, ty, tz);
1837+
1838+ //効果音を再生
1839+ GameSound->HitHuman(tx, ty, tz);
1840+}
1841+
1842+//! @brief 死者を蘇生する
1843+//! @param id 人の番号(0〜MAX_HUMAN-1)
1844+//! @return true:成功 false:失敗
1845+//! @warning 手ぶらのまま蘇生します
1846+//! @attention 無効な人番号が指定された場合や、指定した人が生存していた場合、あるいは謎人間に対して実行した場合、この関数は失敗します。
1847+bool ObjectManager::HumanResuscitation(int id)
1848+{
1849+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return false; }
1850+
1851+ //使用されていないか、生存していれば処理しない。
1852+ if( HumanIndex[id].GetDrawFlag() == false ){ return false; }
1853+ if( HumanIndex[id].GetDeadFlag() == false ){ return false; }
1854+
1855+ int id_param, dataid, team;
1856+ signed char p4;
1857+ HumanIndex[id].GetParamData(&id_param, &dataid, &p4, &team);
1858+ if( (id_param < 0)||( TOTAL_PARAMETERINFO_HUMAN-1 < id_param) ){ return false; } //謎人間なら処理しない
1859+ HumanIndex[id].SetParamData(id_param, dataid, p4, team, true);
1860+
1861+ return true;
1862+}
1863+
1864+//! @brief ゲームクリアー・ゲームオーバーの判定
1865+//! @return ゲームクリアー:1 ゲームオーバー:2 判定なし:0
1866+//! @attention ゲームクリア―とゲームオーバーが同時に成立する条件では、本家XOPSと同様に「ゲームクリアー」と判定されます。
1867+int ObjectManager::CheckGameOverorComplete()
1868+{
1869+ //メモ:
1870+ //
1871+ // 本来は、ゲームオーバー判定を先に行い、次にゲームクリアー判定を実装した方が効率的です。
1872+ // プレイヤーのHPが 0 ならば即ゲームオーバーとして判定し、敵の中でHPが残っている者を見つけた時点で 判定なし、
1873+ // 2つの条件に当てはまらなければ、自動的にゲームクリアーとなります。
1874+ //
1875+ // しかし、本家XOPSはゲームクリアーの判定を優先するため、先にゲームクリアーの判定を行っています。
1876+ // 生きている敵の数を(総HPとして)数え、敵の数(総HP)が 0 ならば、ゲームクリアーと判定します。
1877+ // まぁこのように1つの関数で処理しようとせずに、ゲームクリアーとゲームオーバーで関数自体を分けても良いのですがね・・。
1878+
1879+ //ゲームクリアー判定
1880+ int MyTeamid, teamid;
1881+ int TotalEnemyHP = 0;
1882+ HumanIndex[Player_HumanID].GetParamData(NULL, NULL, NULL, &MyTeamid); //プレイヤーのチーム番号を取得
1883+ for(int i=0; i<MAX_HUMAN; i++){
1884+ //初期化されていなければ処理しない
1885+ if( HumanIndex[i].GetDrawFlag() == false ){ continue; }
1886+
1887+ //調べる対象のチーム番号を取得
1888+ HumanIndex[i].GetParamData(NULL, NULL, NULL, &teamid);
1889+
1890+ //異なるチーム番号(=敵)ならば
1891+ if( teamid != MyTeamid ){
1892+ //生きていれば、敵のHPとして加算
1893+ //if( HumanIndex[i].GetHP() > 0 ){
1894+ if( HumanIndex[i].GetDeadFlag() == false ){
1895+ TotalEnemyHP += HumanIndex[i].GetHP();
1896+ }
1897+ }
1898+ }
1899+ if( TotalEnemyHP == 0 ){ //全敵のHPが 0 ならば
1900+ return 1;
1901+ }
1902+
1903+
1904+ //ゲームオーバー判定
1905+ if( HumanIndex[Player_HumanID].GetDrawFlag() == true ){ //操作対象が有効ならば (注:裏技による変更対策)
1906+ if( HumanIndex[Player_HumanID].GetDeadFlag() == true ){ //プレイヤーが死亡していれば
1907+ return 2;
1908+ }
1909+ }
1910+
1911+ return 0;
1912+}
1913+
1914+//! @brief オブジェクトの情報を取得
1915+//! @param camera_x カメラのX座標
1916+//! @param camera_y カメラのY座標
1917+//! @param camera_z カメラのZ座標
1918+//! @param camera_rx カメラの横軸角度
1919+//! @param camera_ry カメラの縦軸角度
1920+//! @param color 色を取得するポインタ
1921+//! @param infostr 文字を取得するポインタ
1922+//! @return 表示情報あり:true 表示情報なし:false
1923+bool ObjectManager::GetObjectInfoTag(float camera_x, float camera_y, float camera_z, float camera_rx, float camera_ry, int *color, char *infostr)
1924+{
1925+ float dist = 50.0f;
1926+ float px, py, pz;
1927+ float rx, ry;
1928+ float r;
1929+ int Player_teamID;
1930+
1931+ //文字を初期化
1932+ infostr[0] = NULL;
1933+
1934+ //プレイヤーのチーム番号を取得
1935+ HumanIndex[Player_HumanID].GetParamData(NULL, NULL, NULL, &Player_teamID);
1936+
1937+ //人
1938+ for(int i=0; i<MAX_HUMAN; i++){
1939+ //プレイヤー自身なら処理しない
1940+ if( i == Player_HumanID ){ continue; }
1941+
1942+ if( HumanIndex[i].GetDrawFlag() == true ){
1943+ HumanIndex[i].GetPosData(&px, &py, &pz, NULL);
1944+
1945+ //視点を基準に対象までの角度を算出
1946+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, 0.0f, px, py, pz, dist, &rx, NULL, &r) == true ){
1947+ int team;
1948+
1949+ //角度上、視界に入っていれば
1950+ if( abs(rx) < (float)M_PI/18 ){
1951+ HumanIndex[i].GetParamData(NULL, NULL, NULL, &team);
1952+ if( team == Player_teamID ){
1953+ *color = d3dg->GetColorCode(0.0f,0.0f,1.0f,1.0f);
1954+ sprintf(infostr, "Human[%d] HP %d : Friend", i, HumanIndex[i].GetHP());
1955+ }
1956+ else{
1957+ *color = d3dg->GetColorCode(1.0f,0.0f,0.0f,1.0f);
1958+ sprintf(infostr, "Human[%d] HP %d : Enemy", i, HumanIndex[i].GetHP());
1959+ }
1960+ dist = sqrt(r);
1961+ }
1962+ }
1963+ }
1964+ }
1965+
1966+ //武器
1967+ for(int i=0; i<MAX_WEAPON; i++){
1968+ if( (WeaponIndex[i].GetDrawFlag() == true)&&(WeaponIndex[i].GetUsingFlag() == false) ){
1969+ int lnbs, nbs;
1970+
1971+ WeaponIndex[i].GetPosData(&px, &py, &pz, NULL);
1972+ WeaponIndex[i].GetParamData(NULL, &lnbs, &nbs);
1973+
1974+ //視点を基準に対象までの角度を算出
1975+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, camera_ry, px, py, pz, dist, &rx, &ry, &r) == true ){
1976+ //角度上、視界に入っていれば
1977+ if( (abs(rx) < (float)M_PI/18)&&(abs(ry) < (float)M_PI/18) ){
1978+ *color = d3dg->GetColorCode(0.0f,1.0f,0.0f,1.0f);
1979+ sprintf(infostr, "Weapon[%d] %d:%d", i, lnbs, (nbs - lnbs));
1980+ dist = sqrt(r);
1981+ }
1982+ }
1983+ }
1984+ }
1985+
1986+ //小物
1987+ for(int i=0; i<MAX_SMALLOBJECT; i++){
1988+ if( SmallObjectIndex[i].GetDrawFlag() == true ){
1989+ SmallObjectIndex[i].GetPosData(&px, &py, &pz, NULL);
1990+
1991+ //視点を基準に対象までの角度を算出
1992+ if( CheckTargetAngle(camera_x, camera_y, camera_z, camera_rx, camera_ry, px, py, pz, dist, &rx, &ry, &r) == true ){
1993+ //角度上、視界に入っていれば
1994+ if( (abs(rx) < (float)M_PI/18)&&(abs(ry) < (float)M_PI/18) ){
1995+ *color = d3dg->GetColorCode(1.0f,1.0f,0.0f,1.0f);
1996+ sprintf(infostr, "SmallObject[%d] HP %d", i, SmallObjectIndex[i].GetHP());
1997+ dist = sqrt(r);
1998+ }
1999+ }
2000+ }
2001+ }
2002+
2003+ //文字が設定されているかどうかで、有効な処理がされたか判定。
2004+ if( infostr[0] == NULL ){
2005+ return false;
2006+ }
2007+ return true;
2008+}
2009+
2010+//! @brief オブジェクトの主計算処理
2011+//! @param cmdF5id 上昇機能(F5裏技)させる人データ番号(-1で機能無効)
2012+//! @param camera_rx カメラの横軸角度
2013+//! @param camera_ry カメラの縦軸角度
2014+//! @return 常に 0
2015+//! @attention 一般的に cmdF5id は、F5裏技使用中はプレイヤー番号(GetPlayerID()関数で取得)、未使用時は -1 を指定します。
2016+int ObjectManager::Process(int cmdF5id, float camera_rx, float camera_ry)
2017+{
2018+ //このフレームの戦歴を初期化
2019+ for(int i=0; i<MAX_HUMAN; i++){
2020+ Human_ontarget[i] = 0;
2021+ Human_kill[i] = 0;
2022+ Human_headshot[i] = 0;
2023+ }
2024+
2025+ //人オブジェクトの処理
2026+ for(int i=0; i<MAX_HUMAN; i++){
2027+ bool cmdF5;
2028+
2029+ if( i == cmdF5id ){
2030+ cmdF5 = true;
2031+ }
2032+ else{
2033+ cmdF5 = false;
2034+ }
2035+
2036+ if( HumanIndex[i].RunFrame(CollD, BlockData, cmdF5) == 2 ){
2037+ //死亡時のエフェクト
2038+ DeadEffect(&(HumanIndex[i]));
2039+ }
2040+ }
2041+
2042+ //武器オブジェクトの処理
2043+ for(int i=0; i<MAX_WEAPON; i++){
2044+ WeaponIndex[i].RunFrame(CollD);
2045+ }
2046+
2047+ //小物オブジェクトの処理
2048+ for(int i=0; i<MAX_SMALLOBJECT; i++){
2049+ SmallObjectIndex[i].RunFrame();
2050+ }
2051+
2052+ //弾オブジェクトの処理
2053+ for(int i=0; i<MAX_BULLET; i++){
2054+ float bx, by, bz, brx, bry;
2055+ int speed;
2056+ float mx, my, mz;
2057+
2058+ CollideBullet(&BulletIndex[i]); //当たり判定を実行
2059+ BulletIndex[i].RunFrame(); //主計算
2060+
2061+ if( BulletIndex[i].GetDrawFlag() == true ){
2062+ //弾の座標と角度を取得
2063+ BulletIndex[i].GetParamData(NULL, NULL, &speed, NULL, NULL);
2064+ BulletIndex[i].GetPosData(&bx, &by, &bz, &brx, &bry);
2065+ mx = cos(brx)*cos(bry)*speed;
2066+ my = sin(bry)*speed;
2067+ mz = sin(brx)*cos(bry)*speed;
2068+ GameSound->PassingBullet(bx, by, bz, mx, my, mz);
2069+ }
2070+ }
2071+
2072+ //武器を発砲した際のエフェクトを出す
2073+ for(int i=0; i<MAX_HUMAN; i++){
2074+ if( Human_ShotFlag[i] == true ){
2075+ ShotWeaponEffect(i);
2076+ Human_ShotFlag[i] = false;
2077+ }
2078+ }
2079+
2080+ //エフェクトオブジェクトの処理
2081+ for(int i=0; i<MAX_EFFECT; i++){
2082+ EffectIndex[i].RunFrame(camera_rx, camera_ry);
2083+ }
2084+
2085+ //手榴弾の処理
2086+ for(int i=0; i<MAX_GRENADE; i++){
2087+ float speed = GrenadeIndex[i].GetSpeed();
2088+
2089+ //主計算
2090+ int rcr = GrenadeIndex[i].RunFrame(CollD, BlockData);
2091+
2092+ //バウンド・跳ね返ったならば
2093+ if( rcr == 1 ){
2094+ if( speed > 3.4f ){
2095+ //座標を取得し、効果音再生
2096+ float x, y, z;
2097+ GrenadeIndex[i].GetPosData(&x, &y, &z, NULL, NULL);
2098+ GameSound->GrenadeBound(x, y, z);
2099+ }
2100+ }
2101+
2102+ //爆発したなら
2103+ if( rcr == 2 ){
2104+ GrenadeExplosion(&(GrenadeIndex[i]));
2105+ }
2106+ }
2107+
2108+
2109+ //武器を拾う処理
2110+ for(int i=0; i<MAX_HUMAN; i++){
2111+ //武器を拾うだけで毎フレーム総当たりで処理する意味はないので、各武器2フレームに1回処理にケチってます (^^;
2112+ //フレーム数が偶数目の時は、データ番号が偶数の武器。奇数の時は、奇数の武器を処理。
2113+ for(int j=(framecnt%2); j<MAX_WEAPON; j+=2){
2114+ PickupWeapon(&HumanIndex[i], &WeaponIndex[j]);
2115+ }
2116+ }
2117+
2118+ for(int i=0; i<MAX_HUMAN; i++){
2119+ for(int j=i+1; j<MAX_HUMAN; j++){
2120+ //人同士の当たり判定(押し合い)
2121+ CollideHuman(&HumanIndex[i], &HumanIndex[j]);
2122+ }
2123+ }
2124+
2125+ framecnt += 1;
2126+
2127+ return 0;
2128+}
2129+
2130+//! @brief 現フレームの 命中率・倒した敵の数・ヘットショット数 の取得
2131+//! @param id 取得する人のデータ番号
2132+//! @param ontarget 命中数を受け取るポインタ
2133+//! @param kill 倒した敵の数を受け取るポインタ
2134+//! @param headshot 敵の頭部に命中した数を受け取るポインタ
2135+//! @return 成功:true 失敗:false
2136+bool ObjectManager::GetHumanShotInfo(int id, int *ontarget, int *kill, int *headshot)
2137+{
2138+ if( (id < 0)||(MAX_HUMAN-1 < id) ){ return false; }
2139+ *ontarget = Human_ontarget[id];
2140+ *kill = Human_kill[id];
2141+ *headshot = Human_headshot[id];
2142+ return true;
2143+}
2144+
2145+//! @brief エフェクトをソートする
2146+//! @param camera_x カメラのX座標
2147+//! @param camera_y カメラのY座標
2148+//! @param camera_z カメラのZ座標
2149+//! @param data 結果を受け取る effectdata構造体 (要素数:MAX_EFFECT)
2150+//! @return 有効なエフェクトの数
2151+int ObjectManager::SortEffect(float camera_x, float camera_y, float camera_z, effectdata data[])
2152+{
2153+ int cnt = 0;
2154+
2155+ //カメラからの距離を求めつつ、総数を数える。
2156+ for(int i=0; i<MAX_EFFECT; i++){
2157+ if( EffectIndex[i].GetDrawFlag() == true ){
2158+ float ex, ey, ez;
2159+ float x, y, z;
2160+
2161+ //座標を取得し、距離を計算、データに登録。
2162+ EffectIndex[i].GetPosData(&ex, &ey, &ez, NULL);
2163+ x = ex - camera_x;
2164+ y = ey - camera_y;
2165+ z = ez - camera_z;
2166+ data[cnt].id = i;
2167+ data[cnt].dist = x*x + y*y + z*z;
2168+
2169+ //カウントを加算
2170+ cnt += 1;
2171+ }
2172+ }
2173+
2174+ //単純挿入ソート
2175+ effectdata temp;
2176+ for(int i=1; i<cnt; i++) {
2177+ int j;
2178+ temp = data[i];
2179+ for(j=i; j>0 && data[j-1].dist<temp.dist; j--){
2180+ data[j] = data[j-1];
2181+ }
2182+ data[j] = temp;
2183+ }
2184+
2185+ return cnt;
2186+}
2187+
2188+//! @brief オブジェクトの描画処理
2189+//! @param camera_x カメラのX座標
2190+//! @param camera_y カメラのY座標
2191+//! @param camera_z カメラのZ座標
2192+//! @param HidePlayer プレイヤーの非表示設定 (表示:0 非表示:1 腕と武器のみ表示:2)
2193+void ObjectManager::Render(float camera_x, float camera_y, float camera_z, int HidePlayer)
2194+{
2195+ //ワールド座標を原点へ
2196+ d3dg->ResetWorldTransform();
2197+
2198+ //人描画
2199+ for(int i=0; i<MAX_HUMAN; i++){
2200+ bool DrawArm, player;
2201+
2202+ //腕の表示
2203+ if( HidePlayer == 0 ){
2204+ DrawArm = false;
2205+ }
2206+ else if( Player_HumanID != i ){ // HidePlayer != 0
2207+ DrawArm = false;
2208+ }
2209+ else if( HidePlayer == 2 ){ // Player_HumanID == i
2210+ DrawArm = true;
2211+ }
2212+ else{ // Player_HumanID == i && HidePlayer == 1
2213+ continue; //プレイヤー自身を表示しないならスキップ
2214+ }
2215+
2216+ //プレイヤーかどうか判定
2217+ if( Player_HumanID == i ){
2218+ player = true;
2219+ }
2220+ else{
2221+ player = false;
2222+ }
2223+
2224+ HumanIndex[i].Render(d3dg, Resource, DrawArm, player);
2225+ }
2226+
2227+ //武器描画
2228+ for(int i=0; i<MAX_WEAPON; i++){
2229+ WeaponIndex[i].Render(d3dg);
2230+ }
2231+
2232+ //小物描画
2233+ for(int i=0; i<MAX_SMALLOBJECT; i++){
2234+ SmallObjectIndex[i].Render(d3dg);
2235+ }
2236+
2237+ //弾描画
2238+ for(int i=0; i<MAX_BULLET; i++){
2239+ BulletIndex[i].Render(d3dg);
2240+ }
2241+
2242+ //手榴弾描画
2243+ for(int i=0; i<MAX_GRENADE; i++){
2244+ GrenadeIndex[i].Render(d3dg);
2245+ }
2246+
2247+ //エフェクト描画
2248+ /*
2249+ for(int i=0; i<MAX_EFFECT; i++){
2250+ EffectIndex[i].Render(d3dg);
2251+ }
2252+ */
2253+ effectdata data[MAX_EFFECT];
2254+ int cnt = SortEffect(camera_x, camera_y, camera_z, data);
2255+ for(int i=0; i<cnt; i++) {
2256+ EffectIndex[ data[i].id ].Render(d3dg);
2257+ }
2258+}
2259+
2260+//! @brief データの解放
2261+void ObjectManager::Cleanup()
2262+{
2263+ //ポイントデータ解放
2264+ CleanupPointDataToObject();
2265+}
\ No newline at end of file
--- tags/v1.011-20150222/object.cpp (nonexistent)
+++ tags/v1.011-20150222/object.cpp (revision 49)
@@ -0,0 +1,2614 @@
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+ int jump;
2181+
2182+ //飛び具合を取得
2183+ if( id_parameter == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
2184+ jump = MIFdata->GetAddSmallobjectJump();
2185+ }
2186+ else{
2187+ SmallObjectParameter paramdata;
2188+ Param->GetSmallObject(id_parameter, &paramdata);
2189+ jump = paramdata.jump;
2190+ }
2191+
2192+ //飛ばす
2193+ hp = 0;
2194+ jump_cnt = jump;
2195+
2196+ //姿勢設定
2197+ jump_rx = (float)M_PI/18 * GetRand(36);
2198+ move_rx = (float)jump * 0.04243f;
2199+ add_rx = (float)M_PI/180 * GetRand(20);
2200+ add_ry = (float)M_PI/180 * GetRand(20);
2201+}
2202+
2203+//! @brief 計算を実行(破壊時の移動など)
2204+int smallobject::RunFrame()
2205+{
2206+ //描画されていないか、体力が残っていなければ処理しない。
2207+ if( RenderFlag == false ){ return 0; }
2208+ if( hp > 0 ){ return 0; }
2209+
2210+ int cnt;
2211+ int jump;
2212+
2213+ //飛び具合を取得
2214+ if( id_parameter == TOTAL_PARAMETERINFO_SMALLOBJECT+1 -1 ){
2215+ jump = MIFdata->GetAddSmallobjectJump();
2216+ }
2217+ else{
2218+ SmallObjectParameter paramdata;
2219+ Param->GetSmallObject(id_parameter, &paramdata);
2220+ jump = paramdata.jump;
2221+ }
2222+
2223+ //吹き飛んでいるカウント数を計算
2224+ cnt = jump - jump_cnt;
2225+
2226+ //姿勢から座標・角度を計算
2227+ pos_x += cos(jump_rx) * move_rx;
2228+ pos_y += jump_cnt * 0.1f;
2229+ pos_z += sin(jump_rx) * move_rx;
2230+ rotation_x += add_rx;
2231+ rotation_y += add_ry;
2232+
2233+ jump_cnt -= 1;
2234+
2235+ //1秒飛んでいたら描画終了
2236+ if( cnt > (int)GAMEFPS ){
2237+ RenderFlag = false;
2238+ return 2;
2239+ }
2240+
2241+ return 1;
2242+}
2243+
2244+//! @brief 描画
2245+//! @param d3dg D3DGraphicsのポインタ
2246+void smallobject::Render(D3DGraphics *d3dg)
2247+{
2248+ //クラスが設定されていなければ失敗
2249+ if( d3dg == NULL ){ return; }
2250+
2251+ //初期化されていなければ処理しない。
2252+ if( RenderFlag == false ){ return; }
2253+
2254+ //描画
2255+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, rotation_x, rotation_y, model_size);
2256+ d3dg->RenderModel(id_model, id_texture);
2257+}
2258+
2259+//! @brief コンストラクタ
2260+bullet::bullet(int modelid, int textureid)
2261+{
2262+ model_size = 1.0f;
2263+ id_model = modelid;
2264+ id_texture = textureid;
2265+ RenderFlag = false;
2266+}
2267+
2268+//! @brief ディストラクタ
2269+bullet::~bullet()
2270+{}
2271+
2272+//! @brief 座標と角度を設定
2273+//! @param x X座標
2274+//! @param y Y座標
2275+//! @param z Z座標
2276+//! @param rx 横軸回転
2277+//! @param ry 縦軸回転
2278+void bullet::SetPosData(float x, float y, float z, float rx, float ry)
2279+{
2280+ pos_x = x;
2281+ pos_y = y;
2282+ pos_z = z;
2283+ rotation_x = rx;
2284+ rotation_y = ry;
2285+}
2286+
2287+//! @brief 設定値を設定
2288+//! @param _attacks 攻撃力
2289+//! @param _penetration 貫通力
2290+//! @param _speed 弾速
2291+//! @param _teamid チーム番号
2292+//! @param _humanid 人のデータ番号
2293+//! @param init オブジェクトを初期化
2294+void bullet::SetParamData(int _attacks, int _penetration, int _speed, int _teamid, int _humanid, bool init)
2295+{
2296+ attacks = _attacks;
2297+ penetration = _penetration;
2298+ speed = _speed;
2299+ teamid = _teamid;
2300+ humanid = _humanid;
2301+
2302+ if( init == true ){
2303+ cnt = 0;
2304+ }
2305+}
2306+
2307+//! @brief 座標と角度を取得
2308+//! @param x X座標を受け取るポインタ(NULL可)
2309+//! @param y Y座標を受け取るポインタ(NULL可)
2310+//! @param z Z座標を受け取るポインタ(NULL可)
2311+//! @param rx 横軸回転を受け取るポインタ(NULL可)
2312+//! @param ry 縦軸回転を受け取るポインタ(NULL可)
2313+void bullet::GetPosData(float *x, float *y, float *z, float *rx, float *ry)
2314+{
2315+ if( x != NULL ){ *x = pos_x; }
2316+ if( y != NULL ){ *y = pos_y; }
2317+ if( z != NULL ){ *z = pos_z; }
2318+ if( rx != NULL ){ *rx = rotation_x; }
2319+ if( ry != NULL ){ *ry = rotation_y; }
2320+}
2321+
2322+//! @brief 設定値を取得
2323+//! @param _attacks 攻撃力を受け取るポインタ(NULL可)
2324+//! @param _penetration 貫通力を受け取るポインタ(NULL可)
2325+//! @param _speed 弾速を受け取るポインタ(NULL可)
2326+//! @param _teamid チーム番号を受け取るポインタ(NULL可)
2327+//! @param _humanid 人のデータ番号を受け取るポインタ(NULL可)
2328+void bullet::GetParamData(int *_attacks, int *_penetration, int *_speed, int *_teamid, int *_humanid)
2329+{
2330+ if( _attacks != NULL ){ *_attacks = attacks; }
2331+ if( _penetration != NULL ){ *_penetration = penetration; }
2332+ if( _speed != NULL ){ *_speed = speed; }
2333+ if( _teamid != NULL ){ *_teamid = teamid; }
2334+ if( _humanid != NULL ){ *_humanid = humanid; }
2335+}
2336+
2337+//! @brief 計算を実行(弾の進行・時間消滅)
2338+int bullet::RunFrame()
2339+{
2340+ //初期化されていなければ処理しない
2341+ if( RenderFlag == false ){ return 0; }
2342+
2343+ //消滅時間を過ぎていれば、オブジェクトを無効化
2344+ if( cnt > BULLET_DESTROYFRAME ){
2345+ RenderFlag = false;
2346+ return 0;
2347+ }
2348+
2349+ //移動処理
2350+ pos_x += cos(rotation_x)*cos(rotation_y)*speed;
2351+ pos_y += sin(rotation_y)*speed;
2352+ pos_z += sin(rotation_x)*cos(rotation_y)*speed;
2353+ cnt += 1;
2354+
2355+ return 0;
2356+}
2357+
2358+//! @brief 描画
2359+//! @param d3dg D3DGraphicsのポインタ
2360+void bullet::Render(class D3DGraphics *d3dg)
2361+{
2362+ //クラスが設定されていなければ失敗
2363+ if( d3dg == NULL ){ return; }
2364+
2365+ //初期化されていなければ処理しない。
2366+ if( RenderFlag == false ){ return; }
2367+
2368+ //弾を移動前だったら描画しない
2369+ // 弾が頭から突き抜けて見える対策
2370+ if( cnt == 0 ){ return; }
2371+
2372+ //描画
2373+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), rotation_y, model_size);
2374+ d3dg->RenderModel(id_model, id_texture);
2375+}
2376+
2377+//! @brief コンストラクタ
2378+grenade::grenade(int modelid, int textureid) : bullet(modelid, textureid)
2379+{
2380+ if( Param != NULL ){
2381+ WeaponParameter ParamData;
2382+ if( Param->GetWeapon(ID_WEAPON_GRENADE, &ParamData) == 0 ){
2383+ model_size = ParamData.size;
2384+ }
2385+ }
2386+}
2387+
2388+//! @brief ディストラクタ
2389+grenade::~grenade()
2390+{}
2391+
2392+//! @brief 座標と情報を設定
2393+//! @param speed 初速
2394+//! @param _humanid 人のデータ番号
2395+//! @param init オブジェクトを初期化
2396+//! @attention 先に SetPosData() を実行してください。
2397+void grenade::SetParamData(float speed, int _humanid, bool init)
2398+{
2399+ move_x = cos(rotation_x) * cos(rotation_y) * speed;
2400+ move_y = sin(rotation_y) * speed;
2401+ move_z = sin(rotation_x) * cos(rotation_y) * speed;
2402+ humanid = _humanid;
2403+
2404+ if( init == true ){
2405+ cnt = 0;
2406+ }
2407+}
2408+
2409+//! @brief 速度を取得
2410+//! @return 速度
2411+float grenade::GetSpeed()
2412+{
2413+ return sqrt(move_x*move_x + move_y*move_y + move_z*move_z);
2414+}
2415+
2416+//! @brief 計算を実行(手榴弾の進行・爆発)
2417+//! @return 爆発:2 バウンド・跳ね返り:1 それ以外:0
2418+int grenade::RunFrame(class Collision *CollD, class BlockDataInterface *inblockdata)
2419+{
2420+ //初期化されていなければ処理しない
2421+ if( RenderFlag == false ){ return 0; }
2422+
2423+ //時間を過ぎていれば、オブジェクトを無効化し、「爆発」として返す。
2424+ if( cnt > GRENADE_DESTROYFRAME ){
2425+ RenderFlag = false;
2426+ return 2;
2427+ }
2428+
2429+ //静止していれば処理しない
2430+ if( (move_x == 0.0f)&&(move_y == 0.0f)&&(move_z == 0.0f) ){
2431+ cnt += 1;
2432+ return 0;
2433+ }
2434+
2435+ /*
2436+ //静止に近い状態ならば、移動処理をしない。
2437+ if( (move_x*move_x + move_y*move_y + move_z*move_z) < 0.1f*0.1f ){
2438+ cnt += 1;
2439+ return 0;
2440+ }
2441+ */
2442+
2443+ //移動速度を計算
2444+ move_x *= 0.98f;
2445+ move_y = (move_y - 0.17f) * 0.98f;
2446+ move_z *= 0.98f;
2447+
2448+ int id, face;
2449+ float Dist;
2450+ float maxDist = sqrt(move_x*move_x + move_y*move_y + move_z*move_z);
2451+
2452+ //マップに対して当たり判定を実行
2453+ if( CollD->CheckALLBlockIntersectRay(pos_x, pos_y, pos_z, move_x/maxDist, move_y/maxDist, move_z/maxDist, &id, &face, &Dist, maxDist) == true ){
2454+ float vx, vy, vz;
2455+
2456+ //マップと衝突する座標まで移動
2457+ pos_x += move_x/maxDist * (Dist - 0.1f);
2458+ pos_y += move_y/maxDist * (Dist - 0.1f);
2459+ pos_z += move_z/maxDist * (Dist - 0.1f);
2460+
2461+ //反射するベクトルを求める
2462+ CollD->ReflectVector(inblockdata, id, face, move_x, move_y, move_z, &vx, &vy, &vz);
2463+
2464+ //減速
2465+ move_x = vx * GRENADE_BOUND_ACCELERATION;
2466+ move_y = vy * GRENADE_BOUND_ACCELERATION;
2467+ move_z = vz * GRENADE_BOUND_ACCELERATION;
2468+
2469+ cnt += 1;
2470+ return 1;
2471+ }
2472+
2473+ //座標を移動
2474+ pos_x += move_x;
2475+ pos_y += move_y;
2476+ pos_z += move_z;
2477+
2478+ cnt += 1;
2479+ return 0;
2480+}
2481+
2482+//! @brief 描画
2483+//! @param d3dg D3DGraphicsのポインタ
2484+void grenade::Render(class D3DGraphics *d3dg)
2485+{
2486+ //クラスが設定されていなければ失敗
2487+ if( d3dg == NULL ){ return; }
2488+
2489+ //初期化されていなければ処理しない。
2490+ if( RenderFlag == false ){ return; }
2491+
2492+ //描画
2493+ d3dg->SetWorldTransform(pos_x, pos_y, pos_z, (rotation_x * -1 - (float)M_PI/2), 0.0f, (float)M_PI/2, model_size);
2494+ d3dg->RenderModel(id_model, id_texture);
2495+}
2496+
2497+//! @brief コンストラクタ
2498+effect::effect(float x, float y, float z, float size, float rotation, int count, int texture, int settype)
2499+{
2500+ pos_x = x;
2501+ pos_y = y;
2502+ pos_z = z;
2503+ model_size = size;
2504+ camera_rx = 0.0f;
2505+ camera_ry = 0.0f;
2506+ rotation_x = rotation;
2507+ cnt = count;
2508+ setcnt = count;
2509+ id_texture = texture;
2510+ type = settype;
2511+ if( cnt > 0 ){
2512+ RenderFlag = true;
2513+ }
2514+ else{
2515+ RenderFlag = false;
2516+ }
2517+ alpha = 1.0f;
2518+}
2519+
2520+//! @brief ディストラクタ
2521+effect::~effect()
2522+{}
2523+
2524+//! @brief 設定値を設定
2525+//! @param in_move_x X軸移動量
2526+//! @param in_move_y Y軸移動量
2527+//! @param in_move_z Z軸移動量
2528+//! @param size 表示倍率
2529+//! @param rotation 回転角度
2530+//! @param count 表示フレーム数
2531+//! @param texture テクスチャの認識番号
2532+//! @param settype エフェクトの種類 (Effect_Type を組み合せる)
2533+//! @param init オブジェクトを初期化
2534+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)
2535+{
2536+ move_x = in_move_x;
2537+ move_y = in_move_y;
2538+ move_z = in_move_z;
2539+ model_size = size;
2540+ rotation_texture = rotation;
2541+ cnt = count;
2542+ setcnt = count;
2543+ id_texture = texture;
2544+ type = settype;
2545+ alpha = 1.0f;
2546+
2547+ if( init == true ){
2548+ camera_rx = 0.0f;
2549+ camera_ry = 0.0f;
2550+ }
2551+}
2552+
2553+//! @brief 計算を実行(ビルボード化)
2554+//! @param in_camera_rx カメラの横軸角度
2555+//! @param in_camera_ry カメラの縦軸角度
2556+//! @return 処理実行:1 描画最終フレーム:2 処理なし:0
2557+int effect::RunFrame(float in_camera_rx, float in_camera_ry)
2558+{
2559+ //初期化されていなければ処理しない
2560+ if( RenderFlag == false ){ return 0; }
2561+
2562+ //カウントが終了したら、処理しないように設定
2563+ if( cnt <= 0 ){
2564+ RenderFlag = false;
2565+ return 2;
2566+ }
2567+
2568+ //カメラ座標を適用
2569+ camera_rx = in_camera_rx;
2570+ camera_ry = in_camera_ry;
2571+
2572+ //座標移動
2573+ pos_x += move_x;
2574+ pos_y += move_y;
2575+ pos_z += move_z;
2576+
2577+ //特殊処理を実行
2578+ if( type & EFFECT_DISAPPEAR ){ //消す
2579+ alpha -= 1.0f/setcnt;
2580+ }
2581+ if( type & EFFECT_MAGNIFY ){ //拡大
2582+ model_size += model_size/50;
2583+ }
2584+ if( type & EFFECT_ROTATION ){ //回転
2585+ if( rotation_texture > 0.0f ){
2586+ rotation_texture += (float)M_PI/180*1;
2587+ }
2588+ else{
2589+ rotation_texture -= (float)M_PI/180*1;
2590+ }
2591+ }
2592+ if( type & EFFECT_FALL ){ //落下
2593+ move_y = (move_y - 0.17f) * 0.98f;
2594+ }
2595+
2596+ //カウントを 1 引く
2597+ cnt -= 1;
2598+ return 1;
2599+}
2600+
2601+//! @brief 描画
2602+//! @param d3dg D3DGraphicsのポインタ
2603+void effect::Render(class D3DGraphics *d3dg)
2604+{
2605+ //クラスが設定されていなければ失敗
2606+ if( d3dg == NULL ){ return; }
2607+
2608+ //初期化されていなければ処理しない。
2609+ if( RenderFlag == false ){ return; }
2610+
2611+ //描画
2612+ d3dg->SetWorldTransformEffect(pos_x, pos_y, pos_z, camera_rx*-1, camera_ry, rotation_texture, model_size);
2613+ d3dg->RenderBoard(id_texture, alpha);
2614+}
\ No newline at end of file
--- tags/v1.011-20150222/ai.cpp (nonexistent)
+++ tags/v1.011-20150222/ai.cpp (revision 49)
@@ -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; <