void CUser::RecvZoneChange(Packet & pkt) { if (isDead()) // we also need to make sure we're actually waiting on this request... return; uint8 opcode = pkt.read<uint8>(); if (opcode == 1) { g_pMain->UserInOutForMe(this); g_pMain->NpcInOutForMe(this); g_pMain->MerchantUserInOutForMe(this); Packet result(WIZ_ZONE_CHANGE, uint8(2)); // finalise the zone change Send(&result); } else if (opcode == 2) { UserInOut(INOUT_RESPAWN); // TO-DO: Fix all this up (it's too messy/confusing) if (!m_bZoneChangeSameZone) { BlinkStart(); RecastSavedMagic(); } m_bZoneChangeFlag = 0; m_bWarp = 0; } }
// This packet actually contains the char name after the opcode void CUser::GameStart(Packet & pkt) { if (isInGame()) return; uint8 opcode = pkt.read<uint8>(); if (opcode == 1) { SendMyInfo(); g_pMain->UserInOutForMe(this); g_pMain->MerchantUserInOutForMe(this); g_pMain->NpcInOutForMe(this); SendNotice(); SendTime(); SendWeather(); // SendHackToolList(); Packet result(WIZ_GAMESTART); Send(&result); } else if (opcode == 2) { m_state = GAME_STATE_INGAME; UserInOut(INOUT_RESPAWN); if (!m_bCity && m_sHp <= 0) m_bCity = -1; if (m_bCity > 0) { int level = GetLevel(); if (m_bCity <= 100) level--; // make sure we don't exceed bounds if (level > MAX_LEVEL) level = MAX_LEVEL; else if (level < 1) level = 1; m_iLostExp = (g_pMain->GetExpByLevel(level) * (m_bCity % 10) / 100); if (((m_bCity % 10) / 100) == 1) m_iLostExp /= 2; } else { m_iLostExp = 0; } CheckSeedQuest(); BlinkStart(); SetUserAbility(); // rental RecastSavedMagic(m_sHp == m_iMaxHp ? true : false); //ItemMallRecast // If we've relogged while dead, we need to make sure the client // is still given the option to revive. if (isDead()) SendDeathAnimation(); g_pMain->TempleEventGetActiveEventTime(this); } m_tHPLastTimeNormal = UNIXTIME; }
void CUser::Regene(uint8 regene_type, uint32 magicid /*= 0*/) { ASSERT(GetMap() != nullptr); _OBJECT_EVENT* pEvent = nullptr; _HOME_INFO* pHomeInfo = nullptr; float x = 0.0f, z = 0.0f; if (!isDead()) return; if (regene_type != 1 && regene_type != 2) regene_type = 1; if (regene_type == 2) { magicid = 490041; // The Stone of Ressurection magic ID // Is our level high enough to be able to resurrect using this skill? if (GetLevel() <= 5 // Do we have enough resurrection stones? || !RobItem(379006000, 3 * GetLevel())) return; } // If we're in a home zone, we'll want the coordinates from there. Otherwise, assume our own home zone. pHomeInfo = g_pMain->m_HomeArray.GetData(GetZoneID() <= ZONE_ELMORAD ? GetZoneID() : GetNation()); if (pHomeInfo == nullptr) return; UserInOut(INOUT_OUT); pEvent = GetMap()->GetObjectEvent(m_sBind); // If we're not using a spell to resurrect. if (magicid == 0) { // Resurrect at a bind/respawn point if (pEvent != nullptr && pEvent->byLife == 1) { SetPosition(pEvent->fPosX + x, 0.0f, pEvent->fPosZ + z); } // Are we trying to respawn in a home zone? else if (GetZoneID() <= ZONE_ELMORAD) { // Use the proper respawn area for our nation, as the opposite nation can // enter this zone at a war's invasion stage. if (GetNation() == KARUS) { x = (float)(pHomeInfo->KarusZoneX + myrand(0, pHomeInfo->KarusZoneLX)); z = (float)(pHomeInfo->KarusZoneZ + myrand(0, pHomeInfo->KarusZoneLZ)); } else { x = (float)(pHomeInfo->ElmoZoneX + myrand(0, pHomeInfo->ElmoZoneLX)); z = (float)(pHomeInfo->ElmoZoneZ + myrand(0, pHomeInfo->ElmoZoneLZ)); } } else { // If we're in a war zone (aside from snow wars, which apparently use different coords), use BattleZone coordinates. if (GetZoneID() != ZONE_SNOW_BATTLE && GetZoneID() == (ZONE_BATTLE_BASE + g_pMain->m_byBattleZone)) { x = (float)(pHomeInfo->BattleZoneX + myrand(0, pHomeInfo->BattleZoneLX)); z = (float)(pHomeInfo->BattleZoneZ + myrand(0, pHomeInfo->BattleZoneLZ)); } // If we died in the Moradon arena, we need to spawn near the Arena. else if (GetZoneID() == ZONE_MORADON && isInArena()) { x = (float)(MINI_ARENA_RESPAWN_X + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS)); z = (float)(MINI_ARENA_RESPAWN_Z + myrand(-MINI_ARENA_RESPAWN_RADIUS, MINI_ARENA_RESPAWN_RADIUS)); } // For all else, just grab the start position (/town coordinates) from the START_POSITION table. else { short sx, sz; GetStartPosition(sx, sz); x = sx; z = sz; } } SetPosition(x, 0.0f, z); m_bResHpType = USER_STANDING; m_bRegeneType = REGENE_NORMAL; } else // we're respawning using a resurrect skill. { _MAGIC_TYPE5 * pType = g_pMain->m_Magictype5Array.GetData(magicid); if (pType == nullptr) return; MSpChange(-m_iMaxMp); // reset us to 0 MP. if (m_sWhoKilledMe == -1) ExpChange((m_iLostExp * pType->bExpRecover) / 100); // Restore m_bResHpType = USER_STANDING; m_bRegeneType = REGENE_MAGIC; } Packet result(WIZ_REGENE); result << GetSPosX() << GetSPosZ() << GetSPosY(); Send(&result); HpChange(GetMaxHealth()); m_tLastRegeneTime = UNIXTIME; m_sWhoKilledMe = -1; m_iLostExp = 0; if (magicid == 0) BlinkStart(); if (!isBlinking()) { result.Initialize(AG_USER_REGENE); result << GetSocketID() << m_sHp; Send_AIServer(&result); } SetRegion(GetNewRegionX(), GetNewRegionZ()); UserInOut(INOUT_RESPAWN); g_pMain->RegionUserInOutForMe(this); g_pMain->RegionNpcInfoForMe(this); InitializeStealth(); SendUserStatusUpdate(USER_STATUS_DOT, USER_STATUS_CURE); SendUserStatusUpdate(USER_STATUS_POISON, USER_STATUS_CURE); if (isInArena()) SendUserStatusUpdate(USER_STATUS_SPEED, USER_STATUS_CURE); RecastSavedMagic(); // If we actually respawned (i.e. we weren't resurrected by a skill)... if (magicid == 0) { // In PVP zones (not war zones), we must kick out players if they no longer // have any national points. if (GetMap()->isNationPVPZone() && GetMap()->isWarZone() && GetLoyalty() == 0) KickOutZoneUser(false); } }