簡単RPG講座13-7。戦闘システムの7。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

簡単RPG講座13-7。戦闘システムの7。

投稿記事 by softya(ソフト屋) » 14年前

今回は、PSC命令(関数)の説明です。
これを終わればバトル処理モジュールは終了です。
この講座を合わせて初期編は後2回です。がんばりましょう!

[battle.cpp]
バトル処理のプログラム側の続きです。

●(PSC関数)PSC_Exit
バトル終了命令でp1のパラメータをそのまま戻り値にします。
→ PSC_RTN_ENDやPSC_RTN_GAMEVOERなどの値を持って戻すことで終了処理を制御できます。

CODE:

//##############################################################################
//	ここから下はPSCの関数です。↓↓↓
//##############################################################################
//	●(PSC)基本制御系
//##############################################################################

//======================================================================
//	(PSC)バトルを抜ける
//	パラメータ:p1[戻り値]
//======================================================================
static int PSC_Exit(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("バトル終了",0,0);
	
	//	バトル終了codeを持ち帰る。
	return pscData->p1;
}

●(PSC関数)PSC_BattleIn
バトル開始エフェクトの管理を行います。
最初のフレームならバトル描画の状態を強制設定してバトル開始エフェクト状態にします。
指定フレーム(BATTLE_IN_TIME)が経過後は、状態をBATTLE_DRAW_BATTLEに切り替えて次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)バトル開始エフェクト
//	パラメータ:なし
//======================================================================
static int PSC_BattleIn(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("バトル開始",0,0);
	
	//	最初のフレーム?
	if( frame == 0 ) {
		//	バトル描画の状態を強制設定
		STM_ResetState(BattleData.BattleDrawStateObj,BATTLE_DRAW_BATTLEIN);//バトル開始エフェクト
	}
	//	エフェクトフレームの経過。
	if( frame > BATTLE_IN_TIME ) {
		//	次のフレーム描画状態の遷移。
		STM_ChangeState(BattleData.BattleDrawStateObj,BATTLE_DRAW_BATTLE);//バトル中
		//	次のPSCに進む。
		return PSC_RTN_NEXT;
	} else {
		//同じPSCを継続。ただし、バトル開始エフェクト中。
		return 	PSC_RTN_BATTLEIN;
	}
}
●(PSC関数)PSC_AutoMsg
メッセージを自動的に送る自動メッセージ処理を行います。

メッセージウィンドウをアクティブにして、battle_MakePscMsg()でメッセージを組み立てます。
最初のフレームなら、winmng_SetMsg()でMSG_MODE_BTL_AUTOでバトル用自動送りのメッセージ設定を行います。
winmng_UpdateMsg()でメッセージを更新して最後まで表示されたら、次のPSC命令に進みます。

CODE:

//##############################################################################
//	●(PSC)メッセージ系
//##############################################################################

//======================================================================
//	(PSC)バトルメッセージ自動送り
//	パラメータ:str[format]、p1[パラメータ]、p2[パラメータ]
//======================================================================
static int PSC_AutoMsg(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	static char msg[MSG_BUFF_SIZE];	//staticでないと表示できない。
	
	//	メッセージ・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_MSGD);
	
	//	セリフを組み立てる。
	battle_MakePscMsg( msg, pscData );
	
	//	最初のフレーム
	if( frame == 0 ) {
		DEBUG_PSC("メッセージ=%s",msg,0);
		//	メッセージを設定する。自動送りでバトル用。
		winmng_SetMsg(msg,MSG_MODE_BTL_AUTO);
	}
	
	//	毎フレームの更新
	if( winmng_UpdateMsg(BTL_MES_SPEED) ) {
		//	次のPSCに進む。
		return PSC_RTN_NEXT;
	} else {
		//	同じPSCを継続
		return PSC_RTN_CONTINUE;
	}
}
●(PSC関数)PSC_KeyWaitMsg
PSC_AutoMsgとほぼ同様ですが、MSG_MODE_BTL_PAUSEでメッセージを設定するのと最初のフレームは前のメッセージを抜けた処理と同じフレーム内に動くのでキー入力を無視するようになっています。

CODE:

//======================================================================
//	(PSC)バトルメッセージ停止
//	パラメータ:str[format]、p1[パラメータ]、p2[パラメータ]
//======================================================================
static int PSC_KeyWaitMsg(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	static char msg[MSG_BUFF_SIZE];	//staticでないと表示できない。
	
	//	メッセージ・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_MSGD);
	
	//	セリフを組み立てる。
	battle_MakePscMsg( msg, pscData );
	
	//	最初のフレーム
	if( frame == 0 ) {
		DEBUG_PSC("メッセージ=%s",msg,0);
		//	メッセージを設定する。自動送り。
		winmng_SetMsg(msg,MSG_MODE_BTL_PAUSE);
	}
	//	最初のフレームは抜けない?
	int bExit = winmng_UpdateMsg(BTL_MES_SPEED);
	if( frame > 0 ) {
		//	抜ける。
		if( bExit ) {
			//	次のPSCに進む。
			return PSC_RTN_NEXT;
		}
	}
	//	同じPSCを継続
	return PSC_RTN_CONTINUE;
}
●(PSC関数)PSC_ClearMsg
メッセージをクリアします。

CODE:

//======================================================================
//	バトルメッセージクリア
//	パラメータ:なし
//======================================================================
static int PSC_ClearMsg(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("メッセージクリア",0,0);
	
	//	メッセージ・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_MSGD);
	
	//	メッセージをクリア
	winmng_ClearMsg();
	
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_Label
ラベルで特に動作しません。
次のPSC命令に進みます。

CODE:

//##############################################################################
//	●(PSC)ジャンプ・コール系
//##############################################################################

//======================================================================
//	(PSC)ラベル
//	パラメータ:str[ジャンプ先のラベル名]
//======================================================================
static int PSC_Label(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	DEBUG_PSC("ラベル=%s",pscData->str,0);
	
	//	特に何もせず次のPSCに進む。
	return PSC_RTN_NEXT;
}

●(PSC関数)PSC_Jump
パラメータで指定されたラベルにジャンプします。
btlpsc_JumpPSCLabel()がラベルを検索してJUMPする関数です。
JUMP後にラベルの次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)無条件ジャンプ
//	パラメータ:str[ジャンプ先のラベル名]
//======================================================================
static int PSC_Jump(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	DEBUG_PSC("ラベル=%s",pscData->str,0);

	//	無条件ラベルジャンプを行う。
	btlpsc_JumpPSCLabel(pscData->str);
	
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_SelectJump
p1で指定されたPSC変数の値がp2に等しかった場合は、パラメータで指定されたラベルにジャンプします。
ジャンプしなければ、そのまま次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)値条件ジャンプ
//	パラメータ:str[ジャンプ先のラベル名],p1[PSC変数番号],p2[値]
//======================================================================
static int PSC_SelectJump(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	MACRO_ASSERT(pscData->p1>=0);
	MACRO_ASSERT(pscData->p1str,pscData->p1,pscData->p2);
	
	//	条件判断。等しいか。
	if( BattleData.pscVar[pscData->p1] == pscData->p2 ) {
		//	ラベルジャンプを行う。
		btlpsc_JumpPSCLabel(pscData->str);
	}
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_RandJump
p1で指定された値の確率分の一でパラメータで指定されたラベルにジャンプします。
ジャンプしなければ、そのまま次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)ランダムジャンプ
//	パラメータ:str[ジャンプ先のラベル名],p1[確率]
//======================================================================
static int PSC_RandJump(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->p1>=1);
	MACRO_ASSERT(pscData->p1str,pscData->p1,pscData->p2);
	
	//	乱数の確率でジャンプする。数値が大きければ確率は高くなる。
	if( GetRand(pscData->p1-1) > 0 ) {
		//	ラベルジャンプを行う。
		btlpsc_JumpPSCLabel(pscData->str);
	}
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_PlayerDeathJump
主人公が死んでいたらパラメータで指定されたラベルにジャンプします。
ジャンプしなければ、そのまま次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)主人公の死亡ジャンプ
//	パラメータ:str[ジャンプ先のラベル名]
//======================================================================
static int PSC_PlayerDeathJump(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	DEBUG_PSC("ラベル=%s HP=%d",pscData->str,BattleData.playerParam->hp);
	
	//	主人公のHPが0?
	if( BattleData.playerParam->hp == 0 ) {
		//	ラベルジャンプを行う。
		btlpsc_JumpPSCLabel(pscData->str);
	}
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_EnemyDeathJump
敵が死んでいたらパラメータで指定されたラベルにジャンプします。
ジャンプしなければ、そのまま次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)敵の死亡ジャンプ
//	パラメータ:str[ジャンプ先のラベル名]
//======================================================================
static int PSC_EnemyDeathJump(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);
	DEBUG_PSC("ラベル=%s HP=%d",pscData->str,BattleData.enemyParam.hp);
	
	//	主人公のHPが0?
	if( BattleData.enemyParam.hp == 0 ) {
		//	ラベルジャンプを行う。
		btlpsc_JumpPSCLabel(pscData->str);
	}
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_Call
今のPSCポイントを得てスタック(pscCallStack)にPUSHします。
PSC_CallのパラメータをPSC_CallpscDataに保存して、パラメータで指定されたラベルにジャンプします。
JUMP後にラベルの次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)無条件CALL
//	パラメータ:str[ジャンプ先のラベル名],p1[引数1],p2[引数2],p3[引数3],strp1[文字列引数]
//======================================================================
static int PSC_Call(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT(pscData->str!=NULL);

	//	今のPSC位置を得る。
	int pscPoint = btlpsc_CallGetPscPoint();
	//	CALL情報の表示
	DEBUG_PSCP3("ラベル=%s 呼び出し元PSC位置=%d スタック=%d",pscData->str,pscPoint,BattleData.pscCallStackPoint);
	
	//	PSC位置をスタックにPUSHする。
	MACRO_ASSERT( BattleData.pscCallStackPointstr);
	
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_Return
スタック(pscCallStack)からPSCポイントを取り出して、btlpsc_ReturnPscPoint()でジャンプします。
戻り値をPSC変数に保存したら、PSC_Callの次の命令に進みます。

CODE:

//======================================================================
//	(PSC)リターン
//	パラメータ:p1[戻り値]
//======================================================================
static int PSC_Return(PSCData_t *pscData,int frame)
{
	//	スタックからPOPする。
	MACRO_ASSERT( BattleData.pscCallStackPoint>=0 );
	
	int pscPoint = BattleData.pscCallStack[--BattleData.pscCallStackPoint];
	DEBUG_PSC("RETRUN 復帰位置=%d スタック=%d",pscPoint,BattleData.pscCallStackPoint);	
	//	CALLした時のPSCを復元する。
	btlpsc_ReturnPscPoint(pscPoint);
	//	戻り値をPSC変数に保存
	BattleData.pscVar[PSC_VAR_RTN] = pscData->p1;
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_CmdSelect
主人公のコマンドを選択します。
ボスとボスでない場合は、戦闘メニューが変わることに注意してください(逃げられなくなります)。
その他に付いては、今まで出てきた選択メニューと同様ですの細かく説明しません。
唯一の違いはPSC変数に選択された番号を格納していることでしょう。
選択されたら次のPSC命令に進みます。

CODE:

//##############################################################################
//	●(PSC)選択操作系
//##############################################################################

//======================================================================
//	(PSC)コマンド選択
//	パラメータ:なし
//======================================================================
static int PSC_CmdSelect(PSCData_t *pscData,int frame)
{
	//	戦闘メニュー。
	static char *s_BattleMenu[] = {
		"こうげき",
		"まほう",
		"アイテム",
		"にげる",
		
		NULL,//ストッパ
	};
	//	戦闘メニュー(ボス専用で逃げるがない)。
	static char *s_BattleMenuBoss[] = {
		"こうげき",
		"まほう",
		"アイテム",
		
		NULL,//ストッパ
	};
	
	//	メニュー・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_MENU);
	
	//	最初のフレーム
	if( frame == 0 ) {
		DEBUG_PSC("コマンド選択",0,0);
		if( BattleData.bBossEnemy ) {
			//	メニューを設定する(ボス専用)。
			winmng_SetMenu(s_BattleMenuBoss);
		} else {
			//	メニューを設定する。
			winmng_SetMenu(s_BattleMenu);
		}
	}
	
	//	毎フレームの更新
	int sel = winmng_SelectMenu();
	//	選択されたら。
	if( sel != -1 ) {
		//	PSC変数に代入する。
		BattleData.pscVar[PSC_VAR_CMD] = sel;
		//	ウィンドウを閉じる。
		battle_DelWnd(PSC_WND_MENU);
		//	次のPSCに進む。
		return PSC_RTN_NEXT;
	} else {
		//	同じPSCを継続
		return PSC_RTN_CONTINUE;
	}
}
●(PSC関数)PSC_MagicSelect
魔法選択メニューです。
フィールドメニューの魔法処理とやっていることはほぼ同じです。違いは魔法がバトル用であることでしょうか。
選択されたらPSC変数に値を代入して次のPSC命令に進みます。
キャンセルした場合は-1をPSC変数に代入して次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)まほう選択
//	パラメータ:なし
//======================================================================
static int PSC_MagicSelect(PSCData_t *pscData,int frame)
{
	static char *s_magicList[MAGIC_MAX_NUMS+1];			//	表示用のリスト
	
	//----------------------------------------------------
	//	まほうメニューのリスト組み立て
	//----------------------------------------------------
	
	//	まほうメニューの構成を組み立てる準備
	battle_MenuListInit();
	
	//	まほうメニューの構成を組み立てる。
	int magics = 0;
	for( int i=0 ; imp mp ) {
			//	色をグレーにする。
			s_magicList[i] = battle_MenuListSprintf( "/g%s", pMagicData->name );
		} else {
			//	色は白
			s_magicList[i] = battle_MenuListSprintf( "%s", pMagicData->name );
		}
		magics++;
	}
	s_magicList[magics] = NULL;//ストッパ
	
	//----------------------------------------------------
	//	メニューの処理
	//----------------------------------------------------
	//	メニュー・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_MAGIC);
	
	//	最初のフレーム
	if( frame == 0 ) {
		DEBUG_PSC("まほう選択",0,0);
		//	メニューを設定する。
		winmng_SetMenu(s_magicList);
	} else {
		//	まほうメニューを更新
		winmng_UpdateMenu(s_magicList);
	}
	
	//	毎フレームの更新
	int sel = winmng_SelectMenu();
	//	最初のフレームは、無視しないとコマンド選択時の決定を誤認します。
	if( frame > 0 ) {
		int	bSelect = FALSE;//未選択
		//	選択されたら。
		if( sel != -1 ) {
			bSelect = TRUE;//選択された。
		}
		//	キャンセル
		if( g_MainData.key[g_MainData.key_menu] == 1 ) {
			bSelect = TRUE;//選択された。
			sel = -1;	//キャンセル用の値。
		}
		//	選択された?
		if( bSelect ) {
			//	PSC変数に代入する。
			BattleData.pscVar[PSC_VAR_MAGIC] = sel;
			//	ウィンドウを閉じる。
			battle_DelWnd(PSC_WND_MAGIC);
			//	次のPSCに進む。
			return PSC_RTN_NEXT;
		}
	}
	//	同じPSCを継続
	return PSC_RTN_CONTINUE;
}
●(PSC関数)PSC_ItemSelect
アイテム選択メニューです。
これもフィールドメニューのアイテム処理とやっていることはほぼ同じです。
選択されたらPSC変数に値を代入して次のPSC命令に進みます。
キャンセルした場合は-1をPSC変数に代入して次のPSC命令に進みます。

CODE:

//======================================================================
//	(PSC)アイテム選択
//	パラメータ:なし
//======================================================================
static int PSC_ItemSelect(PSCData_t *pscData,int frame)
{
	static char *s_itemList[ITEM_MAX_NUMS+1];			//	表示用のリスト
	
	//----------------------------------------------------
	//	アイテムメニューのリスト組み立て
	//----------------------------------------------------
	
	//	アイテムメニューの構成を組み立てる準備
	battle_MenuListInit();
	
	//	アイテムメニューの構成を組み立てる。
	int items = 0;
	for( int i=0 ; iitems[i] == ITEM_NON ) { //アイテムを所持していない。
			break;	//アイテム未所持なら抜ける。
		}
		s_itemList[i] = battle_MenuListSprintf( "%s", party_getItemName(BattleData.playerParam->items[i]));//アイテム
		items++;
	}
	s_itemList[items] = NULL;//ストッパ
	
	//----------------------------------------------------
	//	メニューの処理
	//----------------------------------------------------
	//	メニュー・ウィンドウの作成・アクティブ化
	battle_ActiveWnd(PSC_WND_ITEM);
	
	//	最初のフレーム
	if( frame == 0 ) {
		DEBUG_PSC("アイテム選択",0,0);
		//	メニューを設定する。
		winmng_SetMenu(s_itemList);
	} else {
		//	アイテムメニューを更新
		winmng_UpdateMenu(s_itemList);
	}
	
	//	毎フレームの更新
	int sel = winmng_SelectMenu();
	//	最初のフレームは、無視しないとコマンド選択時の決定を誤認します。
	if( frame > 0 ) {
		int	bSelect = FALSE;//未選択
		//	選択されたら。
		if( sel != -1 ) {
			bSelect = TRUE;//選択された。
		}
		//	キャンセル
		if( g_MainData.key[g_MainData.key_menu] == 1 ) {
			bSelect = TRUE;//選択された。
			sel = -1;	//キャンセル用の値。
		}
		//	選択された?
		if( bSelect ) {
			//	PSC変数に代入する。
			BattleData.pscVar[PSC_VAR_ITEM] = sel;
			//	ウィンドウを閉じる。
			battle_DelWnd(PSC_WND_ITEM);
			//	次のPSCに進む。
			return PSC_RTN_NEXT;
		}
	}
	//	同じPSCを継続
	return PSC_RTN_CONTINUE;
}
●(PSC関数)PSC_DamageCalc
p1で指定された防御力、p2の補正値、p3の攻撃力でダメージを計算します。
攻撃力は90%から110%の範囲でランダムに変化させた後、ダメージを計算してdamageに保存しています。
計算内容はバトル・シミュレータとほぼ同じです。

CODE:

//##############################################################################
//	●(PSC)ダメージ系
//##############################################################################

//======================================================================
//	(PSC)ダメージ計算
//	パラメータ:p1[パラメータ防御力],p2[補正値],p3[パラメータ攻撃力]
//	{ PSC_DamageCalc,NULL,PSCDATA_INT(PDI_ENEMY_DEF),1,PSCDATA_INT(PDI_PLAYER_ATK) },//ダメージ計算
//======================================================================
static int PSC_DamageCalc(PSCData_t *pscData,int frame)
{
	MACRO_ASSERT( pscData->p2 > 0 );
	
	//	防御力を求める
	int def = 0;
	MACRO_ASSERT(battle_GetPscParam(pscData->p1,&def,NULL,pscData) );
	
	//	攻撃力を求める
	int atk = 0;
	MACRO_ASSERT(battle_GetPscParam(pscData->p3,&atk,NULL,pscData) );
	
	//	攻撃力をランダム補正する。90%~110%
	atk = ( atk * (90 + GetRand(20)) ) / 100;
	
	//	ダメージの計算。攻撃力 - 防御力/2
	int damage = atk - (def/(2*pscData->p2));
	
	//	1以下なら補正。最低限1ダメージ。
	if( damagehp -= BattleData.damage;
	//	死んだ場合。
	if( BattleData.playerParam->hp hp = 0;
	}
	DEBUG_PSC("主人公のダメージ=%d HP=%d",BattleData.damage,BattleData.playerParam->hp);

	//	一時的にダメージ表現でウィンドウの位置をずらす。
	BattleData.PlayerDamageEffectCount = EFFECT_FRAME;

	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_EnemyDamage
PSC_DamageCalcで計算したダメージを敵に与えます。
HPからダメージを引いてマイナスになった場合は0に補正します。
EnemyDamageEffectCountにダメージエフェクトのカウントを設定しています。

CODE:

//======================================================================
//	(PSC)敵にダメージを与える
//	パラメータ:なし
//======================================================================
static int PSC_EnemyDamage(PSCData_t *pscData,int frame)
{
	//	ダメージを与える。
	BattleData.enemyParam.hp -= BattleData.damage;
	//	死んだ場合。
	if( BattleData.enemyParam.hp  0 ) {
		//	普通の攻撃。大きめの確率
		atk_type = ENEMY_ATK_TYPE_NORMAL;
	}
	
	//	決定した攻撃タイプをPSC変数に格納する。
	DEBUG_PSC("敵の攻撃タイプ=%d",atk_type,0);
	BattleData.pscVar[PSC_VAR_ENEMYATK] = atk_type;

	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_MagicAction
PSC_MagicSelectで選択した魔法の実際のアクションを行います。
PSC_VAR_MAGICに保存してあった選択番号で魔法のデータを得ます。
PSC変数(PSC_VAR_MAGIC_ACT)に仮としてPSC_VAR_MAGIC_ACTを設定します。
魔法のデータのmagic_idで処理を振り分けます。
MAGIC_FIREなら、PSC変数(PSC_VAR_MAGIC_ACT)にPSC_MAGIC_ACT_FIREをセットしてmpを消費してMagicAtkをセットして終わりますが、実際のダメージ処理はPSC_DamageCalcで別に行います。
MAGIC_HEALなら、party_useMagic()で回復処理を行いメッセージを組み立てます。
mpが足らなかった場合には、mpが足らないメッセージを組み立てます。

CODE:

//======================================================================
//	(PSC)魔法の処理
//	パラメータ:なし
//======================================================================
static int PSC_MagicAction(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("PSC_MagicAction",0,0);
	
	//	魔法の情報を得る。該当番号のバトルで使える魔法を得る。
	int magic_listno = 	BattleData.pscVar[PSC_VAR_MAGIC];
	const MagicDef_t *pMagicData = party_getMagicData(BattleData.playerParam,magic_listno,MAGIC_TYPE_BATTLE);
	MACRO_ASSERT( pMagicData!=NULL );
	
	//	あとの処理はメッセージと仮定。
	BattleData.pscVar[PSC_VAR_MAGIC_ACT] = PSC_MAGIC_ACT_MSG;
	
	//	発動魔法別に分岐
	int bMpFusoku = FALSE;
	switch( pMagicData->magic_id ) {
	case MAGIC_FIRE:	//ほのおの攻撃魔法
		//	もしmp不足なら?
		if( BattleData.playerParam->mp mp ) {
			//	MPが足らない。
			bMpFusoku = TRUE;
		} else {
			//	mpを消費する。
			BattleData.playerParam->mp -= pMagicData->mp;
			//	魔法の攻撃力
			BattleData.MagicAtk = pMagicData->power;
			//	後で攻撃魔法を処理
			BattleData.pscVar[PSC_VAR_MAGIC_ACT] = PSC_MAGIC_ACT_FIRE;
		}
		break;

	case MAGIC_HEAL:	//回復魔法
		//	回復魔法処理
		if( party_useMagic(BattleData.playerParam,magic_listno,MAGIC_TYPE_BATTLE) ) {
			//	回復した。
			sprintf( s_msgTable[0], "あなたは %s の まほう つかった!",pMagicData->name);
			sprintf( s_msgTable[1], "HPが%dにかいふくした。",BattleData.playerParam->hp);
		} else {
			//	MPが足らない。
			bMpFusoku = TRUE;
		}
		break;
	}
	
	//	MPが足らない?
	if( bMpFusoku ) {
		sprintf( s_msgTable[0], "あなたの %s の まほうはmpが足らなかった!",pMagicData->name);
		sprintf( s_msgTable[1], "");
	}
	
	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_ItemAction
PSC_ItemSelectで選択したアイテムの実際のアクションを行います。
hpとmpの現在をとりあえず保存します。
PSC_VAR_ITEMに保存してあった選択番号でアイテムを選んでparty_useItem()で実際のアイテムを使います。
アイテムを使用したら、hpとmpのそれぞれの回復メッセージを組み立てます。同時回復するアイテムがある場合は、これではダメですけどね。
party_delItem()でアイテムを消費(アイテムテーブルを前に詰める)します。
使えなかった場合は、メッセージでお知らせします。

CODE:

//======================================================================
//	(PSC)アイテムの処理
//	パラメータ:なし
//======================================================================
static int PSC_ItemAction(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("PSC_ItemAction",0,0);

	//	パラメータを保存
	int hp = BattleData.playerParam->hp;
	int mp = BattleData.playerParam->mp;

	//	アイテムの処理を行う。
	int item_selno = BattleData.pscVar[PSC_VAR_ITEM];
	if( party_useItem(BattleData.playerParam,BattleData.playerParam->items[item_selno]) ) {
		//	アイテム使用メッセージ
		sprintf( s_msgTable[0], "あなたは %s を つかった!",party_getItemName(BattleData.playerParam->items[item_selno]));
		if( hp!=BattleData.playerParam->hp ) {	//	HPの回復?
			sprintf( s_msgTable[1], "HPが%dにかいふくした。",BattleData.playerParam->hp);
		} else
		if( mp!=BattleData.playerParam->mp ) {	//	MPの回復?
			sprintf( s_msgTable[1], "MPが%dにかいふくした。",BattleData.playerParam->mp);
		} else {
			sprintf( s_msgTable[1], "バグ?" );
		}
		//	アイテムを消費する(アイテムテーブルを前に詰める)。
		party_delItem(BattleData.playerParam,item_selno);
	} else {
		sprintf( s_msgTable[0], "あなたは %s を 使おうとしたが無駄だったので あきらめた!",party_getItemName(BattleData.playerParam->items[item_selno]));
		sprintf( s_msgTable[1], "");
	}

	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_AttackEffect
攻撃エフェクトの色とエフェクト期間を設定します。
p1で色は自由に変更できます。

CODE:

//======================================================================
//	(PSC)攻撃エフェクト色
//	パラメータ:p1[]
//======================================================================
static int PSC_AttackEffect(PSCData_t *pscData,int frame)
{
	DEBUG_PSC("攻撃エフェクト設定 color=%d",pscData->p1,0);

	//	パラメータ1を解析して値を得る。
	int intP1 = 0;
	int bIntP1 = battle_GetPscParam(pscData->p1,&intP1,NULL,pscData);

	//	エフェクト設定
	BattleData.AttackEffectCount = EFFECT_FRAME_FLASH;	//攻撃エフェクト有効
	BattleData.attackEffectColor = intP1;				//攻撃エフェクト色

	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
●(PSC関数)PSC_Levelup
レベルアップ処理です。
敵の経験値をお金を得てレベルアップする経験値になっていたらレベルアップを行います。

メッセージ表示自体は、s_msgTableに格納してPSC処理で別に表示してもらいますので、ここでは表示しません。
PSC_VAR_LEVELUPに「レベルアップなし」、「レベルアップあり」、「レベルアップあり魔法も覚えた」の3種類の戻り値を返します。
「レベルアップあり」、「レベルアップあり魔法も覚えた」の場合は更に連続レベルアップの可能性があるのでもう一度PSC_Levelupを呼び出してもらう必要があります。

CODE:

//======================================================================
//	(PSC)レベルアップ
//	パラメータ:なし
//======================================================================
static int PSC_Levelup(PSCData_t *pscData,int frame)
{
	int LevelupType = PSC_LEVELUP_RTN_NO;	//レベルアップなし
	
	//	経験値とお金を実際に得る。
	BattleData.playerParam->expp += BattleData.enemyParam.expp;
	BattleData.playerParam->money += BattleData.enemyParam.money;
	
	//	ループでレベルアップチェックするので2回目にアップしないようにクリアする。
	BattleData.enemyParam.expp = 0;
	BattleData.enemyParam.money = 0;

	//	レベルアップする?
	int nextlevel = BattleData.playerParam->level + 1;
	if( BattleData.playerParam->expp >= battle_GetLevelupExpp(nextlevel)  ) {
		DEBUG_PSC("レベルアップあり level=%d->%d",BattleData.playerParam->level,nextlevel);
		//	レベルアップした
		LevelupType = PSC_LEVELUP_RTN_YES;
		
		//	レベルアップ値の計算
		int hp_up = battle_LevelScaler(nextlevel,3,12);	//レベルアップ値の下と上の値。
		int mp_up = battle_LevelScaler(nextlevel,3,15);	//レベルアップ値の下と上の値。
		int atk_up = battle_LevelScaler(nextlevel,5,6);	//レベルアップ値の下と上の値。
		int def_up = battle_LevelScaler(nextlevel,6,7);	//レベルアップ値の下と上の値。
		
		//	実際のレベルアップ
		BattleData.playerParam->level = nextlevel;	//レベル
		BattleData.playerParam->hp_max += hp_up;	//HPMAX
		BattleData.playerParam->mp_max += mp_up;	//MP
		BattleData.playerParam->attack += atk_up;	//攻撃力
		BattleData.playerParam->def += def_up;		//防御力
		
		//	メッセージを組み立てる。表示は後でPSC_KeyWaitMsgで行う。
		sprintf( s_msgTable[0], "レベルが%dにあがった!", nextlevel );
		sprintf( s_msgTable[1], "最大hpが+%d、最大mpが+%d、攻撃力が+%d、防御力が+%dあがった!", hp_up,mp_up,atk_up,def_up );
		//	まほうを覚えた!
		for( int i=0; ilevel == nextlevel ) {
					//	覚えたメッセージ
					sprintf( s_msgTable[2], "%s のまほうをおぼえた!", pMagicData->name );
					//	レベルアップした。魔法も覚えた
					LevelupType = PSC_LEVELUP_RTN_MAHOU;
				}
			}
		}
	} else {
		DEBUG_PSC("レベルアップなし level=%d",BattleData.playerParam->level,0);
	}
	
	//	レベルアップしたフラグをPSC変数に格納する。
	BattleData.pscVar[PSC_VAR_LEVELUP] = LevelupType;

	//	次のPSCに進む。
	return PSC_RTN_NEXT;
}
さて、いよいよ次回は第一部完結編。
バトルを制御するバトルデータをお送りします!
最後に編集したユーザー softya(ソフト屋) on 2011年4月25日(月) 18:28 [ 編集 1 回目 ]

コメントはまだありません。