252 /* use PLAYER_SPECTATOR as new_player to delete the player. */ |
253 /* use PLAYER_SPECTATOR as new_player to delete the player. */ |
253 void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player) |
254 void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player) |
254 { |
255 { |
255 Town *t; |
256 Town *t; |
256 PlayerID old = _current_player; |
257 PlayerID old = _current_player; |
|
258 |
|
259 assert(old_player != new_player); |
|
260 |
|
261 { |
|
262 Player *p; |
|
263 uint i; |
|
264 |
|
265 /* See if the old_player had shares in other companies */ |
|
266 _current_player = old_player; |
|
267 FOR_ALL_PLAYERS(p) { |
|
268 for (i = 0; i < 4; i++) { |
|
269 if (p->share_owners[i] == old_player) { |
|
270 /* Sell his shares */ |
|
271 int32 res = DoCommand(0, p->index, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY); |
|
272 /* Because we are in a DoCommand, we can't just execute an other one and |
|
273 * expect the money to be removed. We need to do it ourself! */ |
|
274 SubtractMoneyFromPlayer(res); |
|
275 } |
|
276 } |
|
277 } |
|
278 |
|
279 /* Sell all the shares that people have on this company */ |
|
280 p = GetPlayer(old_player); |
|
281 for (i = 0; i < 4; i++) { |
|
282 _current_player = p->share_owners[i]; |
|
283 if (_current_player != PLAYER_SPECTATOR) { |
|
284 /* Sell the shares */ |
|
285 int32 res = DoCommand(0, old_player, 0, DC_EXEC, CMD_SELL_SHARE_IN_COMPANY); |
|
286 /* Because we are in a DoCommand, we can't just execute an other one and |
|
287 * expect the money to be removed. We need to do it ourself! */ |
|
288 SubtractMoneyFromPlayer(res); |
|
289 } |
|
290 } |
|
291 } |
|
292 |
257 _current_player = old_player; |
293 _current_player = old_player; |
258 |
294 |
259 /* Temporarily increase the player's money, to be sure that |
295 /* Temporarily increase the player's money, to be sure that |
260 * removing his/her property doesn't fail because of lack of money. |
296 * removing his/her property doesn't fail because of lack of money. |
261 * Not too drastically though, because it could overflow */ |
297 * Not too drastically though, because it could overflow */ |
343 } while (++tile != MapSize()); |
379 } while (++tile != MapSize()); |
344 } |
380 } |
345 |
381 |
346 /* Change color of existing windows */ |
382 /* Change color of existing windows */ |
347 if (new_player != PLAYER_SPECTATOR) ChangeWindowOwner(old_player, new_player); |
383 if (new_player != PLAYER_SPECTATOR) ChangeWindowOwner(old_player, new_player); |
348 |
|
349 { |
|
350 Player *p; |
|
351 uint i; |
|
352 |
|
353 /* Check for shares */ |
|
354 FOR_ALL_PLAYERS(p) { |
|
355 for (i = 0; i < 4; i++) { |
|
356 /* 'Sell' the share if this player has any */ |
|
357 if (p->share_owners[i] == _current_player) { |
|
358 p->share_owners[i] = PLAYER_SPECTATOR; |
|
359 } |
|
360 } |
|
361 } |
|
362 p = GetPlayer(_current_player); |
|
363 /* Sell all the shares that people have on this company */ |
|
364 for (i = 0; i < 4; i++) |
|
365 p->share_owners[i] = PLAYER_SPECTATOR; |
|
366 } |
|
367 |
384 |
368 _current_player = old; |
385 _current_player = old; |
369 |
386 |
370 MarkWholeScreenDirty(); |
387 MarkWholeScreenDirty(); |
371 } |
388 } |
963 int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type) |
980 int32 GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type) |
964 { |
981 { |
965 const CargoSpec *cs = GetCargo(cargo_type); |
982 const CargoSpec *cs = GetCargo(cargo_type); |
966 byte f; |
983 byte f; |
967 |
984 |
|
985 /* Use callback to calculate cargo profit, if available */ |
|
986 if (HASBIT(cs->callback_mask, CBM_CARGO_PROFIT_CALC)) { |
|
987 uint32 var18 = min(dist, 0xFFFF) | (min(num_pieces, 0xFF) << 16) | (transit_days << 24); |
|
988 uint16 callback = GetCargoCallback(CBID_CARGO_PROFIT_CALC, 0, var18, cs); |
|
989 if (callback != CALLBACK_FAILED) { |
|
990 int result = GB(callback, 0, 14); |
|
991 |
|
992 /* Simulate a 15 bit signed value */ |
|
993 if (HASBIT(callback, 14)) result = 0x4000 - result; |
|
994 |
|
995 /* "The result should be a signed multiplier that gets multiplied |
|
996 * by the amount of cargo moved and the price factor, then gets |
|
997 * divided by 8192." */ |
|
998 return result * num_pieces * _cargo_payment_rates[cargo_type] / 8192; |
|
999 } |
|
1000 } |
|
1001 |
968 /* zero the distance if it's the bank and very short transport. */ |
1002 /* zero the distance if it's the bank and very short transport. */ |
969 if (_opt.landscape == LT_TEMPERATE && cs->label == 'VALU' && dist < 10) |
1003 if (_opt.landscape == LT_TEMPERATE && cs->label == 'VALU' && dist < 10) |
970 dist = 0; |
1004 dist = 0; |
971 |
1005 |
972 f = 255; |
1006 f = 255; |
1518 |
1552 |
1519 extern int GetAmountOwnedBy(const Player *p, PlayerID owner); |
1553 extern int GetAmountOwnedBy(const Player *p, PlayerID owner); |
1520 |
1554 |
1521 /** Acquire shares in an opposing company. |
1555 /** Acquire shares in an opposing company. |
1522 * @param tile unused |
1556 * @param tile unused |
|
1557 * @param flags type of operation |
1523 * @param p1 player to buy the shares from |
1558 * @param p1 player to buy the shares from |
1524 * @param p2 unused |
1559 * @param p2 unused |
1525 */ |
1560 */ |
1526 int32 CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1561 int32 CmdBuyShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1527 { |
1562 { |
1563 return cost; |
1598 return cost; |
1564 } |
1599 } |
1565 |
1600 |
1566 /** Sell shares in an opposing company. |
1601 /** Sell shares in an opposing company. |
1567 * @param tile unused |
1602 * @param tile unused |
|
1603 * @param flags type of operation |
1568 * @param p1 player to sell the shares from |
1604 * @param p1 player to sell the shares from |
1569 * @param p2 unused |
1605 * @param p2 unused |
1570 */ |
1606 */ |
1571 int32 CmdSellShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1607 int32 CmdSellShareInCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1572 { |
1608 { |
1598 /** Buy up another company. |
1634 /** Buy up another company. |
1599 * When a competing company is gone bankrupt you get the chance to purchase |
1635 * When a competing company is gone bankrupt you get the chance to purchase |
1600 * that company. |
1636 * that company. |
1601 * @todo currently this only works for AI players |
1637 * @todo currently this only works for AI players |
1602 * @param tile unused |
1638 * @param tile unused |
|
1639 * @param flags type of operation |
1603 * @param p1 player/company to buy up |
1640 * @param p1 player/company to buy up |
1604 * @param p2 unused |
1641 * @param p2 unused |
1605 */ |
1642 */ |
1606 int32 CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1643 int32 CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) |
1607 { |
1644 { |
1608 Player *p; |
1645 Player *p; |
|
1646 PlayerID pid = (PlayerID)p1; |
1609 |
1647 |
1610 /* Disable takeovers in multiplayer games */ |
1648 /* Disable takeovers in multiplayer games */ |
1611 if (!IsValidPlayer((PlayerID)p1) || _networking) return CMD_ERROR; |
1649 if (!IsValidPlayer(pid) || _networking) return CMD_ERROR; |
|
1650 |
|
1651 /* Do not allow players to take over themselves */ |
|
1652 if (pid == _current_player) return CMD_ERROR; |
1612 |
1653 |
1613 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1654 SET_EXPENSES_TYPE(EXPENSES_OTHER); |
1614 p = GetPlayer((PlayerID)p1); |
1655 p = GetPlayer(pid); |
1615 |
1656 |
1616 if (!p->is_ai) return CMD_ERROR; |
1657 if (!p->is_ai) return CMD_ERROR; |
1617 |
1658 |
1618 if (flags & DC_EXEC) { |
1659 if (flags & DC_EXEC) { |
1619 DoAcquireCompany(p); |
1660 DoAcquireCompany(p); |