箱庭諸島/hakoniwa.cgi
箱庭諸島 > 箱庭諸島/hakoniwa.cgi
本文
以降の記述にはスクリプト本文があります。 →[記述をスキップ]
<nowiki>
#!/usr/local/bin/perl
# ↑はサーバーに合わせて変更して下さい。
# なお、perl5.002以降用です。
#----------------------------------------------------------------------
# 箱庭諸島 ver1.1
#
# 字: 徳岡宏樹(tokuoka@taurus.bekkoame.ne.jp)
# 絵: 小川克人
# テストプレイ他協力: 稲葉修吾、井上友博、小澤武史
# 箱庭諸島のページ: http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html
#----------------------------------------------------------------------
#----------------------------------------------------------------------
# 使用条件
#----------------------------------------------------------------------
# このスクリプトについては、自己責任で使用する限り、基本的には自由に
# 利用してもらってかまいません。ただし、変更を加えた場合は、変更した
# ものを勝手に配るのはやめて下さい。
#
# また、付属しているgifファイルは、小川克人氏が著作権をもっています。
# このゲーム用以外の用途に許可なく使用するのは禁止します。
#
# バグを発見した場合は上記のページまでお知らせ下さい。
#----------------------------------------------------------------------
# 設置方法の説明
#----------------------------------------------------------------------
#
# ----設置方法----
#・下のValue packageのところにある設定値を、適切な値に設定
#
#・CGIが実行されるディレクトリを作り、パーミッションを777に設定します。
#
#・そのディレクトリに、このファイル(hakoniwa.cgi)を置き、
# パーミッションを755に設定します。
#
#・key-free というファイル名の、大きさが0のファイルを作成し、
# 同じディレクトリに起きます。パーミッションは644に設定します。
#
#・サーバーにjcode.plがない場合は、同じディレクトリに置きます。
#
#・CGIで実行されるわけではない、通常にアクセス出来る場所に、
# 付属するgifファイル(land*.gif、space*.gif)をすべて置きます。
#
# 以上です。なお、一回目の実行において、hakoniwa.dat、hakoniwa.log
# の2つのファイルが生成されます。
#
# 構成 ()内の数字にパーミッションを設定
#
# cgi実行可能なディレクトリ(755)/
# |
# |-- hakoniwa.cgi (755)
# |-- key-free (644)
# |-- jcode.pl ※必要な場合のみ
# |-- hankoniwa.dat (644) ※初回に生成される
# |-- hakoniwa.log (644) ※初回に生成される
#
# 通常のウェブのディレクトリ/
# |
# |-- land0.gif
# |-- ...
# |-- land9.gif
# |-- space.gif
#----------------------------------------------------------------------
# 注意
#----------------------------------------------------------------------
# key-freeファイルは、スクリプト実行中はkey-lockedという名前に
# なっています。スクリプトが正常に終了しなかった場合、key-locked
# になったままになってしまう事があり、その場合は何度アクセスしても
# 同時アクセスエラーになってしまいます。
#
# そういった場合は、key-locked を強制的に key-free にrenameして下さい。
# ftpのrenameコマンドで出来るはずです。
#----------------------------------------------------------------------
#Value package 各種設定値
#----------------------------------------------------------------------
package Value;
BEGIN {
#------------------------------------------------------------#
# 必ず設定する部分
#------------------------------------------------------------#
# jcode.plの位置
# $jcode = '/usr/libperl/jcode.pl'; # ベッコアメの場合
# $jcode = './jcode.pl'; # 同じディレクトリに置く場合
$jcode = '/usr/libperl/jcode.pl';
# このファイルを置くディレクトリ
# $baseDir = 'http://サーバー/ディレクトリ';
#
# 例)
# http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa/hakoniwa.cgi
# として置く場合、
# $baseDir = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa';
# とする。最後にスラッシュ(/)は付けない。
$baseDir = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa';
# 画像ファイルを置くディレクトリ
# $imageDir = 'http://サーバー/ディレクトリ';
$imageDir = 'http://www.bekkoame.ne.jp/~tokuoka/island';
# 管理者の名前
$admin = '徳岡宏樹';
# 管理者のメールアドレス
$email = 'tokuoka@taurus.bekkoame.ne.jp';
# トップページ
$toppage = 'http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html';
# 掲示板
$bbs = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakobbs/minibbs.cgi';
#------------------------------------------------------------#
# 以降は好みによって変更
#------------------------------------------------------------#
# BODYタグのoption
$body = 'BGCOLOR="#90b090"';
# コマンド先行入力限界数
$commandMax = 40;
# 「最近の出来事」保持ターン数
$logMax = 5;
# 「最近の出来事」表示ターン数
$logPrint = 1;
# 1ターンが何秒か
$unitTime = 21600; # 6時間
# 初期資金
$startMoney = 50;
# 島の最大数
$maxIsland = 150;
# 期限切れ(資金繰りがこのターン数連続すると、島の放棄)
$expire = 28;
# お金の単位
$moneyUnit = '億円';
# 人口の単位
$popUnit = '000人';
# 災害発生率(1d1000で下の数字以下)
$fire = 10; # 火災
$typhoon = 10; # 台風
$tsunami = 20; # 津波
$eruption = 10; # 噴火
$meteo = 10; # 隕石
$earthquake = 5; # 地震
$maizo = 10; # 埋蔵金
# 島の大きさ(変えない方がいいかも)
$islandSize = 12;
# デバッグ(1にすると、「ターンを進める」ボタンが出る)
# $debug = 1;
$debug = 0;
# このファイル
$thisFile = "$baseDir/hakoniwa.cgi";
}
#----------------------------------------------------------------------
# main package メインルーチン
#----------------------------------------------------------------------
package main;
# jcode.plのよみこみ
require "$Value::jcode";
# ロックをかける
if(!&Lock::lock()) {
# ロック失敗
# ヘッダ出力
&IO::out(&Temp::header($Value::body));
# ロック失敗メッセージ
&IO::out(&Temp::lockFail());
# フッタ出力
&IO::out(&Temp::footer());
# 終了
exit(0);
}
# 乱数初期化
srand;
# cookie入力
&Cookie::input();
# CGIコマンド入力
&IO::cgiInput();
# 島データ読み込み
&IO::parseAll();
# ターン処理
# 何ターン過ぎているか計算
$now = time;
$passTurn = int(($now - $Island::lastUpdateTime) / $Value::unitTime);
# デバッグ用ターン処理
if(($Value::debug == 1) && ($Island::mainMode eq 'turn')) {
$passTurn = 1;
# top modeにもどす
$Island::mainMode = 'top';
}
# ターン処理(1ターンのみに改定)
if($passTurn > 0) {
# 最終更新時間を更新
$Island::lastUpdateTime += $Value::unitTime;
# ログファイル名変更
my($i, $j);
for($i = $Value::logMax - 2; $i >= 0; $i--) {
$j = $i + 1;
rename("hakoniwa.log$i", "hakoniwa.log$j");
}
# ファイルバックアップ
rename('hakoniwa.bak7','hakoniwa.bak8');
rename('hakoniwa.bak6','hakoniwa.bak7');
rename('hakoniwa.bak5','hakoniwa.bak6');
rename('hakoniwa.bak4','hakoniwa.bak5');
rename('hakoniwa.bak3','hakoniwa.bak4');
rename('hakoniwa.bak2','hakoniwa.bak3');
rename('hakoniwa.bak1','hakoniwa.bak2');
rename('hakoniwa.dat','hakoniwa.bak1');
# 1ターン進める
&Process::turn();
# ファイルに書き出す
&IO::writeIslands();
}
# 人口順にソート
&Util::sort();
# テンプレート初期化
&Temp::initialize();
# cookie出力
&Cookie::output();
# ヘッダ出力
&IO::out(&Temp::header($Value::body));
# モードにより分岐
if($Island::mainMode eq 'top') {
# ロック解除
&Lock::unlock();
# トップページ
&TopPage::main();
} elsif($Island::mainMode eq 'new') {
# 島の新規作成
&NewIsland::main();
# ロック解除
&Lock::unlock();
} elsif($Island::mainMode eq 'print') {
# ロック解除
&Lock::unlock();
# 島の表示
&PrintIsland::main();
} elsif($Island::mainMode eq 'owner') {
# ロック解除
&Lock::unlock();
# 開発計画
&Owner::main();
} elsif($Island::mainMode eq 'command') {
# 開発計画
&ComSend::main();
} else {
# ロック解除
&Lock::unlock();
}
# フッタ出力
&IO::out(&Temp::footer());
exit(0);
#----------------------------------------------------------------------
# Land package 地形データ
#----------------------------------------------------------------------
package Land;
BEGIN {
# 地形番号の設定
$sea = 0; # 海
$wasteland = 1; # 荒地
$plains = 2; # 平地
$town1 = 3; # 村
$town2 = 4; # 町
$town3 = 5; # 都市
$forest = 6; # 森
$farm = 7; # 農場
$factory = 8; # 工場
$base = 9; # ミサイル基地
$dbase = 10; # 防衛施設
# 地形の名前
$name[$sea] = '海';
$name[$wasteland] = '荒地';
$name[$plains] = '平地';
$name[$town1] = '村';
$name[$town2] = '町';
$name[$town3] = '都市';
$name[$forest] = '森';
$name[$farm] = '農場';
$name[$factory] = '工場';
$name[$base] = 'ミサイル基地';
$name[$dbase] = '防衛施設';
# 人口
$pop[$town1] = 1;
$pop[$town2] = 3;
$pop[$town3] = 5;
# 職場
$work[$farm] = 10;
$work[$factory] = 30;
# 地形の文字(簡略モード用)
$word[$sea] = '<FONT STYLE="background-color:blue">海</FONT>';
$word[$wasteland] = '<FONT STYLE="background-color:darkred">荒</FONT>';
$word[$plains] = '<FONT STYLE="background-color:greenyellow">平</FONT>';
$word[$town1] = '<FONT STYLE="background-color:yellow">村</FONT>';
$word[$town2] = '<FONT STYLE="background-color:orange">町</FONT>';
$word[$town3] = '<FONT STYLE="background-color:lightgrey">都</FONT>';
$word[$forest] = '<FONT STYLE="background-color:forestgreen">森</FONT>';
$word[$farm] = '<FONT STYLE="background-color:palegreen">農</FONT>';
$word[$factory] = '<FONT STYLE="background-color:gray">工</FONT>';
$word[$base] = '<FONT STYLE="background-color:olive">基</FONT>';
$word[$dbase] = '<FONT STYLE="background-color:crimson">防</FONT>';
}
# 陸地である
sub isLand($) {
my($land) = @_;
if(($land != $sea) && ($land != -1)) {
return 1;
} else {
return 0;
}
}
# 成長候補である
sub growLand($) {
my($land) = @_;
if(($land == $plains) ||
($land == $town1) ||
($land == $town2)) {
return 1;
} else {
return 0;
}
}
# 成長要素である
sub growFactor($) {
my($land) = @_;
if(($land == $town1) ||
($land == $town2) ||
($land == $town3) ||
($land == $farm)) {
return 1;
} else {
return 0;
}
}
# 平地系である
sub isPlain($) {
my($land) = @_;
if(($land == $plains) || ($land == $town1) ||
($land == $town2) || ($land == $town3)) {
return 1;
} else {
return 0;
}
}
# 大きな建物
sub isBuilding($) {
my($land) = @_;
if(($land == $factory) || ($land == $town3)) {
return 1;
} else {
return 0;
}
}
# 森
sub isForest($) {
my($land) = @_;
if($land == $forest) {
return 1;
} else {
return 0;
}
}
# 津波にやられるやつ
sub isTsunami($) {
my($land) = @_;
if(($land == $factory) || ($land == $town1) ||
($land == $town2) || ($land == $town3) ||
($land == $farm) || ($land == $base) ||
($land == $dbase)) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------------
# Command package 計画データ
#----------------------------------------------------------------------
package Command;
BEGIN{
# 計画の総数
$total = 16;
# 計画番号の設定
$doNothing = 0; # 資金繰り
$prepare = 1; # 整地
$prepare2 = 11; # 地ならし
$plant = 2; # 植林
$farm = 3; # 農地整備
$factory = 4; # 工場建設
$base = 5; # ミサイル基地建設
$dbase = 15; # 防衛施設建設
$reclaim = 6; # 埋め立て
$donate = 14; # 寄付
$aid = 13; # 資金援助
$missileNM = 7; # ミサイル発射
$missilePP = 8; # PPミサイル発射
$missileST = 12; # STミサイル発射
$missileLD = 9; # 陸地破壊弾発射
$giveup = 10; # 島の放棄
# 順番
@list = ($doNothing,
$prepare,
$prepare2,
$plant,
$farm,
$factory,
$base,
$dbase,
$reclaim,
$donate,
$aid,
$missileNM,
$missilePP,
$missileST,
$missileLD,
$giveup);
# 計画の名前
$name[$doNothing] = '資金繰り';
$name[$prepare] = '整地';
$name[$prepare2] = '地ならし';
$name[$plant] = '植林';
$name[$farm] = '農地整備';
$name[$factory] = '工場建設';
$name[$base] = 'ミサイル基地建設';
$name[$dbase] = '防衛施設建設';
$name[$reclaim] = '埋め立て';
$name[$donate] = '寄付';
$name[$aid] = '資金援助';
$name[$missileNM] = 'ミサイル発射';
$name[$missilePP] = 'PPミサイル発射';
$name[$missileST] = 'STミサイル発射';
$name[$missileLD] = '陸地破壊弾発射';
$name[$giveup] = '島の放棄';
# 必要な資金
$cost[$doNothing] = 0;
$cost[$prepare] = 5;
$cost[$prepare2] = 100;
$cost[$plant] = 5;
$cost[$farm] = 10;
$cost[$factory] = 100;
$cost[$base] = 300;
$cost[$dbase] = 1000;
$cost[$reclaim] = 100;
$cost[$donate] = 100;
$cost[$aid] = 500;
$cost[$missileNM] = 20;
$cost[$missilePP] = 50;
$cost[$missileST] = 50;
$cost[$missileLD] = 150;
$cost[$giveup] = 0;
# 現在受け取ったコマンド
$planNumber = 0; # 計画番号
$kind = 0; # コマンドの種類
$target = ''; # 標的
$x = 0; $y = 0; # 座標
$mode = 0; # モード(挿入、上書き、削除)
}
#----------------------------------------------------------------------
# Island package グローバル変数
#----------------------------------------------------------------------
package Island;
BEGIN {
# ターン数
$turn = 0;
# 島の数
$totalNumber = 0;
# 最終更新時間
$lastUpdateTime = 0;
# CGI入力関係
$name = '';
$password = '';
$password2 = '';
$mainMode = '';
$message = '';
$printMode = '';
# クッキー
$defaultName = '';
$defaultPassword = '';
$defaultTarget = '';
# 島配列(島型の配列)
@island = ();
# 島型
# 以下のメンバを持つハッシュ
# name 名前 :文字列
# money 資金 :整数値
# land 地形 :整数の2次元配列
# command 計画 :計画型の配列
# (以降はlandより算出)
# pop 人口 :整数
# work 職場 :整数
# arm 基地の数 :整数
# prod 生産力 :整数
# farm 農場の数 :整数
# factory 工場の数 :整数
# prepare 整地実行数 :整数
# prepare2 地ならし実行数 :整数
# launch ミサイル発射数 :整数
# dead 死滅 :0 or 1
# 計画型
# 以下のメンバを持つハッシュ
# kind コマンド:整数値
# target 標的の島:文字列
# x,y 座標:整数
}
#----------------------------------------------------------------------
#以降、各要求における動作
#----------------------------------------------------------------------
#----------------------------------------------------------------------
#TopPage package ゲームのトップページ
#----------------------------------------------------------------------
package TopPage;
sub main() {
# トップページの表示
&IO::out(&Temp::topPage());
# ログの表示
&Log::printAll();
}
#----------------------------------------------------------------------
# NewIsland package 島の新規作成
#----------------------------------------------------------------------
package NewIsland;
sub main() {
my($number, $land, @command, $i, $land);
# 名前があるかチェック
if($Island::name eq '') {
&IO::out(&Temp::newIslandNoName());
return;
}
# 島名の設定
$Island::name .= '島';
# 名前の重複チェック
if(&Util::nameToNumber($Island::name) != -1) {
# すでに発見ずみ
&IO::out(&Temp::newIslandAlready());
return;
}
# 名前の中に,がないかチェック
if($Island::name =~ /[,\?\(\)\<\>]/) {
# 使えない名前
&IO::out(&Temp::newIslandBadName());
return;
}
# passwordの存在判定
if($Island::password eq '') {
# password無し
&IO::out(&Temp::noPassword());
return;
}
# 確認用パスワード
if($Island::password ne $Island::password2) {
# password間違い
&IO::out(&Temp::wrongPassword());
return;
}
# 新しい島の番号を決める
$number = $Island::totalNumber;
# 島の番号を一つ増やす
$Island::totalNumber++;
# 初期コマンドを生成
for($i = 0; $i < $Value::commandMax; $i++) {
$command[$i] = {
'kind' => 0,
'target' => '',
'x' => 0,
'y' => 0
};
}
# 島型を生成
$land = &createLand();
$Island::island[$number] = {
'name' => $Island::name,
'password' => &Util::encode($Island::password),
'money' => $Value::startMoney,
'land' => $land,
'command' => \@command,
'message' => "(未登録)"
};
# 人口その他の計算
&Calc::estimate($Island::island[$number]);
# データの書き出し
&IO::writeIslands();
# logの書き出し
&IO::outLog(&Temp::logNewIsland($Island::name));
#「発見した」メッセージ
&IO::out(&Temp::newIslandSuccess($Island::island[$number]));
}
# 新規作成
sub createLand(){
my(@land, $i, $count);
# 島の基礎を作る
@land = &createLandBase();
# 平地を増殖
for($i = 0; $i < 50; $i++) {
&Hex::randomVisit(\&makePlains, @land);
}
# 森を増殖
for($i = 0; $i < 20; $i++) {
&Hex::randomVisit(\&makeForest, @land);
}
# 村を作る
$count = 0;
while($count < 2) {
$count += &Hex::randomVisit(\&makeTown, @land);
}
# 基地を作る
$count = 0;
while($count < 1) {
$count += &Hex::randomVisit(\&makeBase, @land);
}
return \@land;
}
#初期の陸地を決定
sub createLandBase() {
my(@land, $x, $y, $sx, $sy, $ex, $ey, $v);
#陸地を作る座標の範囲を設定
$sx = $Value::islandSize / 4;
$sy = $Value::islandSize / 4;
$ex = $Value::islandSize - $sx;
$ey = $Value::islandSize - $sy;
for($x = 0; $x < $Value::islandSize; $x++) {
for($y = 0; $y < $Value::islandSize; $y++) {
if(($x >= $sx) && ($x < $ex) &&
($y >= $sy) && ($y < $ey)) {
#範囲内の場合、陸地(荒地)に設定
$land[$x][$y] = $Land::wasteland;
} else {
#範囲外の場合、海に設定
$land[$x][$y] = $Land::sea;
}
}
}
return @land;
}
#平地を増やす
sub makePlains($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
#周囲すべて海なら増やさない
if(&Hex::countLand(\&Land::isLand, $x, $y, @land) != 0) {
return $Land::plains;
} else {
return $land;
}
}
#森を増やす
sub makeForest($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
#陸地だった場合に森にする
if(&Land::isLand($land)) {
return $Land::forest;
} else {
return $land;
}
}
#村を増やす
sub makeTown($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
#周囲すべて陸地で、まだ村でない場合に村にする
if((&Hex::countLand(\&Land::isLand, $x, $y, @land) == 7) &&
($land != $Land::town1)) {
$$unit = 1; #村にした場合はカウント
return $Land::town1;
} else {
return $land;
}
}
#基地を増やす
sub makeBase($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
#周囲すべて陸地で、村でない場合に村にする
if((&Hex::countLand(\&Land::isLand, $x, $y, @land) == 7) &&
($land != $Land::town1)) {
$$unit = 1; #基地にした場合はカウント
return $Land::base;
} else {
return $land;
}
}
#----------------------------------------------------------------------
# PrintIsland package 島の表示
#----------------------------------------------------------------------
package PrintIsland;
sub main() {
my($number);
# 島番号の取得
$number = &Util::nameToNumber($Island::name);
if($number == -1) {
# 何かの間違い
&IO::out($Temp::back);
return;
}
# 「ようこそ」メッセージ
&IO::out(&Temp::printIsland($Island::island[$number]));
# 最近の出来事表示
&Log::printOther($Island::name);
}
#----------------------------------------------------------------------
# Owner package 開発計画編集画面
#----------------------------------------------------------------------
package Owner;
sub main() {
my($number, $island);
# 島番号の取得
$number = &Util::nameToNumber($Island::name);
if($number == -1) {
# 何かの間違い
&IO::out($Temp::back);
return;
}
# 島の取得
$island = $Island::island[$number];
# password
if(&Util::encode($Island::password) ne $island->{'password'}) {
&IO::out(&Temp::wrongPassword());
return;
}
#コマンド編集画面の表示
&IO::out(&Temp::ownerMode($island));
# 最近の出来事表示
&Log::printOwner($Island::name);
}
#----------------------------------------------------------------------
# ComSend package 開発計画送信
#----------------------------------------------------------------------
package ComSend;
sub main() {
my($number, $island);
# 島番号の取得
$number = &Util::nameToNumber($Island::name);
if($number == -1) {
# 何かの間違い
&IO::out($Temp::back);
return;
}
# 島の取得
$island = $Island::island[$number];
# password
if(&Util::encode($Island::password) ne $island->{'password'}) {
&IO::out(&Temp::wrongPassword());
return;
}
# modeで分岐
if($Command::mode eq 'delete') {
&Util::slideFront($island->{'command'},$Command::planNumber);
&IO::out(&Temp::comDelete());
} else {
if($Command::mode eq 'insert') {
&Util::slideBack($island->{'command'},$Command::planNumber);
}
# コマンドをさしかえ
$island->{'command'}->[$Command::planNumber] = {
'kind' => $Command::kind,
'target' => $Command::target,
'x' => $Command::x,
'y' => $Command::y
};
&IO::out(&Temp::comAdd());
}
# データの書き出し
&IO::writeIslands();
# ロック解除
&Lock::unlock();
# 開発計画画面へ
&Owner::main();
}
#----------------------------------------------------------------------
# Process package ターン進行処理
#----------------------------------------------------------------------
package Process;
# 1ターン進める
sub turn() {
my($i, $r, $total, $island, @order);
$total = $Island::totalNumber;
# turnの数をふやす
$Island::turn++;
# 収入フェイズ
for($i = 0; $i < $total; $i++) {
$island = $Island::island[$i];
$island->{'money'} += $island->{'prod'};
}
# コマンドフェイズ
# コマンド処理順番を決める
for($i = 0; $i < $total; $i++ ){
$order[$i] = -1;
}
for($i = 0; $i < $total; $i++ ){
$r = int(rand(1) * $total);
if($order[$r] == -1) {
$order[$r] = $i;
} else {
$i--;
}
}
# orderに従ってコマンド処理
for($i = 0; $i < $total; $i++ ){
$island = $Island::island[$order[$i]];
if($island->{'dead'} != 1){
# コマンド1つ実行出来るまで回す
while(&doCommand($island) == 0){}
}
}
# 災害フェイズ
for($i = 0; $i < $total; $i++ ){
$island = $Island::island[$order[$i]];
if($island->{'dead'} != 1){
$currentName = $island->{'name'};
&doDisaster($island);
}
}
# 町の成長フェイズ
for($i = 0; $i < $total; $i++ ){
$island = $Island::island[$order[$i]];
if($island->{'dead'} != 1){
$currentName = $island->{'name'};
&doGrow($island);
}
}
# 死滅判定
for($i = 0; $i < $total; $i++ ){
$island = $Island::island[$i];
if($island->{'dead'} != 1){
# 人口計算
&Calc::estimate($island);
if($island->{'pop'} == 0) {
# ぜんめつ
$island->{'dead'} = 1;
&IO::outLog(&Temp::procDead($island->{'name'}));
}
}
}
# 遅延ログを書き出し
&IO::lateLogWrite();
}
# コマンド一つ実行
sub doCommand($) {
my($island) = @_;
my($command, $kind, $target, $x, $y, $cost, $comName, $land, $pt,
$landKind, $landName, $tn);
# コマンド取り出し
$command = $island->{'command'};
$kind = $command->[0]->{'kind'};
$target = $command->[0]->{'target'};
$x = $command->[0]->{'x'};
$y = $command->[0]->{'y'};
# 導出値
$name = $island->{'name'};
$land = $island->{'land'};
$landKind = $land->[$x][$y];
$landName = $Land::name[$landKind];
$cost = $Command::cost[$kind];
$comName = $Command::name[$kind];
$pt = &Temp::point($x, $y);
# 1つ詰めておく
&Util::slideFront($command, 0);
# 資金チェック
if($island->{'money'} < $cost) {
# 足りない場合
&IO::outLog(&Temp::procNoMoney($name, $comName));
return 0;
}
# コマンドで分岐
if($kind == $Command::doNothing) {
# 資金繰り
$island->{'money'} += 10;
$island->{'absent'} += 1;
if($island->{'absent'} >= $Value::expire) {
# 期限切れ
# 次のコマンドを放棄に
$command->[0]->{'kind'} = $Command::giveup;
}
return 1;
} else {
$island->{'absent'} = 0;
if(($kind == $Command::prepare) || ($kind == $Command::prepare2)){
# 整地
if($landKind == $Land::sea) {
# 海だと失敗
&IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName));
return 0;
}
# 成功
# コマンド名を'整地'に統一
$comName = $Command::name[$Command::prepare];
$land->[$x][$y] = $Land::plains;
$island->{'money'} -= $cost;
&IO::outLog(&Temp::procSuccess($name, $pt, $comName));
if($kind == $Command::prepare2) {
$island->{'prepare2'}++;
return 0;
}
$island->{'prepare'}++;
return 1;
} elsif($kind == $Command::reclaim) {
# 埋め立て
if($landKind != $Land::sea) {
# 海じゃないと失敗
&IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName));
return 0;
}
# 成功
$land->[$x][$y] = $Land::wasteland;
$island->{'money'} -= $cost;
&IO::outLog(&Temp::procSuccess($name, $pt, $comName));
return 1;
} elsif(($kind == $Command::plant) ||
($kind == $Command::farm) ||
($kind == $Command::factory) ||
($kind == $Command::base) ||
($kind == $Command::dbase)) {
# 建設系
if(!&Land::isPlain($land->[$x][$y])) {
# 平地系じゃないと失敗
&IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName));
return 0;
}
# 成功
if($kind == $Command::farm) {
# 農地
$land->[$x][$y] = $Land::farm;
&IO::outLog(&Temp::procSuccess($name, $pt, $comName));
} elsif($kind == $Command::factory) {
# 工場
$land->[$x][$y] = $Land::factory;
&IO::outLog(&Temp::procSuccess($name, $pt, $comName));
} elsif($kind == $Command::dbase) {
# 防衛施設
$land->[$x][$y] = $Land::dbase;
&IO::outLog(&Temp::procSuccess($name, $pt, $comName));
} elsif($kind == $Command::plant) {
# 森
$land->[$x][$y] = $Land::forest;
&IO::outLog(&Temp::procPBSuccess($name));
&IO::outLogSecret($name, &Temp::procSuccess($name, $pt, $comName));
} elsif($kind == $Command::base) {
# 基地
$land->[$x][$y] = $Land::base;
&IO::outLog(&Temp::procPBSuccess($name));
&IO::outLogSecret($name,&Temp::procSuccess($name, $pt, $comName));
}
$island->{'money'} -= $cost;
return 1;
} elsif($kind == $Command::giveup) {
# 島の放棄
&IO::outLog(&Temp::procGiveup($name));
$island->{'dead'} = 1;
return 1;
} elsif(($kind == $Command::donate) ||
($kind == $Command::aid)) {
#資金援助、寄付
# targetを取得
$tn = &Util::nameToNumber($target);
if($tn == -1) {
# その島がすでに無かったら失敗
&IO::outLog(&Temp::procAid2($name, $comName, $target));
} else {
$island->{'money'} -= $cost;
$Island::island[$tn]->{'money'} += $cost;
&IO::outLog(&Temp::procAid($name, $comName, $target));
}
return 0; # どちらにしてもターンは進まない
} elsif($kind == $Command::missileNM) {
return &launchMissile(19, 0, $island, $comName,
$target, $pt, $cost, $x, $y, $pt);
} elsif($kind == $Command::missilePP) {
return &launchMissile(7, 0, $island, $comName,
$target, $pt, $cost, $x, $y, $pt);
} elsif($kind == $Command::missileST) {
return &launchMissile(19, 2, $island, $comName,
$target, $pt, $cost, $x, $y, $pt);
} elsif($kind == $Command::missileLD) {
return &launchMissile(19, 1, $island, $comName,
$target, $pt, $cost, $x, $y, $pt);
}
}
return 0;
}
# ミサイル発射
sub launchMissile($$$$$$$$$$) {
my($err, $power, $island, $comName, $target, $pt, $cost, $x, $y, $pt) = @_;
my($name, $arm, $attack, $tn, $i, $tIsland,
$tLand, $tx, $ty, $tPt, $en, $tKind, $tName, $sName, $defence);
$name = $island->{'name'};
$arm = $island->{'arm'};
# 基地があるか判定
if($arm == 0) {
# 無かったら失敗
&IO::outLog(&Temp::procNoBase($name, $comName));
return 0;
}
# targetを取得
$tn = &Util::nameToNumber($target);
if($tn == -1) {
# その島がすでに無かったら失敗
&IO::outLog(&Temp::procNoTarget($name, $comName, $target));
return 0;
}
$tIsland = $Island::island[$tn];
$tLand = $tIsland->{'land'};
# 何発撃つか計算
$attack = &Util::min($arm, int(($island->{'money'} / $cost)));
$island->{'launch'} += $attack;
# ステルス
if($power == 2) {
$sName = $name;
$name = '???島';
}
# 発射
for($i = 0; $i < $attack; $i++) {
# 誤差値を計算
$en = int(rand(1) * $err);
# 着弾地点を算出
($tx, $ty) = &Hex::around($x, $y, $en);
$tPt = &Temp::point($tx, $ty);
# 領域外かどうか判定
if($tx == -1) {
# 領域外
if($power == 2) {
# ステルス
&IO::outLogLate(&Temp::missileOutArea($name, $comName,
$target, $pt));
&IO::outLogSecret($sName,
&Temp::missileOutArea($sName, $comName,
$target, $pt));
} else {
# 通常
&IO::outLog(&Temp::missileOutArea($name, $comName,
$target, $pt));
}
} else {
# 領域内
$tKind = $tLand->[$tx][$ty];
if($tKind == $Land::sea) {
# 海ポチャの場合
if($power == 2) {
# ステルス
&IO::outLogLate(&Temp::missileSea($name, $comName,
$target, $pt, $tPt));
&IO::outLogSecret($sName,
&Temp::missileSea($sName, $comName,
$target, $pt, $tPt));
} else {
&IO::outLog(&Temp::missileSea($name, $comName,
$target, $pt, $tPt));
}
} else {
# 防衛施設判定
if($tKind == $Land::dbase) {
$defence = 0;
} else {
$defence = &Hex::judgeDBase($tx, $ty, $tLand);
}
if($defence != 0) {
# キャッチされた場合
if($power == 2) {
# ステルス
&IO::outLogLate(&Temp::missileDef($name, $comName,
$target, $pt, $tPt));
&IO::outLogSecret($sName,
&Temp::missileDef($sName, $comName,
$target, $pt, $tPt));
} else {
&IO::outLog(&Temp::missileDef($name, $comName,
$target, $pt, $tPt));
}
} else {
# 陸地に落ちた場合
$tName = $Land::name[$tKind];
if(($power == 0) || ($power == 2)){
if($power == 2) {
# ステルス
&IO::outLogLate(&Temp::missileNormal($name, $comName,
$target,
$pt, $tPt,
$tName));
&IO::outLogSecret($sName,
&Temp::missileNormal($sName,
$comName,
$target,
$pt, $tPt,
$tName));
} else {
# 通常
&IO::outLog(&Temp::missileNormal($name, $comName,
$target, $pt, $tPt,
$tName));
}
$tLand->[$tx][$ty] = $Land::wasteland;
} elsif($power == 1) {
# 陸地破壊
&IO::outLog(&Temp::missileLD($name, $comName,
$target, $pt, $tPt,
$tName));
$tLand->[$tx][$ty] = $Land::sea;
}
}
}
}
$island->{'money'} -= $cost;
}
return 1;
}
# 町の成長判定
sub doGrow($) {
my($island) = @_;
my($count, $x, $y, $l, $d, $tx, $ty);
$count = &Hex::visit(\&grow, @{$island->{'land'}});
# $countに増えた人口が入ってるはずだが、
# 現時点では使用していない。
}
# 成長
sub grow($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random);
# 平地系じゃなければ何もしない
if(!&Land::growLand($land)) {
return $land;
}
# 周囲の町、畑を数える
$count = &Hex::countLand(\&Land::growFactor, $x, $y, @land);
# サイコロ(1-10)
$random = &Util::dice(10);
# 乱数に従って成長判定
if($count >= $random) {
if($land == $Land::plains) {
$$unit += 1;
return $Land::town1;
} elsif($land == $Land::town1) {
$$unit += 2;
return $Land::town2;
} elsif($land == $Land::town2) {
$$unit += 2;
return $Land::town3;
}
}
return $land;
}
# 災害判定
sub doDisaster($) {
my($island) = @_;
my($random, $price, $p, $i);
# 埋蔵金
$random = &Util::dice(1000);
if(($island->{'prepare'} > 0) && ($random <= $Value::maizo)) {
$price = 99 + &Util::dice(401);
$island->{'money'} += $price;
&IO::outLog(&Temp::disMaizo($currentName, $price));
}
# 火災
&Hex::visit(\&fire, @{$island->{'land'}});
# 台風
$random = &Util::dice(1000);
$p = $Value::typhoon * ($island->{'factory'} + 1);
if($random <= $p) {
&IO::outLog(&Temp::disTyphoon1($currentName));
&Hex::visit(\&typhoon, @{$island->{'land'}});
}
# 地震
$random = &Util::dice(1000);
$p = $Value::earthquake * ($island->{'prepare2'} + 1);
if($random <= $p) {
&IO::outLog(&Temp::disEarthquake1($currentName));
&Hex::visit(\&earthquake, @{$island->{'land'}});
}
# 津波
$random = &Util::dice(1000);
if($random <= $Value::tsunami) {
&IO::outLog(&Temp::disTsunami1($currentName));
&Hex::visit(\&tsunami, @{$island->{'land'}});
}
# 火山噴火
$random = &Util::dice(1000);
if($random <= $Value::eruption) {
&Hex::randomVisit(\&eruption, @{$island->{'land'}});
}
# 隕石
$random = &Util::dice(1000);
$p = $Value::meteo * ($island->{'launch'} + 1);
if($random <= $p) {
do {
&Hex::randomVisit(\&meteo, @{$island->{'land'}});
} while(&Util::dice(2) == 1);
}
}
# 火災(工場、都市が荒地になる)
sub fire($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $lName);
# 工場、都市じゃなければ何もしない
if(!&Land::isBuilding($land)) {
return $land;
}
# サイコロ(1-1000)
$random = &Util::dice(1000);
# 乱数に従って判定
if($random > $Value::fire) {
return $land;
}
# 周囲の森の数を数える(1-7)
$count = &Hex::countLand(\&Land::isForest, $x, $y, @land);
if($count > 0) {
# 森に隣接してれば何もしない
return $land;
}
# 乱数に従って火災判定
$lName = $Land::name[$land];
&IO::outLog(&Temp::disFire($currentName, $lName, $x, $y));
return $Land::wasteland; # 荒地になる
}
# 台風(農場が荒地になる)
sub typhoon($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $lName);
# 農場じゃなければ何もしない
if($Land::farm != $land) {
return $land;
}
# サイコロ(1-2)
$random = &Util::dice(2);
# 乱数に従って被害判定
if($random <= 1) {
$lName = $Land::name[$land];
&IO::outLog(&Temp::disTyphoon2($currentName, $lName, $x, $y));
return $Land::plains; # 平地になる
}
return $land;
}
# 地震(建物が荒地になる)
sub earthquake($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $lName);
# 工場、都市じゃなければ何もしない
if(!&Land::isBuilding($land)) {
return $land;
}
# サイコロ(1-3)
$random = &Util::dice(3);
# 乱数に従って被害判定
if($random <= 1) {
$lName = $Land::name[$land];
&IO::outLog(&Temp::disEarthquake2($currentName, $lName, $x, $y));
return $Land::wasteland; # 荒地になる
}
return $land;
}
# 津波(沿岸の建造物が荒地になる)
sub tsunami($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $lName);
# 津波対象地形かどうか調べる
if(!&Land::isTsunami($land)) {
return $land;
}
# 周囲の陸の数を数える(1-7)
$count = &Hex::countLand(\&Land::isLand, $x, $y, @land);
# 率を決定
$count = 6 - $count;
# サイコロ(1-10)
$random = &Util::dice(10);
# 乱数に従って被害判定
if($random <= $count) {
$lName = $Land::name[$land];
&IO::outLog(&Temp::disTsunami2($currentName, $lName, $x, $y));
return $Land::wasteland; # 荒地になる
}
return $land;
}
# 火山噴火(陸、海を問わず荒地になる)
sub eruption($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $l, $lName, $i, $tx, $ty);
# 発生
&IO::outLog(&Temp::disEruption0($currentName, $lName, $x, $y));
for($i = 0; $i < 7; $i++) {
($tx, $ty) = &Hex::around($x, $y, $i);
if($tx != -1) {
$l = $land[$tx][$ty];
$lName = $Land::name[$l];
# 海かどうかでメッセージを分ける
if($l == $Land::sea) {
# 海の場合
&IO::outLog(&Temp::disEruption1($currentName, $lName, $tx, $ty));
} else {
# 海じゃない場合
&IO::outLog(&Temp::disEruption2($currentName, $lName, $tx, $ty));
}
$land[$tx][$ty] = $Land::wasteland;
}
}
return $Land::wasteland; # 荒地へ。
}
# 隕石 落ちた所が海になる
sub meteo($$$$@) {
my($land, $x, $y, $unit, @land) = @_;
my($count, $random, $lName);
# 海かどうかでメッセージを分ける
$lName = $Land::name[$land];
if($land == $Land::sea) {
# 海の場合
&IO::outLog(&Temp::disMeteo1($currentName, $lName, $x, $y));
} else {
# 海じゃない場合
&IO::outLog(&Temp::disMeteo2($currentName, $lName, $x, $y));
}
return $Land::sea; # 海になる
}
#----------------------------------------------------------------------
#Hex package 座標関係
#----------------------------------------------------------------------
package Hex;
BEGIN {
#周囲2ヘックスの座標
#周囲2ヘックスの座標
@dx = (0,1,1,1,0,-1,0,1,2,2,2,1,0,-1,-1,-2,-1,-1,0);
@dy = (0,-1,0,1,1,0,-1,-2,-1,0,1,2,2,2,1,0,-1,-2,-2);
}
#周囲のヘックスを求める
sub around() {
my($sx, $sy, $number, $x, $y);
($sx, $sy, $number) = @_;
$x = $sx + $dx[$number];
$y = $sy + $dy[$number];
if((($sy % 2) == 1) && (($y % 2) == 0)) {
$x -= 1;
}
#範囲外の場合は(-1,-1)で統一
if(($x < 0) || ($x >= $Value::islandSize) ||
($y < 0) || ($y >= $Value::islandSize)) {
$x = -1;
$y = -1;
}
return ($x, $y);
}
#ランダムにヘックスを選ぶ(一番外側以外)
sub random() {
my($x, $y);
$x = int(rand(1) * ($Value::islandSize - 2)) + 1;
$y = int(rand(1) * ($Value::islandSize - 2)) + 1;
return ($x, $y);
}
#全部のヘックスをなめる
#引数は、適用関数、地形型(整数の2次元配列)
sub visit(&@) {
my($visitor,@land) = @_;
my($x, $y, $count, $unit);
#ループ
$count = 0;
for($y = 0; $y < $Value::islandSize; $y++) {
for($x = 0; $x < $Value::islandSize; $x++) {
$unit = 0; #カウント要素用
$land[$x][$y] = &$visitor($land[$x][$y], $x, $y, \$unit, @land);
$count += $unit; #カウント要素を加算
}
}
return $count;
}
#ランダムなヘックスに適用
#(一番外は除く)
sub randomVisit(&@) {
my($visitor,@land) = @_;
my($x, $y, $count);
#座標決定
($x, $y) = random();
$count = 0;
$land[$x][$y] = &$visitor($land[$x][$y], $x, $y, \$count, @land);
return $count;
}
#周囲のヘックス(+自分のヘックス)のうち、引数の数字のやつの探す
sub countLand(&$$@) {
my($cond, $sx, $sy, @land) = @_;
my($count, $i, $x, $y);
$count = 0;
for($i = 0; $i < 7; $i++) {
($x, $y) = &around($sx, $sy, $i);
if($x != -1) {
if(&$cond($land[$x][$y])) {
$count++;
}
}
}
return $count;
}
# 周囲2ヘックス(自分除く)に防衛施設があるかどうか
sub judgeDBase($$$) {
my($sx, $sy, $land) = @_;
my($i, $x, $y);
for($i = 1; $i < 19; $i++) {
($x, $y) = &around($sx, $sy, $i);
if($x != -1) {
if($land->[$x][$y] == $Land::dbase) {
return 1;
}
}
}
return 0;
}
#----------------------------------------------------------------------
#Calc package 人口や生産力等の計算
#----------------------------------------------------------------------
package Calc;
sub estimate($) {
my($island) = @_;
my($x, $y);
# 初期化
$island->{'pop'} = 0;
$island->{'farm'} = 0;
$island->{'factory'} = 0;
$island->{'work'} = 0;
$island->{'arm'} = 0;
# ループ
for($y = 0; $y < $Value::islandSize; $y++) {
for($x = 0; $x < $Value::islandSize; $x++) {
$l = $island->{'land'}->[$x][$y];
if($l == $Land::town1) {
# 村
$island->{'pop'} ++;
} elsif($l == $Land::town2) {
# 町
$island->{'pop'} += 3;
} elsif($l == $Land::town3) {
# 都市
$island->{'pop'} += 5;
} elsif($l == $Land::farm) {
# 農場
$island->{'farm'} ++;
$island->{'work'} +=10;
} elsif($l == $Land::factory) {
# 工場
$island->{'factory'} ++;
$island->{'work'} +=30;
} elsif($l == $Land::base) {
# 基地
$island->{'arm'} ++;
}
}
}
#生産力
$island->{'prod'} = &Util::min($island->{'pop'}, $island->{'work'});
}
#----------------------------------------------------------------------
# IO package 入出力
#----------------------------------------------------------------------
package IO;
# cgiデータの読み込み
sub cgiInput() {
my($line);
# 入力を受け取って日本語変換
$line = <>;
$line =~ tr/+/ /;
$line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$line = &jcode::euc($line);
$line =~ s/[\x00-\x1f\,]//g;
# 対象の島の名前
if($line =~ /CommandButton=(.*)へ送信/) {
# コマンド送信ボタンの場合
$Island::name = $1;
$Island::defaultName = $1;
} elsif($line =~ /ISLANDNAME=([^\&]*)\&/){
# その他の場合
$Island::name = $1;
$Island::defaultName = $1;
} else {
$Island::name = $line;
}
# パスワード
if($line =~ /PASSWORD=([^\&]*)\&/) {
$Island::password = $1;
$Island::defaultPassword = $1;
}
if($line =~ /PASSWORD2=([^\&]*)\&/) {
$Island::password2 = $1;
}
# メッセージ
if($line =~ /MESSAGE=([^\&]*)\&/) {
$Island::message = $1;
}
# 簡略表示モード
if($line =~ /SIMPLEMODE=simple\&/) {
$Island::printMode = 'simple';
} else {
$Island::printMode = '';
}
# main modeの取得
if($line =~ /TurnButton/) {
if($Value::debug == 1) {
$Island::mainMode = 'turn';
}
} elsif($line =~ /OwnerButton/) {
$Island::mainMode = 'owner';
} elsif($line =~ /SightButton/) {
$Island::mainMode = 'print';
} elsif($line =~ /NewIslandButton/) {
$Island::mainMode = 'new';
} elsif($line =~ /CommandButton/) {
$Island::mainMode = 'command';
# コマンドモードの場合、コマンドの取得
$line =~ /NUMBER=([^\&]*)\&/;
$Command::planNumber = $1;
$line =~ /COMMAND=([^\&]*)\&/;
$Command::kind = $1;
$line =~ /TARGETNAME=([^\&]*)\&/;
$Command::target = $1;
$Island::defaultTarget = $1;
$line =~ /POINTX=([^\&]*)\&/;
$Command::x = $1;
$line =~ /POINTY=([^\&]*)\&/;
$Command::y = $1;
$line =~ /COMMANDKIND=([^\&]*)\&/;
$Command::mode = $1;
} else {
$Island::mainMode = 'top';
}
}
# 島データの読み込み
sub parseAll() {
# ファイルを開く
if(open(IN, "hakoniwa.dat") == 0) {
close(IN);
my($now);
# データファイルが無かった場合、作る
open(OUT, ">hakoniwa.dat");
print OUT "1\n"; #ターン数
$now = time;
$now = $now - ($now % ($Value::unitTime));
print OUT "$now\n"; # 開始時間
print OUT "0\n"; # 島の数
close(OUT);
chmod(0666, 'hakoniwa.dat');
return &parseAll();
}
# 現在のターン数を読み込む
chomp($Island::turn = <IN>);
chomp($Island::lastUpdateTime = <IN>);
chomp($Island::totalNumber = <IN>);
my($i);
for($i = 0; $i < $Island::totalNumber; $i++) {
# 各島を読み込む
$Island::island[$i] = &parseIsland();
#人口その他の計算
&Calc::estimate($Island::island[$i]);
}
close(IN);
}
# 島一つをよみこみ
sub parseIsland() {
my($name, $password, $money, $y, $x, $i, $line, @land, @command);
chomp($name = <IN>); # 名前
chomp($absent = <IN>); # 連続資金繰り
chomp($message = <IN>); # メッセージ
chomp($password = <IN>); # password
chomp($money = <IN>); # 金
# 土地
for($y = 0; $y < $Value::islandSize; $y++) {
$line = <IN>;
for($x = 0; $x < $Value::islandSize; $x++) {
$line =~ s/.//;
if($& eq 'a') {
$land[$x][$y] = 10;
} else {
$land[$x][$y] = $&;
}
}
}
#コマンド
for($i = 0; $i < $Value::commandMax; $i++) {
$line = <IN>;
$line =~ /^(.*),(.*),(.*),(.*)$/;
$command[$i] = {
'kind' => $1,
'target' => $2,
'x' => $3,
'y' => $4
};
}
#島型にして返す
return {
'name' => $name,
'password' => $password,
'money' => $money,
'land' => \@land,
'command' => \@command,
'message' => $message,
'absent' => $absent
};
}
# 島データの書き出し
sub writeIslands() {
my($total, $i);
# 生きてる島を数える
$total = 0;
for($i = 0; $i < $Island::totalNumber; $i++) {
if($Island::island[$i]->{'dead'} != 1) {
$total++;
}
}
# ファイル開く
if(open(OUT, '>hakoniwa.dat') == 0) {
print "HOGE STOP";
exit(1);
}
# ターン数、最終更新、島の数
print OUT "$Island::turn\n";
print OUT "$Island::lastUpdateTime\n";
print OUT "$total\n";
# 各島を書き出す
for($i = 0; $i < $Island::totalNumber; $i++) {
if($Island::island[$i]->{'dead'} != 1) {
&writeIsland($Island::island[$i]);
}
}
# ファイル閉じる
close(OUT);
}
# 島一つの書き出し
sub writeIsland($) {
my($island) = @_;
my($land, $command, $x, $y, $i);
#名前、message、password、資金
print OUT "$island->{'name'}\n";
print OUT "$island->{'absent'}\n";
if($island->{'name'} eq $Island::defaultName) {
if($Island::message ne "") {
print OUT "${Island::message}\n";
} else {
print OUT "$island->{'message'}\n";
}
} else {
print OUT "$island->{'message'}\n";
}
print OUT "$island->{'password'}\n";
print OUT "$island->{'money'}\n";
# 要素取り出し
$land = $island->{'land'};
$command = $island->{'command'};
# 陸地の書き出し
for($y = 0; $y < $Value::islandSize; $y++) {
for($x = 0; $x < $Value::islandSize; $x++) {
printf OUT "%x",$land->[$x][$y];
}
print OUT "\n";
}
# 計画の書き出し
for($i = 0; $i < $Value::commandMax; $i++) {
print OUT "$command->[$i]->{'kind'},";
print OUT "$command->[$i]->{'target'},";
print OUT "$command->[$i]->{'x'},";
print OUT "$command->[$i]->{'y'}\n";
}
}
# 標準出力への出力
sub out($) {
my($str) = @_;
print STDOUT &jcode::sjis($str);
}
# logfile 1行追記
sub outLog($) {
my($str) = @_;
my($turn);
open(OUT, '>>hakoniwa.log0');
$turn = &Temp::logTurn();
print OUT "$turn$str\n";
close(OUT);
}
# logfile 遅延追記
sub outLogLate($) {
my($str) = @_;
my($turn);
$turn = &Temp::logTurn();
push(@lateLog, "$turn$str\n");
}
sub lateLogWrite() {
open(OUT, '>>hakoniwa.log0');
print OUT @lateLog;
close(OUT);
@lateLog = ();
}
# logfile 1行追記
sub outLogSecret($$) {
my($name, $str) = @_;
my($turn);
open(OUT, '>>hakoniwa.log0');
$turn = &Temp::logTurn();
print OUT "secretinfo$name${turn}<B>(機密)</B>$str\n";
close(OUT);
}
#----------------------------------------------------------------------
#Lock package 同時アクセス対策
#----------------------------------------------------------------------
package Lock;
sub lock() {
my($t);
# ロックを試す
if(unlink('./key-free')) {
# 成功
# ロック時間書き出し
open(OUT, '>key-locked');
print OUT time;
close(OUT);
return 1;
} else {
# ロック時間チェック
if(!open(IN, 'key-locked')) {
return 0;
}
$t = <IN>;
close(IN);
if(($t != 0) && (($t + 120) < time)) {
# 120秒以上経過してたら、強制的にロックを外す
unlock();
}
return 0;
}
}
sub unlock() {
# ロックを外す
my($i);
$i = rename('./key-locked', './key-free');
}
#----------------------------------------------------------------------
#Util package 各種便利ツール
#----------------------------------------------------------------------
package Util;
#島の名前から番号を取得するやつ
sub nameToNumber {
my($i, $name);
$name = $_[0];
for($i = 0; $i < $Island::totalNumber; $i++){
if($Island::island[$i]->{'name'} eq $name) {
return $i;
}
}
return -1;
}
#pass wordをエンコードするやつ
sub encode($) {
return crypt($_[0], 'hakoniwa');
# (cryptの使い方の自信無し)
}
#小さい方を返すやつ
sub min($$) {
my($x, $y) = @_;
if($x > $y) {
return $y;
} else {
return $x
}
}
# コマンドを後ろにずらすやつ
sub slideBack($$) {
my($command,$number,$i) = @_;
my($i);
for($i = $Value::commandMax - 1; $i > $number; $i--) {
$command->[$i] = $command->[$i - 1];
}
}
# コマンドを前につめるやつ
sub slideFront($$) {
my($command,$number) = @_;
my($i);
for($i = $number; $i < ($Value::commandMax - 1); $i++) {
$command->[$i] = $command->[$i + 1];
}
$command->[$Value::commandMax - 1] = {
'kind' => 0,
'target' => '',
'x' => 0,
'y' => 0
};
}
# 1d10
sub dice($) {
return int(rand(1) * $_[0]) + 1;
}
# 人口順にソート
sub sort() {
my($flag, $size, $i, $tmp);
# ばぶるそおと
$flag = 1;
$size = $Island::totalNumber;
while($flag == 1) {
$flag = 0;
for($i = 0; $i < ($size - 1); $i++) {
if($Island::island[$i]->{'pop'} <
$Island::island[$i + 1]->{'pop'}) {
$flag = 1;
# 島の入れ換え
$tmp = $Island::island[$i];
$Island::island[$i] = $Island::island[$i + 1];
$Island::island[$i + 1] = $tmp;
}
}
}
}
#----------------------------------------------------------------------
#Cookie package cookie入出力
#----------------------------------------------------------------------
package Cookie;
#cookie入力
sub input() {
my($cookie);
$cookie = &jcode::euc($ENV{'HTTP_COOKIE'});
if($cookie =~ /${Value::baseDir}OWNISLANDNAME=\(([^\)]*)\)/) {
$Island::defaultName = $1;
}
if($cookie =~ /${Value::baseDir}OWNISLANDPASSWORD=\(([^\)]*)\)/) {
$Island::defaultPassword = $1;
}
if($cookie =~ /${Value::baseDir}TARGETISLANDNAME=\(([^\)]*)\)/) {
$Island::defaultTarget = $1;
}
}
#cookie出力
sub output() {
my($cookie, $info);
# 消える期限の設定
my($sec, $min, $hour, $date, $mon, $year, $day, $yday, $dummy) =
gmtime(time + 30 * 86400); # 現在 + 30日
# 2ケタ化
if ($year < 10) { $year = "0$year"; }
if ($date < 10) { $date = "0$date"; }
if ($hour < 10) { $hour = "0$hour"; }
if ($min < 10) { $min = "0$min"; }
if ($sec < 10) { $sec = "0$sec"; }
# 曜日を文字に
$day = ("Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday")[$day];
# 月を文字に
$mon = ("Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[$mon];
# パスと期限のセット
$info = "; expires=$day, $date\-$mon\-$year $hour:$min:$sec GMT\n";
# $info = "path=$Value::baseDir/\n";
$cookie = '';
if(($Island::name) && ($Island::mainMode eq 'owner')){
# if($Island::name) {
$cookie .= "Set-Cookie: ${Value::baseDir}OWNISLANDNAME=($Island::name) $info";
}
if($Island::password) {
$cookie .= "Set-Cookie: ${Value::baseDir}OWNISLANDPASSWORD=($Island::password) $info";
}
if($Command::target) {
$cookie .= "Set-Cookie: ${Value::baseDir}TARGETISLANDNAME=($Command::target) $info";
}
&IO::out($cookie);
}
#----------------------------------------------------------------------
#Log package Log表示関係
#----------------------------------------------------------------------
package Log;
sub printAll() {
my($i);
for($i = 0; $i < $Value::logPrint; $i++) {
&print('', 0, "hakoniwa.log$i");
}
}
sub printOther($) {
my($i);
for($i = 0; $i < $Value::logMax; $i++) {
&print($_[0], 0, "hakoniwa.log$i");
}
}
sub printOwner($) {
my($i);
for($i = 0; $i < $Value::logMax; $i++) {
&print($_[0], 1, "hakoniwa.log$i");
}
}
sub print($$$) {
my($name, $secret, $fileName) = @_;
my($count, @line, $i, $line, $turn);
$turn = &Temp::logTurn();
# ログファイルを読み込む
open(IN, $fileName);
$count = 0;
while(<IN>) {
$line[$count] = $_;
$count++;
}
close(IN);
# 表示
for($i = $count - 1; $i >= 0; $i--) {
$line = $line[$i];
if($line =~ /^secretinfo/) {
# 機密情報チェック
if(($secret == 1) && ($line =~ s/^secretinfo$name//)) {
&IO::out($line . '<BR>');
}
} else {
if(($name eq '') || ($line =~ /$name/)) {
&IO::out($line . '<BR>');
}
}
}
}
#----------------------------------------------------------------------
#Temp package 出力Template
#----------------------------------------------------------------------
package Temp;
BEGIN {
my($i, $j, $c, $selected);
# タイトル
$tt_ = '<FONT COLOR="#4040a0"><B>';
$_tt = '</B></FONT>';
# 大きい文字
$big_ = '<FONT SIZE=6><B>';
$_big = '</B></FONT>';
# ちょっと大きい文字
$mid_ = '<FONT SIZE=4><B>';
$_mid = '</B></FONT>';
# 強調文字、表項目
$ind_ = '<FONT COLOR="#800000"><B>';
$_ind = '</B></FONT>';
# 位置、島の名前
$pt_ = '<FONT COLOR="#a06040"><B>';
$_pt = '</B></FONT>';
# 島の名前、薄め
$pt2_ = '<FONT COLOR="#808080"><B>';
$_pt2 = '</B></FONT>';
# コマンド
$com_ = '<FONT COLOR="#202060"><B>';
$_com = '</B></FONT>';
# 災害
$red_ = '<FONT COLOR="#e00000"><B>';
$_red = '</B></FONT>';
# 島のSELECTの中身
$islandList = '';
$targetList = '';
# 「戻る」リンク
$back = "<A HREF=\"$Value::thisFile\">${big_}戻る${_big}</A>";
# 計画番号用のリストボックス
$numberList = '';
for($i = 0; $i < $Value::commandMax; $i++) {
$j = $i + 1;
$numberList .=
"<OPTION VALUE=$i>$j\n";
}
# 座標用のリストボックス
$pointList = '';
for($i = 0; $i < $Value::islandSize; $i++) {
$pointList .=
"<OPTION VALUE=$i>$i\n";
}
# 計画用のリストボックス
$commandList = '';
for($i = 0; $i < $Command::total; $i++) {
$c = $Command::list[$i];
if($c == $Command::prepare) {
$selected = 'SELECTED'; # 整地をデフォルトに
} else {
$selected = '';
}
$commandList .= "<OPTION VALUE=$c $selected>$Command::name[$c]($Command::cost[$c]$Value::moneyUnit)";
}
}
# 島データのプルダウンメニュー用
sub getIslandList($) {
my($select) = @_;
my($list, $name);
#島リストのメニュー
$list = '';
for($i = 0; $i < $Island::totalNumber; $i++) {
$name = $Island::island[$i]->{'name'};
if($name eq $select) {
$s = 'SELECTED';
} else {
$s = '';
}
$list .=
"<OPTION VALUE=\"$name\" $s>$name\n";
}
return $list;
}
#プルダウンメニューの内容等を更新する
#(島データが更新された後に呼ばれる)
sub initialize() {
my($i, $j, $s, $name, $pop, $money, $farm, $factory, $message, $absent,
$pm);
# 簡略表示チェックボックス
if($Island::printMode eq 'simple') {
$pm = 'CHECKED';
} else {
$pm = '';
}
$simpleBox = "<INPUT TYPE=checkbox NAME=SIMPLEMODE VALUE=\"simple\" $pm>簡略表示\n";
# 島リストのメニュー
$islandList = &getIslandList($Island::defaultName);
$targetList = &getIslandList($Island::defaultTarget);
# ランキングの中身
$islandRanking = '';
for($i = 0; $i < $Island::totalNumber; $i++) {
$j = $i + 1;
$name = $Island::island[$i]->{'name'};
$pop = $Island::island[$i]->{'pop'};
$money = $Island::island[$i]->{'money'};
$farm = $Island::island[$i]->{'farm'};
$factory = $Island::island[$i]->{'factory'};
$message = $Island::island[$i]->{'message'};
$message = &escape($message);
$absent = $Island::island[$i]->{'absent'};
if($absent > 0) {
$name = "<TD><NOBR>${pt2_}$name${_pt2}</NOBR></TD>";
} else {
$name = "<TD><NOBR>${pt_}$name${_pt}</NOBR></TD>";
}
$islandRanking .= <<END;
<TR>
<TD align=center><NOBR>${mid_}$j${_mid}</NOBR></TD>
$name
<TD><NOBR>$pop$Value::popUnit</NOBR></TD>
<TD><NOBR>$money$Value::moneyUnit</NOBR></TD>
<TD align=center><NOBR>$factory</NOBR></TD>
<TD align=center><NOBR>$farm</NOBR></TD>
<TD><NOBR>$message</NOBR></TD>
</TR>
END
}
}
# HTMLの文字をエスケープ
sub escape($) {
my($s) = @_;
$s =~ s/&/&/g;
$s =~ s/</</g;
$s =~ s/>/>/g;
$s =~ s/\"/"/g; #"
return $s;
}
# HTMLのアタマ
sub header($) {
my($body) = @_;
return <<END;
Content-type: text/html
<HTML>
<HEAD>
<TITLE>
箱庭諸島
</TITLE>
</STYLE>
</HEAD>
<BODY $body>
END
}
# HTMLのケツ
sub footer() {
return <<END;
<HR>
<P align=center>
管理者:$Value::admin(<A HREF="mailto:$Value::email">$Value::email</A>)<BR>
掲示板(<A HREF="$Value::bbs">$Value::bbs</A>)<BR>
トップページ(<A HREF="$Value::toppage">$Value::toppage</A>)<BR>
箱庭諸島のページ(<A HREF="http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html">http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html</A>)<BR>
</P>
</BODY>
</HTML>
END
}
#トップページ
sub topPage() {
my($debugStr, $newStr);
$debugStr = '';
if($Value::debug == 1) {
$debugStr = <<END;
<FORM action="$Value::thisFile" method=POST>
<INPUT TYPE=submit VALUE="ターンを進める" NAME=TurnButton>
</FORM>
END
}
if($Island::totalNumber >= $Value::maxIsland) {
$newStr = <<END;
<H1>${tt_}新しい島を探す${_tt}</H1>
島の数が最大数です・・・現在登録できません。
END
} else {
$newStr = <<END;
<H1>${tt_}新しい島を探す${_tt}</H1>
<FORM action="$Value::thisFile" method=POST>
どんな名前をつける予定?<BR>
<INPUT TYPE=text NAME=ISLANDNAME SIZE=32 MAXLENGTH=32>島<BR>
パスワードは?<BR>
<INPUT TYPE=password NAME=PASSWORD SIZE=32 MAXLENGTH=32><BR>
念のためパスワードをもう一回<BR>
<INPUT TYPE=password NAME=PASSWORD2><BR>
<INPUT TYPE=submit VALUE="探しに行く" NAME=NewIslandButton>
</FORM>
END
}
return <<END;
$debugStr
<H1>${tt_}自分の島へ${_tt}</H1>
<FORM action="$Value::thisFile" method=POST>
あなたの島の名前は?<BR>
<SELECT NAME=ISLANDNAME>
$islandList
</SELECT><BR>
パスワードをどうぞ!!<BR>
<INPUT TYPE=password NAME=PASSWORD VALUE="$Island::defaultPassword"><BR>
$simpleBox<BR>
<INPUT TYPE=submit VALUE="開発しに行く" NAME=OwnerButton><BR>
</FORM>
<HR>
<H1>${tt_}その他の島へ${_tt}</H1>
<FORM action="$Value::thisFile" method=POST>
どの島を見に行く?<BR>
<SELECT NAME=ISLANDNAME>
$islandList
</SELECT>
<BR>
$simpleBox<BR>
<INPUT TYPE=submit VALUE="観光しに行く" NAME=SightButton>
</FORM>
<HR>
$newStr
<HR>
<H1>${tt_}諸島の状況${_tt}</H1>
<TABLE BORDER>
<TR><TD COLSPAN=7>
${big_}ターン${Island::turn}:${_big}
</TD></TR>
<TR>
<TH><NOBR>${ind_}順位${_ind}</NOBR></TH>
<TH><NOBR>${ind_}島${_ind}</NOBR></TH>
<TH><NOBR>${ind_}人口${_ind}</NOBR></TH>
<TH><NOBR>${ind_}資金${_ind}</NOBR></TH>
<TH><NOBR>${ind_}工場${_ind}</NOBR></TH>
<TH><NOBR>${ind_}農場${_ind}</NOBR></TH>
<TH><NOBR>${ind_}コメント${_ind}</NOBR></TH>
$islandRanking
</TR>
</TABLE>
<HR>
<H1>${tt_}最近の出来事${_tt}</H1>
END
}
# 島の表示
sub islandMap($$) {
my($mode, $island) = @_;
my($str, $x, $y, $kind, $caption, $land, $sm, $tmp);
$land = $island->{'land'};
if($Island::printMode eq 'simple') {
$sm = 1;
} else {
$sm = 0;
}
# 本体
$str = '';
$str .= <<END;
<CENTER>
<TABLE BORDER>
<TR>
<TH>${ind_}人口${_ind}</TH>
<TD>$island->{'pop'}$Value::popUnit</TD>
<TH>${ind_}資金${_ind}</B></TH>
<TD>$island->{'money'}$Value::moneyUnit</TD>
</TR>
<TR>
<TH>${ind_}工場${_ind}</TH>
<TD align=center>$island->{'factory'}</TD>
<TH>${ind_}農場${_ind}</B></TH>
<TD align=center>$island->{'farm'}</TD>
</TR>
</TABLE>
<TABLE BORDER WIDTH=0 HEIGHT=0 CELLSPACING=0 CELLPADDING=0>
<TR><TD>
END
if($sm == 0) {
$str .= "<IMG SRC=\"$Value::imageDir/xbar.gif\" width=400 height=16><BR>";
} else {
$str .= "<PRE><FONT SIZE=5> 0 1 2 3 4 5 6 7 8 9 0 1\n";
}
for($y = 0; $y < $Value::islandSize; $y++) {
if($sm == 1) {
if($y < 10) {
$str .= "$y";
} else {
$tmp = $y - 10;
$str .= "$tmp";
}
}
if(($y % 2) == 0) {
if($sm == 0) {
$str .= "<IMG SRC=\"$Value::imageDir/space${y}.gif\" width=16 height=32>";
} else {
$str .= " ";
}
}
for($x = 0; $x < $Value::islandSize; $x++) {
$kind = $land->[$x][$y];
if(($kind == $Land::base) && ($mode == 0)) {
$kind = $Land::forest;
}
$caption= "($x, $y)$Land::name[$kind]";
if($sm == 0) {
$str .= "<IMG SRC=\"$Value::imageDir/land$kind.gif\" ALT=\"$caption\" width=32 height=32>";
} else {
$str .= $Land::word[$kind];
}
}
if(($y % 2) == 1) {
if($sm == 0) {
$str .= "<IMG SRC=\"$Value::imageDir/space${y}.gif\" width=16 height=32>";
} else {
$str .= " ";
}
}
if($sm == 0) {
$str .= "<BR>";
} else {
$str .= "\n";
}
}
if($sm == 1) {
$str .= "</FONT>";
} $str .= "</TD></TR></TABLE></CENTER>";
return $str;
}
- 新規で名前が無い場合
sub newIslandNoName() { return <<END; ${big_}島につける名前が必要です。${_big}$back END }
- 新規で名前がすでに使用されている場合
sub newIslandAlready() { return <<END; ${big_}その島ならすでに発見されています。${_big}$back END }
- 新規で名前が反則な場合
sub newIslandBadName() { return <<END; ${big_}',?()<>'とか入った変な文字入った名前はやめましょうよ~。${_big}$back END }
- 新規で島が作成された場合
sub newIslandSuccess($) {
my($island) = @_; $map = &Temp::islandMap(1,$island);
return <<END;
${big_}島を発見しました!!${_big}
${big_}${pt_}「$island->{'name'}」${_pt}${_big}
${big_}と名付けます。${_big}
$map
$back
END }
- 島の表示モード
sub printIsland($) {
my($island) = @_; $map = &Temp::islandMap(0,$island);
return <<END;
${big_}${pt_}$island->{'name'}${_pt}へようこそ!!${_big}
$back
$map
$back
${big_}${pt_}$island->{'name'}${_pt}の近況${_big}
END
}
- コマンド変数モード
sub ownerMode($) {
my($island) = @_;
my($map, $command1, $command2, $command3, $command4);
$map = &islandMap(1,$island);
$command1 = &islandCommand($island->{'command'}, 0,
int($Value::commandMax / 5 * 2));
$command2 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 2), int($Value::commandMax / 5 * 3));
$command3 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 3), int($Value::commandMax / 5 * 4));
$command4 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 4), $Value::commandMax); return <<END;
${big_}${pt_}$island->{'name'}${_pt}開発計画${_big}
$back
<FORM action="$Value::thisFile" method=POST>
| 計画番号 | 開発計画 | ターゲット | 座標 |
|---|---|---|---|
|
<SELECT NAME=NUMBER> $numberList </SELECT> |
<SELECT NAME=COMMAND> $commandList </SELECT> |
<SELECT NAME=TARGETNAME> $targetList </SELECT> |
( <SELECT NAME=POINTX> $pointList </SELECT> , <SELECT NAME=POINTY> $pointList </SELECT> ) |
|
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=insert CHECKED>挿入
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=write>上書き
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=delete>削除
$simpleBox |
|||
|
コメント<INPUT TYPE=text NAME=MESSAGE SIZE=80 MAXLENGTH=80> |
|||
|
パスワード
<INPUT TYPE=password NAME=PASSWORD VALUE="$Island::defaultPassword"> |
<INPUT TYPE=submit VALUE="$island->{'name'}へ送信" NAME=CommandButton> |
||
</FORM>
|
|
$map |
|
|
|
|
|
$back
${big_}${pt_}$island->{'name'}${_pt}の近況${_big}
END
}
sub islandCommand($$$) {
my($command, $start, $end) = @_;
my($i, $j, $kind, $target, $x, $y, $str, $pt);
$str = ;
for($i = $start; $i < $end; $i++) {
$j = $i + 1; $str .= "<TR><TD>$ind_$j$_ind</TD><TD>";
# 各値の取り出し $kind = $command->[$i]->{'kind'}; $target = $command->[$i]->{'target'}; $x = $command->[$i]->{'x'}; $y = $command->[$i]->{'y'};
# 基本部品 $pt = &point($x, $y); # 座標 $tg = &targetName($target); # 発射目標
# 分岐 if(($kind == $Command::doNothing) ||($kind == $Command::giveup)) { # 資金繰り、島の放棄 $str .= "${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::prepare) ||($kind == $Command::prepare2) ||($kind == $Command::plant) ||($kind == $Command::farm) ||($kind == $Command::factory) ||($kind == $Command::base) ||($kind == $Command::dbase) ||($kind == $Command::reclaim)) { $str .= "$ptで${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::missileNM) ||($kind == $Command::missilePP) ||($kind == $Command::missileST) ||($kind == $Command::missileLD)) { $str .= "$tgの$ptへ${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::donate) || ($kind == $Command::aid)) { $str .= "$tgへ${com_}$Command::name[$kind]${_com}"; }
$str .= "</TD></TR>";
} return $str;
}
- 座標
sub point($$) {
my($x, $y) = @_; return "$pt_($x,$y)$_pt";
}
- 座標
sub targetName($) {
return "$pt_$_[0]$_pt";
}
- password無し
sub noPassword() { return <<END; ${big_}パスワードがありません。${_big}$back END }
- password間違い
sub wrongPassword() { return <<END; ${big_}パスワードが違います。${_big}$back END }
- lock失敗
sub lockFail() { return <<END; ${big_}同時アクセスエラーです。${_big}$back END }
- ターン
sub logTurn() {
return "${ind_}ターン${Island::turn}:${_ind}";
}
- 島発見の log記述
sub logNewIsland($) {
return "新しく${pt_}$_[0]${_pt}が発見されました。";
}
- コマンド削除
sub comDelete() {
return "${big_}コマンドを削除しました${_big}";
}
- コマンド登録
sub comAdd() {
return "${big_}コマンドを登録しました${_big}";
}
- 資金不足
sub procNoMoney($$) {
my($name, $com) = @_;
return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、資金不足のため実行できませんでした。";
}
- 整地等の失敗
sub procNotAdeqLand($$$$) {
my($name, $pt, $com, $land) = @_;
return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、予定地の${pt_}$pt${_pt}地点が${big_}$land${_big}であったため実施できませんでした。";
}
- 整地等の成功
sub procSuccess($$$) {
my($name, $pt, $com) = @_;
return "${pt_}$name$pt${_pt}で${com_}$com${_com}が行われました。";
}
- 森か基地の建設
sub procPBSuccess($) {
my($name) = @_;
return "こころなしか、${pt_}$name${_pt}の${big_}森${_big}が増えたようです。";
}
- 島の放棄
sub procGiveup($) {
my($name) = @_;
return "${pt_}$name${_pt}は放棄され、${big_}無人島${_big}になりました。";
}
- 資金援助
sub procAid($$$) {
my($name, $com, $target) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}へ${com_}$com${_com}を行いました。";
}
sub procAid2($$$) {
my($name, $com, $target) = @_;
return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、${pt_}$target${_pt}がすでに${big_}無人島${_big}になっているため手遅れでした。";
}
- 基地が無くてミサイルが打てない
sub procNoBase($$) {
my($name, $com) = @_;
return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、ミサイル基地を保有していないため実施できませんでした。";
}
- 目標が無くてミサイルが打てない
sub procNoTarget($$$) {
my($name, $com, $target) = @_;
return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、目標の${pt_}$target${_pt}がすでに放棄されているため、中止されました。";
}
- 画面外に落ちる
sub missileOutArea($$$$) {
my($name, $com, $target, $pt) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、領域外の海に落ちた模様です。";
}
- 海ポチャ
sub missileSea($$$$$) {
my($name, $com, $target, $pt, $tPt) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、${pt_}$tPt${_pt}の海に落ちた模様です。";
}
- 防衛施設でキャッチ
sub missileDef($$$$$) {
my($name, $com, $target, $pt, $tPt) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、${pt_}$tPt${_pt}地点上空で力場に捕らえられ、${big_}空中爆破${_big}しました。";
}
- 通常弾
sub missileNormal($$$$$$) {
my($name, $com, $target, $pt, $tPt, $tName) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行い、${pt_}$tPt${_pt}の${big_}$tName${_big}に着弾。一帯が荒地と化しました。";
}
- 陸地破壊
sub missileLD($$$$$$) {
my($name, $com, $target, $pt, $tPt, $tName) = @_;
return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行い、${pt_}$tPt${_pt}の${big_}$tName${_big}に着弾。一帯が水没しました。";
}
- 死滅
sub procDead($) {
my($name) = @_;
return "${pt_}$name${_pt}から人がいなくなり、${big_}無人島${_big}になりました。";
}
- 火災発生
sub disFire($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}で${red_}火災発生${_red}、${lName}は壊滅しました。";
}
- 台風発生
sub disTyphoon1($) {
my($name) = @_;
return "${pt_}$name${_pt}を${red_}台風${_red}が襲いました。";
}
- 台風被害
sub disTyphoon2($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}台風${_red}によりドームごと飛ばされました。";
}
- 地震発生
sub disEarthquake1($) {
my($name) = @_;
return "${pt_}$name${_pt}で大規模な${red_}地震${_red}が発生しました。";
}
- 地震被害
sub disEarthquake2($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}地震${_red}により壊滅しました。";
}
- 津波発生
sub disTsunami1($) {
my($name) = @_;
return "${pt_}$name${_pt}付近で巨大な${red_}津波${_red}が発生しました。";
}
- 津波被害
sub disTsunami2($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}津波${_red}により壊滅しました。";
}
- 火山噴火発生
sub disEruption0($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}で突然${red_}火山が噴火${_red}!!";
}
- 噴火の影響、海
sub disEruption1($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}に陸地ができました。";
}
- 噴火の影響、陸
sub disEruption2($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}だった所は、${red_}噴火${_red}により荒地になりました。";
}
- 海に隕石落下
sub disMeteo1($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点に${red_}隕石${_red}が落ちましたが、${big_}$lName${_big}であったため無事でした。";
}
- 陸に隕石落下
sub disMeteo2($$$$) {
my($name, $lName, $x, $y) = @_;
return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}に${red_}隕石${_red}が落ち、一帯の陸地が水没しました。";
}
- 埋蔵金
sub disMaizo($$) {
my($name, $price) = @_;
return "${pt_}$name${_pt}で行われた整地中に、${big_}$price$Value::moneyUnit${_big}もの埋蔵金が発見されました。";
}
</nowiki>
</pre>
以上でスクリプト本文の記述は終わりです。
解説
箱庭諸島ver1のスクリプト
[1]より