Hooks
static bool BeforeSetupUnit(const CvWorldBuilderMap::Unit& kSavedUnit, int iPlotX, int iPlotY);static void AfterSetupUnit(const CvWorldBuilderMap::Unit& kSavedUnit, int iPlotX, int iPlotY);static void ReplaceSetupUnit(void (*original)(const CvWorldBuilderMap::Unit&, int, int), const CvWorldBuilderMap::Unit& kSavedUnit, int iPlotX, int iPlotY);// CivHooks.h gives this hook point no types, so nothing checks these hooks' parameters.host->RegisterHook(host->pluginIndex, CivHooks::SetupUnit::ID, CIV_HOOK_BEFORE, (void*)&BeforeSetupUnit);host->RegisterHook(host->pluginIndex, CivHooks::SetupUnit::ID, CIV_HOOK_AFTER, (void*)&AfterSetupUnit);host->RegisterHook(host->pluginIndex, CivHooks::SetupUnit::ID, CIV_HOOK_REPLACE, (void*)&ReplaceSetupUnit);
Code
666void SetupUnit(const CvWorldBuilderMap::Unit& kSavedUnit, int iPlotX, int iPlotY)667{668 const PlayerTypes ePlayer = GetPlayerType(kSavedUnit.m_byOwner);669 UnitTypes eUnitType = (UnitTypes)kSavedUnit.m_byUnitType;670 // Test to see if m_byUnitType is still a byte, if so, if it is 255, then it is really -1 and we must reflect this in the eUnitType671 // The World Builder map format should be changed so the serialization of the unit type is an int. We are already close to672 // maxing out the byte range as it stands now.673 if (sizeof(kSavedUnit.m_byUnitType) == 1 && kSavedUnit.m_byUnitType == 255)674 {675 eUnitType = NO_UNIT;676 }677678 UnitAITypes eAIType = NO_UNITAI;679 const CvUnitEntry* pkUnitType = GC.getUnitInfo(eUnitType);680 FAssert(pkUnitType); // We should probably be concerned if this unit type isn't valid681 if(pkUnitType != NULL)682 eAIType = (UnitAITypes)pkUnitType->GetDefaultUnitAIType();683 else684 return; // The unit type is invalid, we really can't go any further.685686 DirectionTypes eFacing = NO_DIRECTION;687 switch(kSavedUnit.m_byDirection)688 {689 case CvWorldBuilderMap::Unit::DIRECTION_EAST:690 eFacing = DIRECTION_EAST;691 break;692693 case CvWorldBuilderMap::Unit::DIRECTION_NORTHEAST:694 eFacing = DIRECTION_NORTHEAST;695 break;696697 case CvWorldBuilderMap::Unit::DIRECTION_NORTHWEST:698 eFacing = DIRECTION_NORTHWEST;699 break;700701 case CvWorldBuilderMap::Unit::DIRECTION_SOUTHEAST:702 eFacing = DIRECTION_SOUTHEAST;703 break;704705 case CvWorldBuilderMap::Unit::DIRECTION_SOUTHWEST:706 eFacing = DIRECTION_SOUTHWEST;707 break;708709 case CvWorldBuilderMap::Unit::DIRECTION_WEST:710 eFacing = DIRECTION_WEST;711 break;712713 default:714 eFacing = (DirectionTypes)GC.getGame().getJonRandNum(NUM_DIRECTION_TYPES, "Picking Random Unit Direction");715 }716717 if(ePlayer != NO_PLAYER)718 {719 CvPlayer& kPlayer = GET_PLAYER(ePlayer);720 CvUnit* pkGameplayUnit = kPlayer.initUnit(eUnitType, iPlotX, iPlotY, eAIType, eFacing, false);721 if(pkGameplayUnit != NULL)722 {723 if(kSavedUnit.GetFlag(CvWorldBuilderMap::Unit::UNIT_FORTIFIED))724 {725 if(pkGameplayUnit->isFortifyable(true))726 gDLL->sendPushMission(pkGameplayUnit->GetID(), CvTypes::getMISSION_FORTIFY(), 0, 0, 0, false);727 else728 gDLL->sendPushMission(pkGameplayUnit->GetID(), CvTypes::getMISSION_SLEEP(), 0, 0, 0, false);729 }730731 if(kSavedUnit.GetFlag(CvWorldBuilderMap::Unit::UNIT_EMBARKED))732 {733 const PromotionTypes ePromotionEmbarkation = kPlayer.GetEmbarkationPromotion();734 pkGameplayUnit->setHasPromotion(ePromotionEmbarkation, true);735 pkGameplayUnit->setEmbarked(true);736 pkGameplayUnit->setMoves(pkGameplayUnit->maxMoves());737 }738739 if(kSavedUnit.m_uiHealth != kSavedUnit.MaxHealth)740 {741 const int iMaxHitPoints = pkGameplayUnit->GetMaxHitPoints();742743 // TODO: Oh no! It's floating point math! This may be an issue for multi-player.744 const float fHitPoints = kSavedUnit.GetHealthAsFloat() * (float)iMaxHitPoints;745746 // Don't allow the unit to be killed by a precision error747 int iHitPoints = (int)fHitPoints;748 if(iHitPoints == 0 && kSavedUnit.m_uiHealth != 0)749 iHitPoints = 1;750751 pkGameplayUnit->setDamage(iMaxHitPoints - iHitPoints);752 }753754#if defined(MOD_UNITS_XP_TIMES_100)755 pkGameplayUnit->setExperienceTimes100(((int)kSavedUnit.m_uiExperience) * 100);756#else757 pkGameplayUnit->setExperience((int)kSavedUnit.m_uiExperience);758#endif759760 const int iPromotionTypeCount = GC.getNumPromotionInfos();761 for(int iPromotion = 0; iPromotion < iPromotionTypeCount; ++iPromotion)762 {763 const PromotionTypes ePromotionType = (PromotionTypes)iPromotion;764 if(kSavedUnit.m_kPromotions[iPromotion])765 pkGameplayUnit->setHasPromotion(ePromotionType, true);766 }767768 if(kSavedUnit.m_hCustomName.Valid())769 {770 CvWorldBuilderMap::UnitName* pkUnitName = sg_kSave.m_kUnitNames[kSavedUnit.m_hCustomName];771 if(pkUnitName != NULL)772 {773 pkGameplayUnit->setName(pkUnitName->m_szText);774 }775 }776 }777 }778}