Changeset - r12845:8860291369ea
[Not reviewed]
master
0 10 0
rubidium - 15 years ago 2009-09-01 12:57:04
rubidium@openttd.org
(svn r17345) -Fix [FS#2769]: one wasn't offered to take over bankrupt companies anymore; caused by the introduction NoAI, although NewAI had the same problem too.
10 files changed with 153 insertions and 16 deletions:
0 comments (0 inline, 0 general)
src/ai/ai_instance.cpp
Show inline comments
 
@@ -186,6 +186,7 @@ void AIInstance::RegisterAPI()
 
	SQAIEngineList_Register(this->engine);
 
	SQAIError_Register(this->engine);
 
	SQAIEvent_Register(this->engine);
 
	SQAIEventCompanyAskMerger_Register(this->engine);
 
	SQAIEventCompanyBankrupt_Register(this->engine);
 
	SQAIEventCompanyInTrouble_Register(this->engine);
 
	SQAIEventCompanyMerger_Register(this->engine);
src/ai/api/ai_changelog.hpp
Show inline comments
 
@@ -19,6 +19,7 @@
 
 * API additions:
 
 * \li AIBaseStation
 
 * \li AIBuoyList
 
 * \li AIEventCompanyAskMerger
 
 * \li AIRail::RemoveRailWaypointTileRect
 
 * \li AISubsidy::SubsidyParticipantType
 
 * \li AISubsidy::GetSourceType
src/ai/api/ai_event.hpp
Show inline comments
 
@@ -36,6 +36,7 @@ public:
 
		AI_ET_ENGINE_PREVIEW,
 
		AI_ET_COMPANY_NEW,
 
		AI_ET_COMPANY_IN_TROUBLE,
 
		AI_ET_COMPANY_ASK_MERGER,
 
		AI_ET_COMPANY_MERGER,
 
		AI_ET_COMPANY_BANKRUPT,
 
		AI_ET_VEHICLE_CRASHED,
src/ai/api/ai_event.hpp.sq
Show inline comments
 
@@ -38,6 +38,7 @@ void SQAIEvent_Register(Squirrel *engine
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_ENGINE_PREVIEW,              "AI_ET_ENGINE_PREVIEW");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_NEW,                 "AI_ET_COMPANY_NEW");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_IN_TROUBLE,          "AI_ET_COMPANY_IN_TROUBLE");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_ASK_MERGER,          "AI_ET_COMPANY_ASK_MERGER");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_MERGER,              "AI_ET_COMPANY_MERGER");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_COMPANY_BANKRUPT,            "AI_ET_COMPANY_BANKRUPT");
 
	SQAIEvent.DefSQConst(engine, AIEvent::AI_ET_VEHICLE_CRASHED,             "AI_ET_VEHICLE_CRASHED");
src/ai/api/ai_event_types.cpp
Show inline comments
 
@@ -92,3 +92,8 @@ bool AIEventEnginePreview::AcceptPreview
 
{
 
	return AIObject::DoCommand(0, this->engine, 0, CMD_WANT_ENGINE_PREVIEW);
 
}
 

	
 
bool AIEventCompanyAskMerger::AcceptMerger()
 
{
 
	return AIObject::DoCommand(0, this->owner, 0, CMD_BUY_COMPANY);
 
}
src/ai/api/ai_event_types.hpp
Show inline comments
 
@@ -359,6 +359,54 @@ private:
 
};
 

	
 
/**
 
 * Event Company Ask Merger, indicating a company can be bought (cheaply) by you.
 
 */
 
class AIEventCompanyAskMerger : public AIEvent {
 
public:
 
	static const char *GetClassName() { return "AIEventCompanyAskMerger"; }
 

	
 
	/**
 
	 * @param owner The company that can be bough.
 
	 * @param value The value/costs of buying the company.
 
	 */
 
	AIEventCompanyAskMerger(Owner owner, int32 value) :
 
		AIEvent(AI_ET_COMPANY_MERGER),
 
		owner((AICompany::CompanyID)owner),
 
		value(value)
 
	{}
 

	
 
	/**
 
	 * Convert an AIEvent to the real instance.
 
	 * @param instance The instance to convert.
 
	 * @return The converted instance.
 
	 */
 
	static AIEventCompanyAskMerger *Convert(AIEvent *instance) { return (AIEventCompanyAskMerger *)instance; }
 

	
 
	/**
 
	 * Get the CompanyID of the company that can be bought.
 
	 * @return The CompanyID of the company that can be bought.
 
	 * @note If the company is bought this will become invalid.
 
	 */
 
	AICompany::CompanyID GetCompanyID() { return this->owner; }
 

	
 
	/**
 
	 * Get the value of the new company.
 
	 * @return The value of the new company.
 
	 */
 
	int32 GetValue() { return this->value; }
 

	
 
	/**
 
	 * Take over the company for this merger.
 
	 * @return true if the merger was a success.
 
	 */
 
	bool AcceptMerger();
 

	
 
private:
 
	AICompany::CompanyID owner;
 
	int32 value;
 
};
 

	
 
/**
 
 * Event Company Merger, indicating a company has been bought by another
 
 *  company.
 
 */
src/ai/api/ai_event_types.hpp.sq
Show inline comments
 
@@ -192,6 +192,28 @@ void SQAIEventCompanyInTrouble_Register(
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyAskMerger to be used as Squirrel parameter */
 
	template <> AIEventCompanyAskMerger *GetParam(ForceType<AIEventCompanyAskMerger *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyAskMerger *)instance; }
 
	template <> AIEventCompanyAskMerger &GetParam(ForceType<AIEventCompanyAskMerger &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyAskMerger *)instance; }
 
	template <> const AIEventCompanyAskMerger *GetParam(ForceType<const AIEventCompanyAskMerger *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyAskMerger *)instance; }
 
	template <> const AIEventCompanyAskMerger &GetParam(ForceType<const AIEventCompanyAskMerger &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyAskMerger *)instance; }
 
	template <> int Return<AIEventCompanyAskMerger *>(HSQUIRRELVM vm, AIEventCompanyAskMerger *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "AIEventCompanyAskMerger", res, NULL, DefSQDestructorCallback<AIEventCompanyAskMerger>); return 1; }
 
}; // namespace SQConvert
 

	
 
void SQAIEventCompanyAskMerger_Register(Squirrel *engine) {
 
	DefSQClass <AIEventCompanyAskMerger> SQAIEventCompanyAskMerger("AIEventCompanyAskMerger");
 
	SQAIEventCompanyAskMerger.PreRegister(engine, "AIEvent");
 

	
 
	SQAIEventCompanyAskMerger.DefSQStaticMethod(engine, &AIEventCompanyAskMerger::Convert, "Convert", 2, ".x");
 

	
 
	SQAIEventCompanyAskMerger.DefSQMethod(engine, &AIEventCompanyAskMerger::GetCompanyID, "GetCompanyID", 1, "x");
 
	SQAIEventCompanyAskMerger.DefSQMethod(engine, &AIEventCompanyAskMerger::GetValue,     "GetValue",     1, "x");
 
	SQAIEventCompanyAskMerger.DefSQMethod(engine, &AIEventCompanyAskMerger::AcceptMerger, "AcceptMerger", 1, "x");
 

	
 
	SQAIEventCompanyAskMerger.PostRegister(engine);
 
}
 

	
 
namespace SQConvert {
 
	/* Allow AIEventCompanyMerger to be used as Squirrel parameter */
 
	template <> AIEventCompanyMerger *GetParam(ForceType<AIEventCompanyMerger *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return  (AIEventCompanyMerger *)instance; }
 
	template <> AIEventCompanyMerger &GetParam(ForceType<AIEventCompanyMerger &>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(AIEventCompanyMerger *)instance; }
src/company_cmd.cpp
Show inline comments
 
@@ -492,13 +492,78 @@ void InitializeCompanies()
 
	_cur_company_tick_index = 0;
 
}
 

	
 
/**
 
 * Handle the bankruptcy take over of a company.
 
 * Companies going bankrupt will ask the other companies in order of their
 
 * performance rating, so better performing companies get the 'do you want to
 
 * merge with Y' question earlier. The question will then stay till either the
 
 * company has gone bankrupt or got merged with a company.
 
 *
 
 * @param c the company that is going bankrupt.
 
 */
 
static void HandleBankruptcyTakeover(Company *c)
 
{
 
	/* Amount of time out for each company to take over a company;
 
	 * Timeout is a quarter (3 months of 30 days) divided over the
 
	 * number of companies. The minimum number of days in a quarter
 
	 * is 90: 31 in January, 28 in February and 31 in March.
 
	 * Note that the company going bankrupt can't buy itself. */
 
	static const int TAKE_OVER_TIMEOUT = 3 * 30 * DAY_TICKS / (MAX_COMPANIES - 1);
 

	
 
	assert(c->bankrupt_asked != 0);
 

	
 
	/* We're currently asking some company to buy 'us' */
 
	if (c->bankrupt_timeout != 0) {
 
		c->bankrupt_timeout -= MAX_COMPANIES;
 
		if (c->bankrupt_timeout > 0) return;
 
		c->bankrupt_timeout = 0;
 

	
 
		return;
 
	}
 

	
 
	/* Did we ask everyone for bankruptcy? If so, bail out. */
 
	if (c->bankrupt_asked == MAX_UVALUE(CompanyMask)) return;
 

	
 
	Company *c2, *best = NULL;
 
	int32 best_performance = -1;
 

	
 
	/* Ask the company with the highest performance history first */
 
	FOR_ALL_COMPANIES(c2) {
 
		if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves
 
				!HasBit(c->bankrupt_asked, c2->index) &&
 
				best_performance < c2->old_economy[1].performance_history) {
 
			best_performance = c2->old_economy[1].performance_history;
 
			best = c2;
 
		}
 
	}
 

	
 
	/* Asked all companies? */
 
	if (best_performance == -1) {
 
		c->bankrupt_asked = MAX_UVALUE(CompanyMask);
 
		return;
 
	}
 

	
 
	SetBit(c->bankrupt_asked, best->index);
 

	
 
	if (IsInteractiveCompany(best->index)) {
 
		c->bankrupt_timeout = TAKE_OVER_TIMEOUT;
 
		ShowBuyCompanyDialog(c->index);
 
		return;
 
	}
 

	
 
	if (best->is_ai) {
 
		AI::NewEvent(best->index, new AIEventCompanyAskMerger(c->index, ClampToI32(c->bankrupt_value)));
 
	}
 
}
 

	
 
void OnTick_Companies()
 
{
 
	if (_game_mode == GM_EDITOR) return;
 

	
 
	Company *c = Company::GetIfValid(_cur_company_tick_index);
 
	if (c != NULL && c->name_1 != 0) {
 
		GenerateCompanyName(c);
 
	if (c != NULL) {
 
		if (c->name_1 != 0) GenerateCompanyName(c);
 
		if (c->bankrupt_asked != 0) HandleBankruptcyTakeover(c);
 
	}
 

	
 
	if (_next_competitor_start == 0) {
src/company_func.h
Show inline comments
 
@@ -21,6 +21,7 @@
 
void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner);
 
void GetNameOfOwner(Owner owner, TileIndex tile);
 
void SetLocalCompany(CompanyID new_company);
 
void ShowBuyCompanyDialog(CompanyID company);
 

	
 
extern CompanyByte _local_company;
 
extern CompanyByte _current_company;
src/economy.cpp
Show inline comments
 
@@ -506,16 +506,6 @@ static void CompanyCheckBankrupt(Company
 
			AI::BroadcastNewEvent(new AIEventCompanyInTrouble(c->index));
 
			break;
 
		case 3: {
 
			/* XXX - In multiplayer, should we ask other companies if it wants to take
 
		          over when it is a human company? -- TrueLight */
 
			if (!c->is_ai) {
 
				SetDParam(0, STR_NEWS_COMPANY_IN_TROUBLE_TITLE);
 
				SetDParam(1, STR_NEWS_COMPANY_IN_TROUBLE_DESCRIPTION);
 
				SetDParamStr(2, cni->company_name);
 
				AddCompanyNewsItem(STR_MESSAGE_NEWS_FORMAT, NS_COMPANY_TROUBLE, cni);
 
				break;
 
			}
 

	
 
			/* Check if the company has any value.. if not, declare it bankrupt
 
			 *  right now */
 
			Money val = CalculateCompanyValue(c);
 
@@ -1560,15 +1550,17 @@ CommandCost CmdSellShareInCompany(TileIn
 
CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 
{
 
	Company *c = Company::GetIfValid(p1);
 
	if (c == NULL) return CMD_ERROR;
 

	
 
	/* Disable takeovers in multiplayer games */
 
	if (c == NULL || _networking) return CMD_ERROR;
 
	/* Disable takeovers when not asked */
 
	if (!HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR;
 

	
 
	/* Disable taking over the local company in single player */
 
	if (!_networking && _local_company == c->index) return CMD_ERROR;
 

	
 
	/* Do not allow companies to take over themselves */
 
	if ((CompanyID)p1 == _current_company) return CMD_ERROR;
 

	
 
	if (!c->is_ai) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		DoAcquireCompany(c);
 
	}
0 comments (0 inline, 0 general)