alchemistarkの日記

やったことのメモ

kothのタイマーを操作する

クソみたいに遠回りした…
とりあえず順番に語ります。本題だけ見たい人は最後のコードを見てください。


kothのタイマーを操作したい
とりあえず止めたり動かしたり時間を変えたりしたい

ではkothのタイマーはどこにあるのか?
とりあえず思いつくのはtf_logic_koth、tf_gamerules、team_round_timer

tf_logic_kothはとりあえずkothのHUDを表示してる
後タイマーにセットする時間を持っている

tf_gamerulesにはkoth関係と思われるInputはSetRedKothClockActiveとSetBlueKothClockActiveしかない
これはkothのタイマーをスタートさせるだけ 一方が動き出すともう片方は止まる。

team_round_timerは複数のマップをHammerEditerで開いてみたところ、
そもそもkothマップには置いてない事が多いように見える。

つまり、bspファイル内にkothのタイマーを記録しているEntityは存在しない…?

と思っていたらtf_logic_kothのページにこのような記述を発見。

It creates two entities named zz_red_koth_timer and zz_blue_koth_timer which have inputs like pause,resume,etc

これは、zz_red_koth_timerとzz_blue_koth_timerという名前の2つのエンティティを作成します。これらのエンティティには、一時停止、再開などの入力があります。

動的に作ってんのかよ!!!

じゃープラグインからzz_*_koth_timerってEntity探したり作ったりしてみようか
まで考えたけど見つからないし作成できず。

うん、僕バカなのでzz_*_koth_timerってClassnameでEntity探したよね

個別のEntity名ですってば。プロパティ名で言うとtargetname
恐らくEntityClassnameはteam_round_timerだと思われ

HammerEditerでOutput先にzz_~を指定するとOutput先が存在しないって言われるけど動作します。
何かのイベントが起きるとタイマーが止まるkothマップとか作れます。

zz_~で調べてたら、その名前で引っ掛けてEntityを特定してるコードを発見。
けどもう少し調べたらtf_gamerulesのNetPropに普通に格納されてた
んでtf_gamerulesはsdktoolsをincludeしたらGameRules_GetPropEntで読めるから…
あれ、これコード凄い単純じゃね…?

以下コード。

public Action:Cmd_get(client, args){

	//タイマーのEntityを確保する
	new bluetimerEnt = GameRules_GetPropEnt("m_hBlueKothTimer");
	new redtimerEnt = GameRules_GetPropEnt("m_hRedKothTimer");

	new float:fBluTime;
	new float:fRedTime;
	
	//青タイマー確認	//止まっていると1、動いていると0
	if(GetEntProp(bluetimerEnt, Prop_Send, "m_bTimerPaused") == 0){
		//タイマー動作中(タイマー開始時の時刻-現在時刻)
		fBluTime = GetEntPropFloat(bluetimerEnt, Prop_Send, "m_flTimerEndTime") -  GetGameTime();
	}
	else{
		//タイマー停止中
		fBluTime = GetEntPropFloat(bluetimerEnt, Prop_Send, "m_flTimeRemaining");
	}
	
	//赤タイマー確認
	if(GetEntProp(redtimerEnt, Prop_Send, "m_bTimerPaused") == 0){
		fRedTime = GetEntPropFloat(redtimerEnt, Prop_Send, "m_flTimerEndTime") -  GetGameTime();
	}
	else{
		fRedTime = GetEntPropFloat(redtimerEnt, Prop_Send, "m_flTimeRemaining");
	}
	
	//表示する
	PrintToChat(client,"Blue:%f Red:%f",fBluTime,fRedTime);
	PrintToChat(client,"BlueTimer:%d RedTimer:%d",GetEntProp(bluetimerEnt, Prop_Send, "m_bTimerPaused"),GetEntProp(redtimerEnt, Prop_Send, "m_bTimerPaused"));
	
	/*
	SetEntProp(bluetimerEnt, Prop_Send, "m_bTimerPaused",1);
	"m_bTimerPaused"に1を書き込むとタイマーが停止するが、同時に"m_flTimeRemaining"の値でタイマーが上書きされる
	停止させる前に手動で"m_flTimeRemaining"の値を更新すること
	また、CPは取得されたままになるのでCPの所有者を開放する等の処置を取ること
	*/
	
}

多分team_round_timeのInputが使えるので、全部GetEntPropする必要は無いと思う。
コメントにも書いてるけど、タイマーをただ停止させるとタイマーが動く前の時間に戻されるので注意。
先にTimeRemainingの値を書き換えておけばOK

そういえば両方動かしたら両方同時に動き出してちょっと笑える

ていうか最終的にコピペしたのがmorestocksなのちょっと納得行かない
つまりmorestocksをincludeした方が断然早い。

sourcemod-snippets/tf2_morestocks.inc at master · powerlord/sourcemod-snippets · GitHub