Hooks
static bool BeforeCvPlayer_doAdvancedStartAction(CvPlayer* self, AdvancedStartActionTypes eAction, int iX, int iY, int iData, bool bAdd);static void AfterCvPlayer_doAdvancedStartAction(CvPlayer* self, AdvancedStartActionTypes eAction, int iX, int iY, int iData, bool bAdd);static void ReplaceCvPlayer_doAdvancedStartAction(void (*original)(CvPlayer*, AdvancedStartActionTypes, int, int, int, bool), CvPlayer* self, AdvancedStartActionTypes eAction, int iX, int iY, int iData, bool bAdd);CivRegisterBefore<CivHooks::CvPlayer_doAdvancedStartAction>(host, &BeforeCvPlayer_doAdvancedStartAction);CivRegisterAfter<CivHooks::CvPlayer_doAdvancedStartAction>(host, &AfterCvPlayer_doAdvancedStartAction);CivRegisterReplace<CivHooks::CvPlayer_doAdvancedStartAction>(host, &ReplaceCvPlayer_doAdvancedStartAction);
Code
22301void CvPlayer::doAdvancedStartAction(AdvancedStartActionTypes eAction, int iX, int iY, int iData, bool bAdd)22302{22303 CvPlot* pPlot = GC.getMap().plot(iX, iY);2230422305 if(0 == getNumCities())22306 {22307 switch(eAction)22308 {22309 case ADVANCEDSTARTACTION_EXIT:22310 //Try to build this player's empire22311 if(GetID() == GC.getGame().getActivePlayer())22312 {22313 GC.GetEngineUserInterface()->setBusy(true);22314 }22315 if(GetID() == GC.getGame().getActivePlayer())22316 {22317 GC.GetEngineUserInterface()->setBusy(false);22318 }22319 break;22320 case ADVANCEDSTARTACTION_AUTOMATE:22321 case ADVANCEDSTARTACTION_CITY:22322 break;22323 default:22324 // The first action must be to place a city22325 // so players can lose by spending everything22326 return;22327 }22328 }2232922330 switch(eAction)22331 {22332 case ADVANCEDSTARTACTION_EXIT:22333 GetTreasury()->ChangeGold(getAdvancedStartPoints());22334 setAdvancedStartPoints(-1);22335 if(GC.getGame().getActivePlayer() == GetID())22336 {22337 GC.GetEngineUserInterface()->setInAdvancedStart(false);22338 }2233922340 if(isHuman())22341 {22342 int iLoop;22343 for(CvCity* pCity = firstCity(&iLoop); NULL != pCity; pCity = nextCity(&iLoop))22344 {22345 pCity->chooseProduction();22346 }2234722348 chooseTech();22349 }22350 break;22351 case ADVANCEDSTARTACTION_AUTOMATE:22352 if(GetID() == GC.getGame().getActivePlayer())22353 {22354 GC.GetEngineUserInterface()->setBusy(true);22355 }22356 if(GetID() == GC.getGame().getActivePlayer())22357 {22358 GC.GetEngineUserInterface()->setBusy(false);22359 }22360 break;22361 case ADVANCEDSTARTACTION_UNIT:22362 {22363 if(pPlot == NULL)22364 return;2236522366 UnitTypes eUnit = (UnitTypes) iData;22367 int iCost = getAdvancedStartUnitCost(eUnit, bAdd, pPlot);2236822369 if(bAdd && iCost < 0)22370 {22371 return;22372 }2237322374 // Add unit to the map22375 if(bAdd)22376 {22377 if(getAdvancedStartPoints() >= iCost)22378 {22379 CvUnit* pUnit = initUnit(eUnit, iX, iY);22380 if(NULL != pUnit)22381 {22382 pUnit->finishMoves();22383 changeAdvancedStartPoints(-iCost);22384 }22385 }22386 }2238722388 // Remove unit from the map22389 else22390 {22391 // If cost is -1 we already know this unit isn't present22392 if(iCost != -1)22393 {22394 IDInfo* pUnitNode = pPlot->headUnitNode();22395 while(pUnitNode != NULL)22396 {22397 CvUnit* pLoopUnit = ::getUnit(*pUnitNode);22398 pUnitNode = pPlot->nextUnitNode(pUnitNode);2239922400 if(NULL != pLoopUnit && pLoopUnit->getUnitType() == eUnit)22401 {22402 pLoopUnit->kill(false);22403 changeAdvancedStartPoints(iCost);22404 return;22405 }22406 }22407 }2240822409 // Proper unit not found above, delete first found22410 IDInfo* pUnitNode = pPlot->headUnitNode();22411 if(pUnitNode != NULL)22412 {22413 CvUnit* pUnit = ::getUnit(*pUnitNode);2241422415 iCost = getAdvancedStartUnitCost(pUnit->getUnitType(), false);22416 CvAssertMsg(iCost != -1, "If this is -1 then that means it's going to try to delete a unit which shouldn't exist");22417 pUnit->kill(false);22418 changeAdvancedStartPoints(iCost);22419 }22420 }2242122422 if(GetID() == GC.getGame().getActivePlayer())22423 {22424 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22425 }22426 }22427 break;22428 case ADVANCEDSTARTACTION_CITY:22429 {22430 if(pPlot == NULL)22431 return;2243222433 int iCost = getAdvancedStartCityCost(bAdd, pPlot);2243422435 if(iCost < 0)22436 {22437 return;22438 }2243922440 // Add City to the map22441 if(bAdd)22442 {22443 if(0 == getNumCities())22444 {22445 PlayerTypes eClosestPlayer = NO_PLAYER;22446 int iMinDistance = INT_MAX;22447 for(int iPlayer = 0; iPlayer < MAX_CIV_PLAYERS; iPlayer++)22448 {22449 CvPlayer& kPlayer = GET_PLAYER((PlayerTypes)iPlayer);22450 if(kPlayer.isAlive())22451 {22452 if(kPlayer.getTeam() == getTeam())22453 {22454 if(0 == kPlayer.getNumCities())22455 {22456 CvAssert(kPlayer.getStartingPlot() != NULL);22457 int iDistance = plotDistance(iX, iY, kPlayer.getStartingPlot()->getX(), kPlayer.getStartingPlot()->getY());22458 if(iDistance < iMinDistance)22459 {22460 eClosestPlayer = kPlayer.GetID();22461 iMinDistance = iDistance;22462 }22463 }22464 }22465 }22466 }22467 CvAssertMsg(eClosestPlayer != NO_PLAYER, "Self at a minimum should always be valid");22468 if(eClosestPlayer != GetID())22469 {22470 CvPlot* pTempPlot = GET_PLAYER(eClosestPlayer).getStartingPlot();22471 GET_PLAYER(eClosestPlayer).setStartingPlot(getStartingPlot());22472 setStartingPlot(pTempPlot);22473 }22474 }22475 if(getAdvancedStartPoints() >= iCost || 0 == getNumCities())22476 {22477 found(iX, iY);22478 changeAdvancedStartPoints(-iCost);22479 CvCity* pCity = pPlot->getPlotCity();22480 if(pCity != NULL)22481 {22482 if(pCity->getPopulation() > 1)22483 {22484 pCity->setFood(pCity->growthThreshold() / 2);22485 }22486 }22487 }22488 }2248922490 // Remove City from the map22491 else22492 {22493 pPlot->setRouteType(NO_ROUTE);22494 pPlot->getPlotCity()->kill();22495 pPlot->setImprovementType(NO_IMPROVEMENT);22496 changeAdvancedStartPoints(iCost);22497 }2249822499 if(GetID() == GC.getGame().getActivePlayer())22500 {22501 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22502 }22503 }22504 break;22505 case ADVANCEDSTARTACTION_POP:22506 {22507 if(pPlot == NULL)22508 return;2250922510 CvCity* pCity = pPlot->getPlotCity();2251122512 if(pCity != NULL)22513 {22514 int iCost = getAdvancedStartPopCost(bAdd, pCity);2251522516 if(iCost < 0)22517 {22518 return;22519 }2252022521 // Add Pop to the City22522 if(bAdd)22523 {22524 if(getAdvancedStartPoints() >= iCost)22525 {22526 pCity->changePopulation(1);22527 changeAdvancedStartPoints(-iCost);22528 if(pCity->getPopulation() > 1)22529 {22530 pCity->setFood(pCity->growthThreshold() / 2);22531 pCity->setFoodKept((pCity->getFood() * pCity->getMaxFoodKeptPercent()) / 100);22532 }22533 }22534 }2253522536 // Remove Pop from the city22537 else22538 {22539 pCity->changePopulation(-1);22540 changeAdvancedStartPoints(iCost);22541 if(pCity->getPopulation() == 1)22542 {22543 pCity->setFood(0);22544 pCity->setFoodKept(0);22545 }22546 }22547 }22548 }22549 break;22550 case ADVANCEDSTARTACTION_BUILDING:22551 {22552 if(pPlot == NULL)22553 return;2255422555 CvCity* pCity = pPlot->getPlotCity();2255622557 if(pCity != NULL)22558 {22559 BuildingTypes eBuilding = (BuildingTypes) iData;2256022561 CvBuildingEntry* pkBuildingInfo = GC.getBuildingInfo(eBuilding);22562 if(pkBuildingInfo == NULL)22563 {22564 return;22565 }2256622567 int iCost = getAdvancedStartBuildingCost(eBuilding, bAdd, pCity);22568 if(iCost < 0)22569 {22570 return;22571 }2257222573 // Add Building to the City22574 if(bAdd)22575 {22576 if(getAdvancedStartPoints() >= iCost)22577 {22578 pCity->GetCityBuildings()->SetNumRealBuilding(eBuilding, pCity->GetCityBuildings()->GetNumRealBuilding(eBuilding)+1);22579 changeAdvancedStartPoints(-iCost);22580 if(pkBuildingInfo->GetFoodKept() != 0)22581 {22582 pCity->setFoodKept((pCity->getFood() * pCity->getMaxFoodKeptPercent()) / 100);22583 }22584 }22585 }2258622587 // Remove Building from the map22588 else22589 {22590 pCity->GetCityBuildings()->SetNumRealBuilding(eBuilding, pCity->GetCityBuildings()->GetNumRealBuilding(eBuilding)-1);22591 changeAdvancedStartPoints(iCost);22592 if(pkBuildingInfo->GetFoodKept() != 0)22593 {22594 pCity->setFoodKept((pCity->getFood() * pCity->getMaxFoodKeptPercent()) / 100);22595 }22596 }22597 }2259822599 if(GetID() == GC.getGame().getActivePlayer())22600 {22601 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22602 }22603 }22604 break;22605 case ADVANCEDSTARTACTION_ROUTE:22606 {22607 if(pPlot == NULL)22608 return;2260922610 RouteTypes eRoute = (RouteTypes) iData;22611 int iCost = getAdvancedStartRouteCost(eRoute, bAdd, pPlot);2261222613 if(bAdd && iCost < 0)22614 {22615 return;22616 }2261722618 // Add Route to the plot22619 if(bAdd)22620 {22621 if(getAdvancedStartPoints() >= iCost)22622 {22623 pPlot->setRouteType(eRoute);22624 changeAdvancedStartPoints(-iCost);22625 }22626 }2262722628 // Remove Route from the Plot22629 else22630 {22631 if(pPlot->getRouteType() != eRoute)22632 {22633 eRoute = pPlot->getRouteType();22634 iCost = getAdvancedStartRouteCost(eRoute, bAdd);22635 }2263622637 if(iCost < 0)22638 {22639 return;22640 }2264122642 pPlot->setRouteType(NO_ROUTE);22643 changeAdvancedStartPoints(iCost);22644 }2264522646 if(GetID() == GC.getGame().getActivePlayer())22647 {22648 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22649 }22650 }22651 break;22652 case ADVANCEDSTARTACTION_IMPROVEMENT:22653 {22654 if(pPlot == NULL)22655 return;2265622657 ImprovementTypes eImprovement = (ImprovementTypes) iData;22658 int iCost = getAdvancedStartImprovementCost(eImprovement, bAdd, pPlot);2265922660 if(bAdd && iCost < 0)22661 {22662 return;22663 }2266422665 // Add Improvement to the plot22666 if(bAdd)22667 {22668 if(getAdvancedStartPoints() >= iCost)22669 {22670 if(pPlot->getFeatureType() != NO_FEATURE)22671 {22672 for(int iI = 0; iI < GC.getNumBuildInfos(); ++iI)22673 {22674 CvBuildInfo* pkBuildInfo = GC.getBuildInfo((BuildTypes) iI);22675 if(!pkBuildInfo)22676 {22677 continue;22678 }2267922680 ImprovementTypes eLoopImprovement = ((ImprovementTypes)(pkBuildInfo->getImprovement()));2268122682 if(eImprovement == eLoopImprovement)22683 {22684 if(pkBuildInfo->isFeatureRemove(pPlot->getFeatureType()) && canBuild(pPlot, (BuildTypes)iI))22685 {22686 pPlot->setFeatureType(NO_FEATURE);22687 break;22688 }22689 }22690 }22691 }2269222693 pPlot->setImprovementType(eImprovement, GetID());2269422695 changeAdvancedStartPoints(-iCost);22696 }22697 }2269822699 // Remove Improvement from the Plot22700 else22701 {22702 if(pPlot->getImprovementType() != eImprovement)22703 {22704 eImprovement = pPlot->getImprovementType();22705 iCost = getAdvancedStartImprovementCost(eImprovement, bAdd, pPlot);22706 }2270722708 if(iCost < 0)22709 {22710 return;22711 }2271222713 pPlot->setImprovementType(NO_IMPROVEMENT);22714 changeAdvancedStartPoints(iCost);22715 }2271622717 if(GetID() == GC.getGame().getActivePlayer())22718 {22719 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22720 }22721 }22722 break;22723 case ADVANCEDSTARTACTION_TECH:22724 {22725 TechTypes eTech = (TechTypes) iData;22726 int iCost = getAdvancedStartTechCost(eTech, bAdd);2272722728 if(iCost < 0)22729 {22730 return;22731 }2273222733 // Add Tech to team22734 if(bAdd)22735 {22736 if(getAdvancedStartPoints() >= iCost)22737 {22738 GET_TEAM(getTeam()).setHasTech(eTech, true, GetID(), false, false);22739 changeAdvancedStartPoints(-iCost);22740 }22741 }2274222743 // Remove Tech from the Team22744 else22745 {22746 GET_TEAM(getTeam()).setHasTech(eTech, false, GetID(), false, false);22747 changeAdvancedStartPoints(iCost);22748 }2274922750 if(GetID() == GC.getGame().getActivePlayer())22751 {22752 GC.GetEngineUserInterface()->setDirty(Advanced_Start_DIRTY_BIT, true);22753 }22754 }22755 break;22756 case ADVANCEDSTARTACTION_VISIBILITY:22757 {22758 if(pPlot == NULL)22759 return;2276022761 int iCost = getAdvancedStartVisibilityCost(bAdd, pPlot);2276222763 if(iCost < 0)22764 {22765 return;22766 }2276722768 // Add Visibility to the plot22769 if(bAdd)22770 {22771 if(getAdvancedStartPoints() >= iCost)22772 {22773#if defined(MOD_API_EXTENSIONS)22774 pPlot->setRevealed(getTeam(), true, NULL, true);22775#else22776 pPlot->setRevealed(getTeam(), true, true);22777#endif22778 changeAdvancedStartPoints(-iCost);22779 }22780 }2278122782 // Remove Visibility from the Plot22783 else22784 {22785#if defined(MOD_API_EXTENSIONS)22786 pPlot->setRevealed(getTeam(), false, NULL, true);22787#else22788 pPlot->setRevealed(getTeam(), false, true);22789#endif22790 changeAdvancedStartPoints(iCost);22791 }22792 }22793 break;22794 default:22795 CvAssert(false);22796 break;22797 }22798}