§
------------------------------------------------
CWG - Simutrans 時間制御ゲート機能パッチ

				Jul 10, 2012
				 for CWG 004
				    wackdone
------------------------------------------------

Simutransに道路信号に似た周期時間制御の信号を
追加するパッチです。

--------------------
= バージョン情報
--------------------
パッチバージョン: CWG Version 0.04
対応Simutransソース: Nightly r5788
パッチファイル名: simutrans-r5788-cwg-004.patch

== 適用可能ソースについて
このパッチは、Release 111.3 (r5772) にも適用できることを確認しています。
(パッチがあたっていることを確認したのみで動作確認は充分にしていません。)	

== 動作確認
現在は、NetBSD と Windows 上で動作を確認しています。


--------------------
= 機能の概要
--------------------
日本語Forumでgonyoさんが提案されていた
  「道路信号機のような鉄道信号機」
を実装してみました。

最新Simutransの道路信号機は、青と赤の時間を制御できます。
これと同様の設定ができる timing gate 「時間ゲート」 という機能を作り、
線路や道路上に配置することができます。

乗り物はゲートが開いている時にしか通ることができません。
ゲートが閉じている場合は、その前で停止状態になりゲートが開くのを待ちます。
ゲートの開閉時間を調整することで、乗り物の等間隔運行が簡単にできるようになります。
(等間隔にしたいだけならTTTより簡単なのではと考えています。)

またこの改造の副産物として block gate 「手動封鎖ゲート」というものもできました。
ゲートを設置したあと、同じゲートでクリックする(信号機の向きを変える感じ)、
あるいは情報ウィンドウ上でボタンを押すことで、ゲートの開閉を手動操作できます。
工事やダイヤ乱れのあとの一時的な運行整理を手動でしたい場合などに
使えるかもしれません。

なお、ゲートは線路や道路の交差部分(三叉路を含む)には設置できません。


--------------------
= 仕組み
--------------------
乗り物の経路探索(次の停車点までどの線路を通るかの決定)の中では、
ゲートの存在は無視されます。つまりゲートがあってもそこを通れる前提の
最短経路を探して走行しようとします。

実際に走行する際に、ゲートにさしかかった時にゲートの状態を見て
閉じていたらその手前で停止します。

鉄道車両のように線路の予約がある乗り物にとって、閉じているゲートは
その１マスだけ線路が他の車両に予約されているかのように扱われます。
ゲートが開いた段階で、その先の信号まで線路を予約して、走行します。

自動車にとっては、道路信号機と同じような扱いです。


--------------------
= パッチの適用とビルド
--------------------
同梱のパッチファイルをSimutransのソースに適用したうえで、
ビルドコンフィグ内に

{{{
  CFLAGS += -DUSE_WAYGATE
  USE_WAYGATE = 1
}}}

の二行を追加してビルドしてください。

この指定をしなければ、オリジナル通りの動作になります。


--------------------
= 使い方
--------------------
この機能の使用にはオブジェクト(pak)の追加が必要です。

== pak の作成と導入
timing_gate および block_gate の機能を持つ新たな roadsign の pak を
pakディレクトリに入れる必要があります。

pak の作り方は後述しますが、サンプルとして pak64 と pak128 用の
追加 pak (鉄道用のみ) を同梱しておきます。

  CWG_sample_gates_64.pak
  CWG_sample_gates_128.pak

どちらもそれぞれ pak64 と pak128 のオリジナル内にある private_way の
画像をそのまま使って、waygateにしたものです。
ゲーム上では見分けがつかなくなりますが、あくまでお試しですのでご容赦ください。
ツール上ではツールチップを読めば一応区別できます。
また建設した後は、情報ウィンドウを開けばすぐにわかります。

== 建設
新たに導入したオブジェクトをツールで選んで、線路上、道路上に建設します。
block_gate は、鉄道信号機のように同じツールでもう一度押すことで
開閉を切り替えられます。

== 建設制限
分岐点やカーブ部分の道路、線路上にはゲートを建てることはできません。
また踏切の上にも建てられません。

注意: 旧版 (CWG-003以前) は、カーブ部分には建設できました。
  しかしこの旧版でデータ保持方法に問題が見つかったため変更した結果、
  このような制限が出来ています。旧版のデータでカーブにゲートのあるものは
  とりあえずロードできるようにはしているつもりですが、その先の動作が
  怪しくなるかもしれません。残念ですが破壊して直線部分に建設しなおしてください。

== block_gate の操作
block_gate は情報ウィンドウの中の下のほうにあるボタンで手動開閉できます。

== timing_gate の操作
timing_gate は情報ウィンドウの中で、以下の3つのパラメータを設定できます。
  open time
    ゲートが開いている時間を指定します
  close time
    ゲートが閉じている時間を指定します
  offset
    ゲートの開閉のゲーム内絶対時間からのずれです
時間の単位は全て 1024ticks (約1秒) です。
値はどれも 0 から 255 の範囲で設定できます。
(この仕様は道路信号機とほぼ同じです。南北向きが「開」、東西向きが「閉」に
なったと考えていただければよいかと思います。)

ゲートは、(open_time + close_time) 時間を周期として繰り返し動作します。
この周期の中で、はじめに open_time だけ開いていて
続いて close_time だけ閉じています。
offset を設定することで、複数のゲートのあいだで開くタイミングを
ずらすことが可能です。

--------------------
= pakの作り方
--------------------
waygateにするには dat ファイルの中でまず is_private を 1にしたうえで
もう一つ、他の何かを 1 にします。

block gate は end_of_choose を 1 にします。
{{{
  is_private=1
  end_of_choose=1
}}}

timing gate は is_signal を 1 にします。
{{{
  is_private=1
  end_of_choose=1
}}}

以下に、pak128のソースにある画像からそれぞれのwaygateを作った時のdatを示します。
{{{
# track blocking gate
obj=roadsign
name=Track_blocking_gate
copyright=Fabio Gonella
cost=8000
waytype=track
is_private=1
end_of_choose=1
image[0]=railgate.1.0
Image[1]=railgate.1.1
Image[2]=railgate.1.2
Image[3]=railgate.1.3
Icon=> railgate.1.4
Cursor=railgate.1.5
-- 
# track timing gate
obj=roadsign
name=Track_timing_gate
copyright=Fabio Gonella
cost=8000
waytype=track
is_private=1
is_signal=1
image[0]=railgate.1.0
Image[1]=railgate.1.1
Image[2]=railgate.1.2
Image[3]=railgate.1.3
Icon=> railgate.1.4
Cursor=railgate.1.5
-- 
}}}

今のサンプルの絵は、大袈裟な門だったり遮断棒だったり、どうも微妙です。
信号機や信号所の絵にした方がビジュアル的にスマートになりそうですね。
(ただ、今ぐらい大袈裟な方が動作している様子はよくわかる)


--------------------
= セーブファイルのバージョン
--------------------
ファイルのバージョンは変更されていませんが、
ゲートは新たな ding type を持っているため、
ゲートが含まれたセーブファイルをオリジナルのバージョンで開くことはできません。
(fatalエラーになります)

この問題への対策 (ゲートが入っていても無視してロードできるような
セーブファイルを作る) も考えています。



--------------------
= 既知の問題点
--------------------
チューズシグナル(振分信号)との相性がよくありません。

チューズシグナルで行き先(入線先)を選びなおす時、ゲートが無視されます。
よって、ずっと閉じたままのゲートであってもその先にホームが空いていれば入ろうとし
ゲートが開かないからなかなか入れない、という困った状態になります。

この問題は改善予定です。
(入線にゲートを使うというのは、あまりニーズが無いでしょうが)


--------------------
= パッチの概要
--------------------
走行経路制御に影響を与える roadsign はいくつもありますが、

  private_way: 恒久的に通行止めとして扱われる (指定されたプレーヤー以外には)
  signal: 走行時の判定だが線路予約を前提としている
  crossing: 踏切上での車両の出し入れや「通過する時に閉める」などの動作が入る

と、どれもぴったりとくるものがありません。
このため、waygate という概念を新たに導入することにしました。
waygate であればどんな種類であっても、走行側の判定は共通化されるので、
違う機能を持った新たな waygate を追加していけます。

  (例えば、ある特定の線路タイルがリザーブされていない時だけ開くゲート、とか)

signal_t のように roadsign_t を継承して waygate_t という新クラスを作っています。
これは、signal_t と同様 (フィールドはもとから roadsign_t にある)
zustand (状態) を持っており、rot(赤)、gruen(緑)のいずれかをとります。
(オリジナルには naechste_rot(次は赤?)がありこの時の画像も持てますが、
コードの中でこの状態になることは今は無いようです。)

block_gate, timing_gate の分け方は signal_t と同様、roadsing_besch の中の
フラグで振り分けています。ここで、waygateだけは強引に挟み込み方をしています。
(pakの作り方を見ていただければわかるかと)

ゲートの通過時の判定は vehicle/simvehikel.cc の中です。
道路車両は、ほとんど  traffic_light と同じところで判定。
鉄道は線路のリザーブをかけるところで判定です。

なお、wegの方では道(道路、線路)の上に waygate があることを
記録するために、flags の中の IS_DIAGONAL と HAS_CROSSING を使っています。
  この両方がflagsに立っていれば waygate
  HAS_CROSSING だけだったら crossing
  IS_DIAGONAL だけだったら斜め道路/線路
という具合です。
本来このような汚い改造は良くないのですが、flagsが8bitで管理しており、
フラグの定義は8bitめいいっぱい、さらにweg_tのインスタンスのデータの
隙間もまったく無し(見事に8bit,8bit,16bitと使って埋めている)
という状況なため、このような無理をしています。
(旧来のバージョン (CWG-003) までは、SIGNAL|CROSSINGを使っていましたが、
 これでは、踏切の上に鉄道信号が置けなくなります。
 フォーラム上で o_o さんが問題を教えてくださいました。ありがとうございます。)



--------------------
= ご利用上の注意点とお願い
--------------------
このパッチは現在、αクオリティです。
一切の動作の保証はできませんのでご了承ください。

鉄道では、ある程度の動作は確認していますが、
道路車両はあまりテストできていません。

バグのご報告や機能改善のご提案はウェルカムです。
(ただし充分に対応できる余裕はございませんので対応が遅れましてもご了承ください。)
ご連絡は日本語フォーラム
  Japanese Simutrans Forum
の該当トピックへお願いいたします。
