| 441 | } |
| 442 | |
| 443 | bool UnPackNetPlayer(const PlayerNetPack &packed, Player &player) |
| 444 | { |
| 445 | CopyUtf8(player._pName, packed.pName, sizeof(player._pName)); |
| 446 | ValidateField(packed.pName, UiValidPlayerName(player._pName)); |
| 447 | |
| 448 | ValidateField(packed.pClass, packed.pClass < enum_size<HeroClass>::value); |
| 449 | player._pClass = static_cast<HeroClass>(packed.pClass); |
| 450 | |
| 451 | Point position { packed.px, packed.py }; |
| 452 | ValidateFields(position.x, position.y, InDungeonBounds(position)); |
| 453 | ValidateField(packed.plrlevel, packed.plrlevel < NUMLEVELS); |
| 454 | ValidateField(packed.pLevel, packed.pLevel >= 1 && packed.pLevel <= MaxCharacterLevel); |
| 455 | |
| 456 | int32_t baseHpMax = SDL_SwapLE32(packed.pMaxHPBase); |
| 457 | int32_t baseHp = SDL_SwapLE32(packed.pHPBase); |
| 458 | int32_t hpMax = SDL_SwapLE32(packed.pMaxHP); |
| 459 | ValidateFields(baseHp, baseHpMax, baseHp >= (baseHpMax - hpMax) && baseHp <= baseHpMax); |
| 460 | |
| 461 | int32_t baseManaMax = SDL_SwapLE32(packed.pMaxManaBase); |
| 462 | int32_t baseMana = SDL_SwapLE32(packed.pManaBase); |
| 463 | ValidateFields(baseMana, baseManaMax, baseMana <= baseManaMax); |
| 464 | |
| 465 | ValidateFields(packed.pClass, packed.pBaseStr, packed.pBaseStr <= player.GetMaximumAttributeValue(CharacterAttribute::Strength)); |
| 466 | ValidateFields(packed.pClass, packed.pBaseMag, packed.pBaseMag <= player.GetMaximumAttributeValue(CharacterAttribute::Magic)); |
| 467 | ValidateFields(packed.pClass, packed.pBaseDex, packed.pBaseDex <= player.GetMaximumAttributeValue(CharacterAttribute::Dexterity)); |
| 468 | ValidateFields(packed.pClass, packed.pBaseVit, packed.pBaseVit <= player.GetMaximumAttributeValue(CharacterAttribute::Vitality)); |
| 469 | |
| 470 | ValidateField(packed._pNumInv, packed._pNumInv <= InventoryGridCells); |
| 471 | |
| 472 | player._pLevel = packed.pLevel; |
| 473 | player.position.tile = position; |
| 474 | player.position.future = position; |
| 475 | player.plrlevel = packed.plrlevel; |
| 476 | player.plrIsOnSetLevel = packed.isOnSetLevel != 0; |
| 477 | player._pMaxHPBase = baseHpMax; |
| 478 | player._pHPBase = baseHp; |
| 479 | player._pMaxHP = baseHpMax; |
| 480 | player._pHitPoints = baseHp; |
| 481 | |
| 482 | ClrPlrPath(player); |
| 483 | player.destAction = ACTION_NONE; |
| 484 | |
| 485 | InitPlayer(player, true); |
| 486 | |
| 487 | player._pBaseStr = packed.pBaseStr; |
| 488 | player._pStrength = player._pBaseStr; |
| 489 | player._pBaseMag = packed.pBaseMag; |
| 490 | player._pMagic = player._pBaseMag; |
| 491 | player._pBaseDex = packed.pBaseDex; |
| 492 | player._pDexterity = player._pBaseDex; |
| 493 | player._pBaseVit = packed.pBaseVit; |
| 494 | player._pVitality = player._pBaseVit; |
| 495 | player._pStatPts = packed.pStatPts; |
| 496 | |
| 497 | player._pExperience = SDL_SwapLE32(packed.pExperience); |
| 498 | player._pBaseToBlk = PlayersData[static_cast<std::size_t>(player._pClass)].blockBonus; |
| 499 | player._pMaxManaBase = baseManaMax; |
| 500 | player._pManaBase = baseMana; |