// Global function for checking if SCP is enabled at all function IsSCPEnabled() { return 1; } // SCP Manager class class SCPManager { _main_ptr = null; _scp_enabled = null; static COMMAND_SET = "Company Value GS"; constructor(main_ptr) { this._scp_enabled = IsSCPEnabled(); this._main_ptr = main_ptr; this.SetupSCP(); } } function DataToStr(data) { if (data == null) return "NULL"; local s = "["; foreach(d in data) { if (s != "[") s += ", "; if (d == null) s += "NULL"; else if(typeof(d) == "string") s += "\"" + d + "\""; else s += d.tostring(); } return s + "]"; } function SCPManager::SetupSCP() { if (!this._scp_enabled) return; // Initialize the library itself local dummy = SCPLib("CVGS", 4, null); // yes, call constructor and then throw away instance. local show_debug = true; SCPLib.SCPLogging_Info(show_debug); // <-- static call to library SCPLib.SCPLogging_Error(true); // Register commands local self = this; // AI -> GS commands: // SCPLib.AddCommand("CurrentGoal", COMMAND_SET, self, SCPManager.ReceivedCurrentGoalCommand); SCPLib.AddCommand("Setting", COMMAND_SET, self, SCPManager.ReceivedSettingCommand); // GS -> AI commands: SCPLib.AddCommand("GoalReached", COMMAND_SET, self); } function SCPManager::Check() { if (!this._scp_enabled) return; // Update SCP logging in case the log level was changed local show_debug = true; SCPLib.SCPLogging_Info(show_debug); // Let SCP check for incoming messages return SCPLib.Check(); } /***************************************************************** * * * Outgoing Commands - commands that we can send to AIs * * * *****************************************************************/ // Call one of these methods to send a command to an AI. /* * Tells a company that it has reached the transport goal for the specified cargo * @param to_company Company ID of the company to inform * @param cargo_id Cargo ID of the cargo that was completed * @param date Date when the goal was detected to be completed. (date is in the from and data type as returned form GSDate.GetDate()) */ function SCPManager::SendGoalReached(to_company, c_id, goal_value, days_taken) { if (!this._scp_enabled) return false; if (!SCPLib.CanSpeakWith(to_company)) return false; //GSController.Break("Tell about goal completed: " + GSCargo.GetCargoLabel(cargo_id)); SCPLib.TellCompany("GoalReached", COMMAND_SET, to_company, [c_id, goal_value, days_taken]); } /* * @param to_company Which company to send the message to * @param for_company Which company to lookup the goals for * @param answer_to_message if this command is sent in return to a query, pass the query message instance with this parameter * * See ReceivedCurrentGoalCommand for a detailed explanation of the transmitted data (or just read the code). */ function SCPManager::SendCurrentGoal(to_company, for_company, answer_to_message = null) { if (!this._scp_enabled) return false; if (answer_to_message == null && !SCPLib.CanSpeakWith(to_company)) return false; // Find the data for company foreach(company_data in this._main_ptr._company_list) { if(company_data._company_id == for_company) { local date = GSDate.GetCurrentDate(); local days_left = this._main_ptr._goal_data.GetDaysLeft(); // company id date days left goal 0 goal 1 goal 2 local result = [for_company, date, days_left, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for(local i = 0; i < 3; i++) { local cargo = this._main_ptr._goal_data._cargo_list[i]; local target = GSController.GetSetting("transport_target") local transported = company_data._transported_list[i]; result[3 + i * 3 ] = cargo; result[3 + i * 3 + 1] = target; result[3 + i * 3 + 2] = transported; } local s = ""; for(local i = 0; i < result.len(); i++) { if (i == 3) s+= " | "; else if (i == 3 + 3) s+= " | "; else if (i == 3 + 6) s+= " | "; else if (s != "") s+=", "; s += "" + result[i]; } Log.Info(answer_to_message != null? "send response to message" : "tell company", Log.LVL_DEBUG); Log.Info("sent CurrentGoal: " + s, Log.LVL_SUB_DECISIONS); if(answer_to_message != null) SCPLib.Answer(answer_to_message, result); else SCPLib.TellCompany("CurrentGoal", COMMAND_SET, to_company, result); return true; } } return false; } /***************************************************************** * * * Incoming Commands - commands that we can get from AIs * * * *****************************************************************/ // These methods are called by the SCP library when we call SCPLib.Check() and there is // a received incoming message. /* * Input: * Data[0] => CompanyID to get goal of * * Output: * Data[0] => Company ID of the company that these values are valid for * Data[1] => Date when the goals was sent * Data[2] => Days left of the game. (lower bound, a few extra days may happen due to frequency of checks) * * Data[3] => Cargo of goal 1 * Data[4] => Amount of transported cargo for goal 1 * Data[5] => Target transport amount for goal 1 * Data[6] => Cargo of goal 2 * ... * Data[11] => Target transport amount for goal 3 * * Note that also accomplished goals are included in the output. * If [transported amount] > [target amount], then the goal has already been accomplished. */ function SCPManager::ReceivedCurrentGoalCommand(message, self) { if (!self._scp_enabled) return; if(Log.IsLevelAccepted(Log.LVL_SUB_DECISIONS)) { Log.Info("Received CurrentGoal Command with data: " + DataToStr(message.Data), Log.LVL_INFO); } // If first param is available, use it as company ID, else // use SenderID. local query_company = message.GetIntData(0); if(query_company == null) query_company = message.SenderID; Log.Info(GSCompany.GetName(message.SenderID) + " asks for the current goal of " + GSCompany.GetName(query_company), Log.LVL_DEBUG); if(!self.SendCurrentGoal(message.SenderID, query_company, message)) { Log.Info("Unknown sender asks for its current goal", Log.LVL_INFO); // Can't find company - respond to the sender with null to tell // that we got the command, but couldn't find any result for the // company. SCPLib.Answer(message, null); } } /* * Input: * Data[0] => string to pass to GSController.GetSetting(setting) * Data[1] => new value of setting (only accepted by some settings) * * Output: * Data[0] => setting name string * Data[1] => setting value * * If the setting doesn't exist, Data[0] will contain the setting name and * Data[1] will contain null. */ function SCPManager::ReceivedSettingCommand(message, self) { if (!self._scp_enabled) return; if(true) { GSLog.Info("Received Setting Command with data: " + DataToStr(message.Data)); } // Get setting string local setting = message.GetStringData(0); local response_value = null; if(setting != null) { // fake setting? if (setting == "version") { response_value = 4; } else if(setting == "goal_mode") { response_value = CompanyValue.goal_mode; } else if(setting == "goal_value") { response_value = CompanyValue.best_value; } // else if(setting == "ai_monthly_report") // { // local from = message.SenderID; // local from_company = self._main_ptr.GetCompanyData(from); // if (from_company != null) // { // local new_value = message.GetBoolData(1); // if (new_value != null) // { // from_company.SetAIMonthlyReport(new_value); // } // // response_value = from_company.GetAIMonthlyReport(); // Log.Info("Received request to update monthly AI report for " + GSCompany.GetName(from_company._company_id) + " to " + new_value + " | setting value after update: " + response_value, Log.LVL_SUB_DECISIONS); // } // } // else if(setting == "play_years") // only white listed GSSetting settings are allowed // { // response_value = GSController.GetSetting(setting); // } else { Log.Info("AI company " + GSCompany.GetName(message.SenderID) + " asked for unknown setting \"" + setting + "\"", Log.LVL_INFO); } // if (response_value != null) GSLog.Info(GSCompany.GetName(message.SenderID) + " asked for setting value of \"" + setting + "\" which has the value: " + response_value); } // Answer with the setting value SCPLib.Answer(message, setting, response_value); }