NoCarGoal-v1/ 0000700 0001750 0001001 00000000000 12014513673 011524 5 ustar Leif None NoCarGoal-v1/companydata.nut 0000700 0001750 0001001 00000015670 12014511511 014555 0 ustar Leif None
//------------------------------------------------------------//
// //
// Class for storage of company specific data //
// //
//------------------------------------------------------------//
class CompanyData
{
_company_id = null; // company id
_goal_list = null; // index = GOLD, SILVER or BRONZE
_transported_list = null; // index = 0, 1, 2 for the three cargoes (with lowest cargo ID first)
_hq_sign = null; // sign id of the sign sitting ontop of the HQ
_goal_ptr = null;
constructor(company_id, goal_ptr)
{
this._company_id = company_id;
this._goal_list = [-1, -1, -1];
this._transported_list = [0, 0, 0];
this._hq_sign = -1;
this._goal_ptr = goal_ptr;
}
// Creates goal in the GUI
function CreateGoals();
function UpdateGoals();
// Send information about goal to AI or Human players
function InformAboutGoal();
// Track goal progress
function TrackProgress();
// Called when the end of game has been reached
function GameEnd();
// Called at end of year (but not when the game end has been reached)
function EndOfYear();
// For save/load
function SaveToTable();
static function CreateFromTable(table, goal_ptr);
}
function CompanyData::CreateGoals()
{
this.UpdateGoals();
}
function CompanyData::UpdateGoals()
{
// Create goals for the goal GUI
for(local i = 0; i < 3; i++)
{
local transport_target = GSController.GetSetting("transport_target");
local should_exist = this._transported_list[i] < transport_target;
local exists = GSGoal.IsValidGoal(this._goal_list[i]);
Log.Info(GSCompany.GetName(this._company_id) + " - " + GSCargo.GetCargoLabel(this._goal_ptr._cargo_list[i]) + ": target: " + transport_target + " transported: " + this._transported_list[i] + " exist: " + exists + " should exist: " + should_exist, Log.LVL_DEBUG);
// Exist, but should be removed?
if(exists && !should_exist)
GSGoal.Remove(this._goal_list[i]);
// Doesn't exist, but should exist?
if(!exists && should_exist)
{
this._goal_list[i] =
GSGoal.New(this._company_id, GSText(GSText.STR_GOAL_GOLD + i,
// target
transport_target,
// goal cargoes
1 << this._goal_ptr._cargo_list[0],
1 << this._goal_ptr._cargo_list[1],
1 << this._goal_ptr._cargo_list[2],
// target year
this._goal_ptr.GetEndYear()/*,
// progress:
this._transported_list[0],
this._transported_list[1],
this._transported_list[2]*/
), GSGoal.GT_NONE, 0);
}
}
}
/* returns GOLD, SILVER, BRONZE or NO_MEDAL */
function CompanyData::GetMedal()
{
local num_achived = 0;
for(local i = 0; i < 3; i++)
{
if(this._transported_list[i] > GSController.GetSetting("transport_target"))
{
num_achived++;
}
}
switch(num_achived)
{
case 3: return GOLD;
case 2: return SILVER;
case 1: return BRONZE;
default: return NO_MEDAL;
}
}
function CompanyData::InformAboutGoal()
{
//if(g_scp.CanSpeakWith(this._company_id))
//{
// g_scp.TellCompany("NewGoal", "TransportGoals", this._company_id, this._goal_value);
//}
// AIs can't read news, but humans can be on the same company as AIs,
// so always send news even if the company has registered with the
// SCP protocol.
GSNews.Create(GSNews.NT_GENERAL, GSText(GSText.STR_NEW_GOAL_NEWS,
GSController.GetSetting("transport_target"),
1 << this._goal_ptr._cargo_list[0],
1 << this._goal_ptr._cargo_list[1],
1 << this._goal_ptr._cargo_list[2]
), this._company_id);
}
function CompanyData::TrackProgress()
{
local town_list = GSTownList();
local industry_list = GSIndustryList();
for(local i = 0; i < 3; i++)
{
local cargo = this._goal_ptr._cargo_list[i];
local transported = 0;
// Scan all towns and industries for delivery of cargo since last check
// Todo: do some optimization and only monitor towns/industries that can accept the given cargo
foreach(town_id, _ in town_list)
{
transported += GSCargoMonitor.GetTownDeliveryAmount(this._company_id, cargo, town_id, true);
}
foreach(industry_id, _ in industry_list)
{
transported += GSCargoMonitor.GetIndustryDeliveryAmount(this._company_id, cargo, industry_id, true);
}
this._transported_list[i] += transported;
}
// Update goals
this.UpdateGoals();
this.UpdateHQSign();
}
function CompanyData::UpdateHQSign()
{
// Todo, once basic functionality is done
/* // Put the sign on the south tile of the HQ
local hq_tile = Direction.GetAdjacentTileInDirection(
GSCompany.GetCompanyHQ(this._company_id),
Direction.DIR_S);
local hq_exist = GSMap.IsValidTile(hq_tile);
if(company_data._hq_sign != null && !hq_exist)
{
// Sign exist, but no HQ => remove sign
GSSign.RemoveSign(company_data._hq_sign);
company_data._hq_sign = null;
}
else if(hq_exist)
{
// The HQ exist
local sign_text = GSText(GSText.STR_SCORE, (company_data._goal_value - GOAL_STEP_SIZE));
if(company_data._hq_sign == null)
{
// HQ exist, but no sign yet => create new sign
company_data._hq_sign = GSSign.BuildSign(hq_tile, sign_text);
}
else
{
// HQ exist as well as a sign
if(GSSign.GetLocation(company_data._hq_sign) == hq_tile)
{
// The sign is at the right location => update only the text contents
GSSign.SetName(company_data._hq_sign, sign_text);
}
else
{
// The sign exist, but at the wrong tile
GSSign.RemoveSign(company_data._hq_sign);
company_data._hq_sign = GSSign.BuildSign(hq_tile, sign_text);
}
}
}
else
{
// No HQ and no old sign
}
*/
}
function CompanyData::GameEnd()
{
GSGoal.Question(0, this._company_id, GSText(GSText.STR_GAME_END_GOLD + this.GetMedal(),
this._transported_list[0],
1 << this._goal_ptr._cargo_list[0],
this._transported_list[1],
1 << this._goal_ptr._cargo_list[1],
this._transported_list[2],
1 << this._goal_ptr._cargo_list[2]
), GSGoal.QT_INFORMATION, GSGoal.BUTTON_CLOSE);
}
function CompanyData::EndOfYear()
{
GSNews.Create(GSNews.NT_GENERAL, GSText(GSText.STR_GOAL_PROGRESS_NEWS,
1 << this._goal_ptr._cargo_list[0],
this._transported_list[0],
1 << this._goal_ptr._cargo_list[1],
this._transported_list[1],
1 << this._goal_ptr._cargo_list[2],
this._transported_list[2],
GSController.GetSetting("transport_target")
), this._company_id);
}
function CompanyData::SaveToTable()
{
return {
company_id = this._company_id,
goal_list = this._goal_list,
transported_list = this._transported_list,
hq_sign = this._hq_sign,
};
}
/* static */ function CompanyData::CreateFromTable(table, goal_ptr)
{
local result = CompanyData(table.company_id, goal_ptr);
result._goal_list = table.goal_list;
result._transported_list = table.transported_list;
result._hq_sign = table.hq_sign;
return result;
}
NoCarGoal-v1/goal.nut 0000700 0001750 0001001 00000004032 12014504127 013172 0 ustar Leif None
//------------------------------------------------------------//
// //
// Class for storage of global goal data //
// //
//------------------------------------------------------------//
class GoalData
{
_cargo_list = null; // index = 0, 1, 2 for the three cargoes (with lowest cargo ID first)
_min_transported = 0;
_start_year = 0;
constructor()
{
this._cargo_list = [-1, -1, -1];
this._min_transported = 0;
this._start_year = 0;
}
// pick cargoes
function InitalizeGoals();
function GetEndYear();
// For save/load
function SaveToTable();
static function CreateFromTable(table);
}
function GoalData::InitalizeGoals()
{
// Pick 3 random cargoes
local cargo_list = GSCargoList();
cargo_list.Valuate(GSBase.RandItem);
cargo_list.KeepTop(3);
// Sort them by cargo ID
cargo_list.Sort(GSList.SORT_BY_ITEM, GSList.SORT_ASCENDING);
// Store the cargo IDs in this._cargo_list
local i = 0;
local cargo_list_str = "";
foreach(cargo, _ in cargo_list)
{
this._cargo_list[i] = cargo;
if(cargo_list_str != "") cargo_list_str += ", ";
cargo_list_str += GSCargo.GetCargoLabel(cargo);
i++;
}
// save the start year of the game
this._start_year = GSDate.GetYear(GSDate.GetCurrentDate());
// log some info about the goals
Log.Info("Goal cargoes: " + cargo_list_str, Log.LVL_INFO);
Log.Info("Target value: " + GSController.GetSetting("transport_target"), Log.LVL_INFO);
Log.Info("By year: " + this.GetEndYear());
}
function GoalData::GetEndYear()
{
return this._start_year + GSController.GetSetting("play_years");
}
function GoalData::SaveToTable()
{
return {
cargo_list = this._cargo_list,
start_year = this._start_year
};
}
/*static*/ function GoalData::CreateFromTable(table)
{
local result = GoalData();
result._cargo_list = table.cargo_list;
result._start_year = table.start_year;
return result;
}
NoCarGoal-v1/info.nut 0000700 0001750 0001001 00000004331 12014513624 013207 0 ustar Leif None /*
* This file is part of NoCarGoal, which is a GameScript for OpenTTD
* Copyright (C) 2012 Leif Linse
*
* NoCarGoal is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License
*
* NoCarGoal is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NoCarGoal; If not, see or
* write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
require("version.nut");
class FMainClass extends GSInfo {
function GetAuthor() { return "Zuu"; }
function GetName() { return "NoCarGoal"; }
function GetDescription() { return "Goal: Transport at least X units of cargo A, B and C by the end of year YYYY. 1 cargo = Bronze, 2 cargoes = Silver, 3 cargoes = Gold"; }
function GetVersion() { return SELF_VERSION; }
function GetDate() { return "2012-03-04"; }
function CreateInstance() { return "MainClass"; }
function GetShortName() { return "CAGO"; }
function GetAPIVersion() { return "1.3"; }
function GetUrl() { return ""; }
function GetSettings() {
AddSetting({name = "transport_target",
description = "Target transport amount (per cargo)",
easy_value = 100000,
medium_value = 100000,
hard_value = 100000,
custom_value = 100000,
flags = CONFIG_INGAME, min_value = 1, max_value = 1000000000});
AddSetting({name = "play_years",
description = "How many game years should the challenge cover?",
easy_value = 100,
medium_value = 100,
hard_value = 100,
custom_value = 100,
flags = 0, min_value = 1, max_value = 10000});
AddSetting({name = "log_level", description = "Debug: Log level (higher = print more)", easy_value = 3, medium_value = 3, hard_value = 3, custom_value = 3, flags = CONFIG_INGAME, min_value = 1, max_value = 3});
}
}
RegisterGS(FMainClass());
NoCarGoal-v1/lang/ 0000700 0001750 0001001 00000000000 12014513536 012443 5 ustar Leif None NoCarGoal-v1/lang/english.txt 0000700 0001750 0001001 00000003101 12014512002 014616 0 ustar Leif None STR_GOAL_GOLD :To reach GOLD, transport at least {NUM} cargo units of each cargo; {CARGO_LIST}, {CARGO_LIST} and {CARGO_LIST} before the end of year {NUM}
STR_GOAL_SILVER :To reach SILVER, transport at least {NUM} cargo units of two of the following cargoes; {CARGO_LIST}, {CARGO_LIST} and {CARGO_LIST} before the end of year {NUM}
STR_GOAL_BRONZE :To reach BRONZE, transport at least {NUM} cargo units of one of the following cargoes; {CARGO_LIST}, {CARGO_LIST} and {CARGO_LIST} before the end of year {NUM}
STR_NEW_GOAL_NEWS :Goal: Transport at least {NUM} units of cargo of {CARGO_LIST}, {CARGO_LIST} and {CARGO_LIST}. 1 cargo = Bronze, 2 cargoes = Silver and 3 cargoes = Gold
STR_GOAL_PROGRESS_NEWS :Goal progress:{}{CARGO_LIST}: {NUM} units transported{}{CARGO_LIST}: {NUM} units transported{}{CARGO_LIST}: {NUM} units transported{}out of target: {NUM}
STR_GAME_END_GOLD :You have won GOLD medal!{}{}In total, you have transported:{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}
STR_GAME_END_SILVER :You have won SILVER medal!{}{}In total, you have transported:{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}
STR_GAME_END_BRONZE :You have won BRONZE medal!{}{}In total, you have transported:{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}{}{NUM} units of {CARGO_LIST}
STR_GAME_END_NO_MEDAL :Game Over{}{}You did not reach any of the cargo goals{}{}In total, you have transported {NUM} units of {CARGO_LIST}, {NUM} units of {CARGO_LIST} and {NUM} units of {CARGO_LIST}.
NoCarGoal-v1/main.nut 0000700 0001750 0001001 00000015531 12014512150 013175 0 ustar Leif None /*
* This file is part of MinimalGS, which is a GameScript for OpenTTD
* Copyright (C) 2012 Leif Linse
*
* MinimalGS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License
*
* MinimalGS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MinimalGS; If not, see or
* write to the Free Software Foundation, Inc., 51 Franklin Street,
* Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
/* Import SuperLib for GameScript */
import("util.superlib", "SuperLib", 25);
Result <- SuperLib.Result;
Log <- SuperLib.Log;
Helper <- SuperLib.Helper;
ScoreList <- SuperLib.ScoreList;
Tile <- SuperLib.Tile;
Direction <- SuperLib.Direction;
Town <- SuperLib.Town;
Industry <- SuperLib.Industry;
require("version.nut"); // get SELF_VERSION
require("goal.nut");
require("companydata.nut");
// Goals
GOLD <- 0;
SILVER <- 1;
BRONZE <- 2;
NO_MEDAL <- 3;
class MainClass extends GSController
{
_loaded_data = null;
_loaded_from_version = null;
_company_list = null;
_goal_data = null;
constructor()
{
this._loaded_data = null;
this._loaded_from_version = null;
this._company_list = [];
this._goal_data = null; // created by Init
}
}
function MainClass::Start()
{
this.Init();
Log.Info("Setup done", Log.LVL_INFO);
// Wait for the game to start
this.Sleep(1);
local last_goal_check = GSDate.GetCurrentDate();
local last_loop_year = GSDate.GetYear(GSDate.GetCurrentDate());
while (true) {
local loop_start_tick = GSController.GetTick();
// Handle events
this.HandleEvents();
// Reached end of year?
local current_date = GSDate.GetCurrentDate();
local year = GSDate.GetYear(current_date);
if(year != last_loop_year)
{
// reached end of challenge?
if(year == this._goal_data.GetEndYear())
{
this.GameEnd();
}
else if(year < this._goal_data.GetEndYear())
{
this.EndOfYear();
}
last_loop_year = year;
}
// Once a month
if(current_date > last_goal_check + 30)
{
last_goal_check = current_date;
// Check goals setup once a month to fix problems when events has been lost
this.UpdateCompanyList();
// Has any goals been fulfilled?
GSLog.Info("Scan goals START");
this.ScanGoals();
GSLog.Info("Scan goals END");
}
// Check for incoming SCP messages
//Log.Info("SCP.Check", Log.LVL_INFO);
//while(g_scp.Check()) {};
// Loop with a frequency of five days
local ticks_used = GSController.GetTick() - loop_start_tick;
this.Sleep(Helper.Max(1, 5 * 74 - ticks_used));
}
}
function MainClass::Init()
{
if (this._loaded_data != null)
{
// Copy loaded data from this._loaded_data to this.*
// or do whatever with the loaded data
// load goal data
this._goal_data = GoalData.CreateFromTable(this._loaded_data.goal_data);
// Load company data from loaded data
foreach(_, company_table in this._loaded_data.company_list)
{
if(company_table != null)
{
Log.Info("Loading data for company " + GSCompany.GetName(company_table.company_id), Log.LVL_INFO);
this._company_list.append(
CompanyData.CreateFromTable(company_table, this._goal_data)
);
}
}
this._loaded_data = null; // don't attempt to load again
}
else
{
// New game
this._goal_data = GoalData();
this._goal_data.InitalizeGoals(); // select goal cargoes
}
// Add possible new companies
this.UpdateCompanyList();
// Start up cargo monitoring by reading from
// all cargo monitors.
this.ScanGoals();
}
function MainClass::HandleEvents()
{
if(GSEventController.IsEventWaiting())
{
local ev = GSEventController.GetNextEvent();
if(ev == null)
return;
local ev_type = ev.GetEventType();
if(ev_type == GSEvent.ET_COMPANY_NEW ||
ev_type == GSEvent.ET_COMPANY_BANKRUPT ||
ev_type == GSEvent.ET_COMPANY_MERGER)
{
Log.Info("A company was created/bankrupt/merged => update company list", Log.LVL_INFO);
// Update the goal list when:
// - a new company has been created
// - a company has gone bankrupt
// - a company has been bought by another company
this.UpdateCompanyList();
}
}
}
function MainClass::UpdateCompanyList()
{
// Loop over all possible company IDs
for(local c = GSCompany.COMPANY_FIRST; c <= GSCompany.COMPANY_LAST; c++)
{
// has goals already been set up for this company?
local existing = null;
local existing_idx = 0;
foreach(company_data in this._company_list)
{
if(company_data._company_id == c)
{
existing = company_data;
break;
}
existing_idx++;
}
// does the company exist in the game
if(GSCompany.ResolveCompanyID(c) == GSCompany.COMPANY_INVALID)
{
if(existing != null)
{
// Remove data for no longer existing company
this._company_list.remove(existing_idx);
}
continue;
}
// If the company can be resolved and exist (goals has been setup) => don't do anything
if(existing != null) continue;
// Company goals has not yet been setup for this company
local company_data = CompanyData(c, this._goal_data);
company_data.CreateGoals();
company_data.InformAboutGoal();
company_data.TrackProgress();
this._company_list.append(company_data);
}
}
function MainClass::ScanGoals()
{
foreach(company_data in this._company_list)
{
company_data.TrackProgress();
}
}
// Called when the end of game has been reached
function MainClass::GameEnd()
{
// Pause the game
GSGame.Pause();
// Show End of Game message for each company
foreach(company_data in this._company_list)
{
company_data.GameEnd();
}
}
// Called at end of year (but not when the game end has been reached)
function MainClass::EndOfYear()
{
foreach(company_data in this._company_list)
{
company_data.EndOfYear();
}
}
function MainClass::Save()
{
Log.Info("Saving data to savegame", Log.LVL_INFO);
local company_save_list = [];
foreach(company_data in this._company_list)
{
company_save_list.append(company_data.SaveToTable());
}
return {
goal_data = this._goal_data.SaveToTable(),
company_list = company_save_list
};
}
function MainClass::Load(version, tbl)
{
Log.Info("Loading data from savegame made with version " + version + " of the game script", Log.LVL_INFO);
if(version > SELF_VERSION)
{
Log.Warning("Warning: Loading from a newer version of TransportGoals", Log.LVL_INFO);
}
// Store a copy of the table from the save game
// but do not process the loaded data yet. Wait with that to Init
// so that OpenTTD doesn't kick us for taking too long to load.
this._loaded_data = {}
foreach(key, val in tbl)
{
this._loaded_data.rawset(key, val);
}
this._loaded_from_version = version;
}
NoCarGoal-v1/version.nut 0000700 0001750 0001001 00000000332 11701136763 013745 0 ustar Leif None /*
* Warning: This file is loaded both by main.nut and info.nut
* thus, don't place anything here that is heavy or not required
* to be available when OpenTTD scans the info.nut file.
*/
SELF_VERSION <- 1;