#include "AvHNetworkMessages.h" #include "NetworkMeter.h" #include "../util/MathUtil.h" //for WrapFloat #include "../util/STLUtil.h" //for MakeBytesFromHexPairs #include "../cl_dll/parsemsg.h" #ifndef AVH_SERVER #include "../cl_dll/chudmisc.h" #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MESSAGE CODES - NEED TO BE INITIALIZED BEFORE CLIENT CONNECTION, OR THEY'D // BE LOCAL STATICS INSIDE OF THE FUNCTIONS USING LAZY INSTANTIATION //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifdef AVH_SERVER int g_msgAmmoPickup = 0, g_msgAmmoX, g_msgBattery, g_msgCurWeapon, g_msgDamage, //5 g_msgDeathMsg, g_msgFade, g_msgFlashlight, g_msgGeigerRange, g_msgHealth, //10 g_msgHideWeapon, g_msgHudText, g_msgHudText2, g_msgInitHUD, g_msgItemPickup, g_msgMOTD, g_msgResetHUD, g_msgSayText, g_msgScoreInfo, g_msgServerName, g_msgSetFOV, g_msgShake, g_msgShowGameTitle, g_msgShowMenu, g_msgStatusText, g_msgStatusValue, g_msgTeamInfo, g_msgTeamNames, g_msgTeamScore, g_msgTextMsg, g_msgTrain, g_msgWeaponList, g_msgWeapPickup, g_msgAlienInfo, g_msgBalanceVar, g_msgBlipList, g_msgBuildMiniMap, g_msgClientScripts, g_msgDebugCSP, g_msgEditPS, g_msgFog, g_msgGameStatus, g_msgListPS, g_msgPlayHUDNotification, g_msgProgressBar, g_msgServerVar, g_msgSetGammaRamp, g_msgSetOrder, g_msgSetParticleTemplates, g_msgDelParts, g_msgSetSelect, g_msgSetRequest, g_msgSetSoundNames, g_msgSetTechNodes, g_msgSetTechSlots, g_msgSetTopDown, g_msgSetupMap, g_msgUpdateCountdown, g_msgUpdateEntityHierarchy, g_msgDelEntityHierarchy, g_msgProfileInfo, g_msgNexusBytes, g_msgIssueOrder, g_msgHUDSetUpgrades; void Net_InitializeMessages(void) { if (g_msgAmmoPickup != 0) { return; } g_msgAmmoPickup = REG_USER_MSG("AmmoPickup", 2); g_msgAmmoX = REG_USER_MSG("AmmoX", 2); g_msgBattery = REG_USER_MSG("Battery", 2); g_msgCurWeapon = REG_USER_MSG("CurWeapon", 3); g_msgDamage = REG_USER_MSG("Damage", 12); g_msgDeathMsg = REG_USER_MSG("DeathMsg", -1); g_msgFade = REG_USER_MSG("ScreenFade", sizeof(ScreenFade)); g_msgFlashlight = REG_USER_MSG("FLashlight", 2); g_msgGeigerRange = REG_USER_MSG("Geiger", 1); g_msgHealth = REG_USER_MSG("Health", 2); g_msgHideWeapon = REG_USER_MSG("HideWeapon", 1); g_msgHudText = REG_USER_MSG("HudText", -1); g_msgHudText2 = REG_USER_MSG("HudText2", -1); g_msgInitHUD = REG_USER_MSG("InitHUD", 0); g_msgItemPickup = REG_USER_MSG("ItemPickup", -1); g_msgMOTD = REG_USER_MSG("MOTD", -1); g_msgResetHUD = REG_USER_MSG("ResetHUD", 0); g_msgSayText = REG_USER_MSG("SayText", -1); // : 0001073 g_msgScoreInfo = REG_USER_MSG("ScoreInfo", -1); g_msgServerName = REG_USER_MSG("ServerName", -1); g_msgSetFOV = REG_USER_MSG("SetFOV", 1); g_msgShake = REG_USER_MSG("ScreenShake", 6); g_msgShowGameTitle = REG_USER_MSG("GameTitle", 1); g_msgShowMenu = REG_USER_MSG("ShowMenu", -1); g_msgStatusText = REG_USER_MSG("StatusText", -1); g_msgStatusValue = REG_USER_MSG("StatusValue", 3); g_msgTeamInfo = REG_USER_MSG("TeamInfo", -1); g_msgTeamNames = REG_USER_MSG("TeamNames", -1); g_msgTeamScore = REG_USER_MSG("TeamScore", -1); g_msgTextMsg = REG_USER_MSG("TextMsg", -1); g_msgTrain = REG_USER_MSG("Train", 1); g_msgWeaponList = REG_USER_MSG("WeaponList", -1); g_msgWeapPickup = REG_USER_MSG("WeapPickup", 1); g_msgAlienInfo = REG_USER_MSG("AlienInfo", -1); g_msgBalanceVar = REG_USER_MSG("BalanceVar", -1); g_msgBlipList = REG_USER_MSG("BlipList", -1); g_msgBuildMiniMap = REG_USER_MSG("MiniMap", -1); g_msgClientScripts = REG_USER_MSG("ClScript", -1); g_msgDebugCSP = REG_USER_MSG("DebugCSP", 14); g_msgEditPS = REG_USER_MSG("EditPS", 2); g_msgFog = REG_USER_MSG("Fog", -1); g_msgGameStatus = REG_USER_MSG("GameStatus", -1); g_msgListPS = REG_USER_MSG("ListPS", -1); g_msgPlayHUDNotification = REG_USER_MSG("PlayHUDNot", 6); g_msgHUDSetUpgrades = REG_USER_MSG("SetUpgrades", 1); g_msgProgressBar = REG_USER_MSG("Progress", -1); g_msgServerVar = REG_USER_MSG("ServerVar", -1); g_msgSetGammaRamp = REG_USER_MSG("SetGmma", 1); g_msgSetOrder = REG_USER_MSG("SetOrder", -1); g_msgSetParticleTemplates = REG_USER_MSG("Particles", -1); g_msgDelParts = REG_USER_MSG("DelParts", 0); g_msgSetSelect = REG_USER_MSG("SetSelect", -1); g_msgSetRequest = REG_USER_MSG("SetRequest", 2); g_msgSetSoundNames = REG_USER_MSG("SoundNames", -1); g_msgSetTechNodes = REG_USER_MSG("SetTech", 9); g_msgSetTechSlots = REG_USER_MSG("TechSlots", 1 + kNumTechSlots); g_msgSetTopDown = REG_USER_MSG("SetTopDown", -1); g_msgSetupMap = REG_USER_MSG("SetupMap", -1); g_msgUpdateCountdown = REG_USER_MSG("Countdown", 1); g_msgUpdateEntityHierarchy = REG_USER_MSG("EntHier", -1); g_msgDelEntityHierarchy = REG_USER_MSG("DelEntHier", 0); g_msgProfileInfo = REG_USER_MSG("ProfileInfo", 8); g_msgNexusBytes = REG_USER_MSG("NexusBytes", -1); // : 0000971 g_msgIssueOrder = REG_USER_MSG("IssueOrder", 9); // : } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MESSAGE FUNCTIONS - READ/WRITE PAIRS FOR NETWORK MESSAGES //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #define END_READ() ; #ifndef AVH_SERVER void NetMsg_AmmoPickup(void* const buffer, const int size, int& index, int& count) { BEGIN_READ(buffer, size); index = READ_BYTE(); count = READ_BYTE(); END_READ(); } #else void NetMsg_AmmoPickup(entvars_t* const pev, const int index, const int count) { MESSAGE_BEGIN(MSG_ONE, g_msgAmmoPickup, NULL, pev); WRITE_BYTE(index); WRITE_BYTE(count); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_AmmoX(void* const buffer, const int size, int& index, int& count) { BEGIN_READ(buffer, size); index = READ_BYTE(); count = READ_BYTE(); END_READ(); } #else void NetMsg_AmmoX(entvars_t* pev, const int index, const int count) { MESSAGE_BEGIN(MSG_ONE, g_msgAmmoX, NULL, pev); WRITE_BYTE(index); WRITE_BYTE(count); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Battery(void* const buffer, const int size, int& armor_amount) { BEGIN_READ(buffer, size); armor_amount = READ_SHORT(); END_READ(); } #else void NetMsg_Battery(entvars_t* const pev, const int armor_amount) { MESSAGE_BEGIN(MSG_ONE, g_msgBattery, NULL, pev); WRITE_SHORT(armor_amount); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_CurWeapon(void* const buffer, const int size, int& state, int& id, int& clip) { BEGIN_READ(buffer, size); state = READ_BYTE(); id = READ_BYTE(); clip = READ_BYTE(); END_READ(); } #else void NetMsg_CurWeapon(entvars_t* const pev, const int state, const int id, const int clip) { MESSAGE_BEGIN(MSG_ONE, g_msgCurWeapon, NULL, pev); WRITE_BYTE(state); WRITE_BYTE(id); WRITE_BYTE(clip); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Damage(void* const buffer, const int size, int& dmg_save, int& dmg_take, long& bits, float* origin) { BEGIN_READ(buffer, size); dmg_save = READ_BYTE(); dmg_take = READ_BYTE(); bits = READ_LONG(); origin[0] = READ_COORD(); origin[1] = READ_COORD(); origin[2] = READ_COORD(); END_READ(); } #else void NetMsg_Damage(entvars_t* const pev, const int dmg_save, const int dmg_take, const long bits, const float* origin) { MESSAGE_BEGIN(MSG_ONE, g_msgDamage, NULL, pev); WRITE_BYTE(dmg_save); WRITE_BYTE(dmg_take); WRITE_LONG(bits); WRITE_COORD(origin[0]); WRITE_COORD(origin[1]); WRITE_COORD(origin[2]); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_DeathMsg(void* const buffer, const int size, int& killer_index, int& victim_index, string& weapon_name) { BEGIN_READ(buffer, size); killer_index = READ_BYTE(); victim_index = READ_BYTE(); weapon_name = READ_STRING(); END_READ(); } #else void NetMsg_DeathMsg(const int killer_index, const int victim_index, string& weapon_name) { MESSAGE_BEGIN(MSG_ALL, g_msgDeathMsg); WRITE_BYTE(killer_index); WRITE_BYTE(victim_index); WRITE_STRING(weapon_name.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Fade(void* const buffer, const int size, ScreenFade& fade) { BEGIN_READ(buffer, size); fade.duration = READ_SHORT(); fade.holdTime = READ_SHORT(); fade.fadeFlags = READ_SHORT(); fade.r = READ_BYTE(); fade.g = READ_BYTE(); fade.b = READ_BYTE(); fade.a = READ_BYTE(); END_READ(); } #else void NetMsg_Fade(entvars_t* const pev, const ScreenFade& fade) { MESSAGE_BEGIN(MSG_ONE, g_msgFade, NULL, pev); // use the magic #1 for "one client" WRITE_SHORT(fade.duration); WRITE_SHORT(fade.holdTime); WRITE_SHORT(fade.fadeFlags); WRITE_BYTE(fade.r); WRITE_BYTE(fade.g); WRITE_BYTE(fade.b); WRITE_BYTE(fade.a); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Flashlight(void* const buffer, const int size, int& is_on, int& flash_battery) { BEGIN_READ(buffer, size); is_on = READ_BYTE(); flash_battery = READ_BYTE(); END_READ(); } #else void NetMsg_Flashlight(entvars_t* const pev, const int is_on, const int flash_battery) { MESSAGE_BEGIN(MSG_ONE, g_msgFlashlight, NULL, pev); WRITE_BYTE(is_on); WRITE_BYTE(flash_battery); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_GeigerRange(void* const buffer, const int size, int& range) { BEGIN_READ(buffer, size); range = READ_BYTE(); END_READ(); } #else void NetMsg_GeigerRange(entvars_t* const pev, const int range) { MESSAGE_BEGIN(MSG_ONE, g_msgGeigerRange, NULL, pev); WRITE_BYTE(range); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Health(void* const buffer, const int size, int& health) { BEGIN_READ(buffer, size); health = READ_SHORT(); END_READ(); } #else void NetMsg_Health(entvars_t* const pev, const int health) { MESSAGE_BEGIN(MSG_ONE, g_msgHealth, NULL, pev); WRITE_SHORT(health); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_HideWeapon(void* const buffer, const int size, int& hide) { BEGIN_READ(buffer, size); hide = READ_BYTE(); END_READ(); } #else void NetMsg_HideWeapon(entvars_t* const pev, const int hide) { MESSAGE_BEGIN(MSG_ONE, g_msgHideWeapon, NULL, pev); WRITE_BYTE(hide); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_HudText(void* const buffer, const int size, string& text) { BEGIN_READ(buffer, size); text = READ_STRING(); END_READ(); } #else void NetMsg_HudText(entvars_t* const pev, const string& text) { MESSAGE_BEGIN(MSG_ONE, g_msgHudText, NULL, pev); WRITE_STRING(text.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_HudText2(void* const buffer, const int size, string& text, int& flags) { BEGIN_READ(buffer, size); text = READ_STRING(); flags = READ_BYTE(); END_READ(); } #else void NetMsg_HudText2(entvars_t* const pev, const string& text, const int flags) { MESSAGE_BEGIN(MSG_ONE, g_msgHudText2, NULL, pev); WRITE_STRING(text.c_str()); WRITE_BYTE(flags); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_InitHUD(void* const buffer, const int size) { BEGIN_READ(buffer, size); END_READ(); } #else void NetMsg_InitHUD(entvars_t* const pev) { MESSAGE_BEGIN(MSG_ONE, g_msgInitHUD, NULL, pev); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ItemPickup(void* const buffer, const int size, string& item_name) { BEGIN_READ(buffer, size); item_name = READ_STRING(); END_READ(); } #else void NetMsg_ItemPickup(entvars_t* const pev, const string& item_name) { MESSAGE_BEGIN(MSG_ONE, g_msgItemPickup, NULL, pev); WRITE_STRING(item_name.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_MOTD(void* const buffer, const int size, bool& is_finished, string& MOTD) { BEGIN_READ(buffer, size); is_finished = (READ_BYTE() == 1); MOTD = READ_STRING(); END_READ(); } #else void NetMsg_MOTD(entvars_t* const pev, const bool is_finished, const string& MOTD) { MESSAGE_BEGIN(MSG_ONE, g_msgMOTD, NULL, pev); WRITE_BYTE(is_finished ? 1 : 0); WRITE_STRING(MOTD.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ResetHUD(void* const buffer, const int size) { BEGIN_READ(buffer, size); END_READ(); } #else void NetMsg_ResetHUD(entvars_t* const pev) { MESSAGE_BEGIN(MSG_ONE, g_msgResetHUD, NULL, pev); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SayText(void* const buffer, const int size, int& entity_index, string& text, string& location) { BEGIN_READ(buffer, size); entity_index = READ_BYTE(); text = READ_STRING(); location = READ_STRING(); END_READ(); } #else //MESSAGE TO EVERYBODY void NetMsg_SayText(const int entity_index, const string& text, const string& location) { MESSAGE_BEGIN(MSG_ALL, g_msgSayText, NULL); WRITE_BYTE(entity_index); WRITE_STRING(text.c_str()); WRITE_STRING(location.c_str()); MESSAGE_END(); } //MESSAGE TO ONE PERSON void NetMsg_SayText(entvars_t* const pev, const int entity_index, const string& text, const string& location) { MESSAGE_BEGIN(MSG_ONE, g_msgSayText, NULL, pev); WRITE_BYTE(entity_index); WRITE_STRING(text.c_str()); WRITE_STRING(location.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // : 0001073 #ifndef AVH_SERVER void NetMsg_ScoreInfo(void* const buffer, const int size, ScoreInfo& info) { BEGIN_READ(buffer, size); info.player_index = READ_BYTE(); info.score = READ_SHORT(); info.frags = READ_SHORT(); info.deaths = READ_SHORT(); info.extra = READ_SHORT(); info.player_class = READ_BYTE(); info.auth = READ_SHORT(); info.team = READ_SHORT(); info.health = READ_SHORT(); char* theString = READ_STRING(); #ifdef USE_OLDAUTH if (info.auth & PLAYERAUTH_CUSTOM) { //clear the string (I dont think this array is reset anywhere else (since everything is set when the score info message is sent anyways) //so just memset it here to prevent any possible problems. memset(&g_PlayerExtraInfo[info.player_index].customicon, 0, sizeof(g_PlayerExtraInfo[info.player_index].customicon)); // Read custom icon if (theString && strlen(theString) >= 4 && strlen(theString) <= CUSTOM_ICON_LENGTH + 2)//make sure the string is within the right size. strncpy(g_PlayerExtraInfo[info.player_index].customicon, theString, sizeof(g_PlayerExtraInfo[info.player_index].customicon) - 1); } #endif END_READ(); } #else void NetMsg_ScoreInfo(const ScoreInfo& info) { MESSAGE_BEGIN(MSG_ALL, g_msgScoreInfo); WRITE_BYTE(info.player_index); WRITE_SHORT(info.score); WRITE_SHORT(info.frags); WRITE_SHORT(info.deaths); WRITE_SHORT(info.extra); WRITE_BYTE(info.player_class); WRITE_SHORT(info.auth); WRITE_SHORT(info.team); WRITE_SHORT(info.health); WRITE_STRING("0"); MESSAGE_END(); } void NetMsgSpec_ScoreInfo(const ScoreInfo& info) { MESSAGE_BEGIN(MSG_SPEC, g_msgScoreInfo); WRITE_BYTE(info.player_index); WRITE_SHORT(info.score); WRITE_SHORT(info.frags); WRITE_SHORT(info.deaths); WRITE_SHORT(info.extra); WRITE_BYTE(info.player_class); WRITE_SHORT(info.auth); WRITE_SHORT(info.team); WRITE_SHORT(info.health); WRITE_STRING("0"); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ServerName(void* const buffer, const int size, string& name) { BEGIN_READ(buffer, size); name = READ_STRING(); END_READ(); } #else void NetMsg_ServerName(entvars_t* const pev, const string& name) { MESSAGE_BEGIN(MSG_ONE, g_msgServerName, NULL, pev); WRITE_STRING(name.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetFOV(void* const buffer, const int size, int& fov) { BEGIN_READ(buffer, size); fov = READ_BYTE(); END_READ(); } #else void NetMsg_SetFOV(entvars_t* const pev, const int fov) { MESSAGE_BEGIN(MSG_ONE, g_msgSetFOV, NULL, pev); WRITE_BYTE(fov); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Shake(void* const buffer, const int size, ScreenShake& shake) { BEGIN_READ(buffer, size); shake.amplitude = READ_SHORT(); shake.duration = READ_SHORT(); shake.frequency = READ_SHORT(); END_READ(); } #else void NetMsg_Shake(entvars_t* const pev, const ScreenShake& shake) { MESSAGE_BEGIN(MSG_ONE, g_msgShake, NULL, pev); WRITE_SHORT(shake.amplitude); WRITE_SHORT(shake.duration); WRITE_SHORT(shake.frequency); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ShowGameTitle(void* const buffer, const int size) { BEGIN_READ(buffer, size); END_READ(); } #else void NetMsg_ShowGameTitle(entvars_t* const pev) { MESSAGE_BEGIN(MSG_ONE, g_msgShowGameTitle, NULL, pev); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ShowMenu(void* const buffer, const int size, int& valid_slots, int& display_time, int& flags, string& content) { BEGIN_READ(buffer, size); valid_slots = READ_SHORT(); display_time = READ_CHAR(); flags = READ_BYTE(); content = READ_STRING(); END_READ(); } #else void NetMsg_ShowMenu(entvars_t* const pev, const int valid_slots, const int display_time, const int flags, const string& content) { MESSAGE_BEGIN(MSG_ONE, g_msgShowMenu, NULL, pev); WRITE_SHORT(valid_slots); WRITE_CHAR(display_time); WRITE_BYTE(flags); WRITE_STRING(content.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_StatusText(void* const buffer, const int size, int& location, string& content) { BEGIN_READ(buffer, size); location = READ_BYTE(); content = READ_STRING(); END_READ(); } #else void NetMsg_StatusText(entvars_t* const pev, const int location, const string& content) { MESSAGE_BEGIN(MSG_ONE, g_msgStatusText, NULL, pev); WRITE_BYTE(location); WRITE_STRING(content.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_StatusValue(void* const buffer, const int size, int& location, int& state) { BEGIN_READ(buffer, size); location = READ_BYTE(); state = READ_SHORT(); END_READ(); } #else void NetMsg_StatusValue(entvars_t* const pev, const int location, const int state) { MESSAGE_BEGIN(MSG_ONE, g_msgStatusValue, NULL, pev); WRITE_BYTE(location); WRITE_SHORT(state); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_TeamInfo(void* const buffer, const int size, int& player_index, string& team_id) { BEGIN_READ(buffer, size); player_index = READ_BYTE(); team_id = READ_STRING(); END_READ(); } #else //MESSAGE TO EVERYBODY void NetMsg_TeamInfo(const int player_index, const string& team_id) { MESSAGE_BEGIN(MSG_ALL, g_msgTeamInfo); WRITE_BYTE(player_index); WRITE_STRING(team_id.c_str()); MESSAGE_END(); } //MESSAGE TO SPECTATORS void NetMsgSpec_TeamInfo(const int player_index, const string& team_id) { MESSAGE_BEGIN(MSG_SPEC, g_msgTeamInfo); WRITE_BYTE(player_index); WRITE_STRING(team_id.c_str()); MESSAGE_END(); } //MESSAGE TO ONE PERSON void NetMsg_TeamInfo(entvars_t* const pev, const int player_index, const string& team_id) { MESSAGE_BEGIN(MSG_ONE, g_msgTeamInfo, NULL, pev); WRITE_BYTE(player_index); WRITE_STRING(team_id.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_TeamNames(void* const buffer, const int size, StringList& team_names) { team_names.clear(); BEGIN_READ(buffer, size); int num_teams = READ_BYTE(); for (int counter = 0; counter < num_teams; counter++) { string name(READ_STRING()); team_names.push_back(name); } END_READ(); } #else void NetMsg_TeamNames(entvars_t* const pev, const StringList& team_names) { MESSAGE_BEGIN(MSG_ONE, g_msgTeamNames, NULL, pev); WRITE_BYTE(team_names.size()); for (int counter = 0; counter < team_names.size(); counter++) { WRITE_STRING(team_names[counter].c_str()); } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_TeamScore(void* const buffer, const int size, string& team_name, int& score, int& reset) { BEGIN_READ(buffer, size); team_name = READ_STRING(); score = READ_SHORT(); reset = READ_SHORT(); END_READ(); } #else void NetMsg_TeamScore(entvars_t* const pev, const string& team_name, const int score, const int reset) { MESSAGE_BEGIN(MSG_ONE, g_msgTeamScore, NULL, pev); WRITE_STRING(team_name.c_str()); WRITE_SHORT(score); WRITE_SHORT(reset); MESSAGE_END(); } void NetMsg_TeamScore(const string& team_name, const int score, const int reset) { MESSAGE_BEGIN(MSG_ALL, g_msgTeamScore); WRITE_STRING(team_name.c_str()); WRITE_SHORT(score); WRITE_SHORT(reset); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_TextMsg(void* const buffer, const int size, int& destination, StringList& message) { message.clear(); BEGIN_READ(buffer, size); destination = READ_BYTE(); message.push_back(string(READ_STRING())); message.push_back(string(READ_STRING())); message.push_back(string(READ_STRING())); message.push_back(string(READ_STRING())); message.push_back(string(READ_STRING())); END_READ(); } #else //MESSAGE TO EVERYBODY void NetMsg_TextMsg(const int destination, const StringList& message) { MESSAGE_BEGIN(MSG_ALL, g_msgTextMsg); WRITE_BYTE(destination); WRITE_STRING(message[0].c_str()); if (message.size() > 1) WRITE_STRING(message[1].c_str()); if (message.size() > 2) WRITE_STRING(message[2].c_str()); if (message.size() > 3) WRITE_STRING(message[3].c_str()); if (message.size() > 4) WRITE_STRING(message[4].c_str()); MESSAGE_END(); } //MESSAGE TO SPECTATORS void NetMsgSpec_TextMsg(const int destination, const StringList& message) { MESSAGE_BEGIN(MSG_SPEC, g_msgTextMsg); WRITE_BYTE(destination); WRITE_STRING(message[0].c_str()); if (message.size() > 1) WRITE_STRING(message[1].c_str()); if (message.size() > 2) WRITE_STRING(message[2].c_str()); if (message.size() > 3) WRITE_STRING(message[3].c_str()); if (message.size() > 4) WRITE_STRING(message[4].c_str()); MESSAGE_END(); } //MESSAGE TO ONE PERSON void NetMsg_TextMsg(entvars_t* const pev, const int destination, const StringList& message) { MESSAGE_BEGIN(MSG_ONE, g_msgTextMsg, NULL, pev); WRITE_BYTE(destination); WRITE_STRING(message[0].c_str()); if (message.size() > 1) WRITE_STRING(message[1].c_str()); if (message.size() > 2) WRITE_STRING(message[2].c_str()); if (message.size() > 3) WRITE_STRING(message[3].c_str()); if (message.size() > 4) WRITE_STRING(message[4].c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Train(void* const buffer, const int size, int& state) { BEGIN_READ(buffer, size); state = READ_BYTE(); END_READ(); } #else void NetMsg_Train(entvars_t* const pev, const int state) { MESSAGE_BEGIN(MSG_ONE, g_msgTrain, NULL, pev); WRITE_BYTE(state); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_WeaponList(void* const buffer, const int size, WeaponList& weapon) { BEGIN_READ(buffer, size); weapon.weapon_name = READ_STRING(); weapon.ammo1_type = READ_CHAR(); weapon.ammo1_max_amnt = READ_BYTE(); weapon.ammo2_type = READ_CHAR(); weapon.ammo2_max_amnt = READ_BYTE(); weapon.bucket = READ_CHAR(); weapon.bucket_pos = READ_CHAR(); weapon.bit_index = READ_CHAR(); weapon.flags = READ_BYTE(); END_READ(); } #else void NetMsg_WeaponList(entvars_t* const pev, const WeaponList& weapon) { MESSAGE_BEGIN(MSG_ONE, g_msgWeaponList, NULL, pev); WRITE_STRING(weapon.weapon_name.c_str()); WRITE_CHAR(weapon.ammo1_type); WRITE_BYTE(weapon.ammo1_max_amnt); WRITE_CHAR(weapon.ammo2_type); WRITE_BYTE(weapon.ammo2_max_amnt); WRITE_CHAR(weapon.bucket); WRITE_CHAR(weapon.bucket_pos); WRITE_CHAR(weapon.bit_index); WRITE_BYTE(weapon.flags); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_WeapPickup(void* const buffer, const int size, int& weapon_id) { BEGIN_READ(buffer, size); weapon_id = READ_BYTE(); END_READ(); } #else void NetMsg_WeapPickup(entvars_t* const pev, const int weapon_id) { MESSAGE_BEGIN(MSG_ONE, g_msgWeapPickup, NULL, pev); WRITE_BYTE(weapon_id); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ enum AlienInfo_ChangeFlags { NO_CHANGE = 0, COORDS_CHANGED = 1, STATUS_CHANGED = 2, HEALTH_CHANGED = 4 }; #ifndef AVH_SERVER void NetMsg_AlienInfo(void* const buffer, const int size, bool& was_hive_info, AvHAlienUpgradeListType& upgrades, HiveInfoListType& hives) { BEGIN_READ(buffer, size); int status, type, header = READ_BYTE(); was_hive_info = (header & 0x80) == 0; if (was_hive_info) { int num_hives = header; AlienInfo_ChangeFlags changes; for (int counter = 0; counter < num_hives; counter++) { if (hives.size() <= counter) { AvHHiveInfo hive; hives.push_back(hive); } changes = (AlienInfo_ChangeFlags)READ_BYTE(); if (changes & COORDS_CHANGED) { hives[counter].mPosX = READ_COORD(); hives[counter].mPosY = READ_COORD(); hives[counter].mPosZ = READ_COORD(); } if (changes & STATUS_CHANGED) { status = READ_BYTE(); type = (status >> 3) & 0x03; hives[counter].mUnderAttack = (status & 0x80) != 0; hives[counter].mStatus = status & 0x07; switch (type) { case 0: hives[counter].mTechnology = MESSAGE_NULL; break; case 1: hives[counter].mTechnology = ALIEN_BUILD_DEFENSE_CHAMBER; break; case 2: hives[counter].mTechnology = ALIEN_BUILD_SENSORY_CHAMBER; break; case 3: hives[counter].mTechnology = ALIEN_BUILD_MOVEMENT_CHAMBER; break; } } if (changes & HEALTH_CHANGED) { hives[counter].mHealthPercentage = READ_BYTE(); } } } else { int num_upgrades = READ_BYTE(); upgrades.clear(); for (int counter = 0; counter < num_upgrades; counter++) { AvHAlienUpgradeCategory theUpgradeCategory = AvHAlienUpgradeCategory(READ_BYTE()); upgrades.push_back(theUpgradeCategory); } } END_READ(); } #else void NetMsg_AlienInfo_Upgrades(entvars_t* const pev, const AvHAlienUpgradeListType& upgrades) { MESSAGE_BEGIN(MSG_ONE, g_msgAlienInfo, NULL, pev); WRITE_BYTE(0x80); //magic number for hive size field, upgrade info WRITE_BYTE(upgrades.size()); AvHAlienUpgradeListType::const_iterator current, end = upgrades.end(); for (current = upgrades.begin(); current != end; ++current) { WRITE_BYTE(*current); } MESSAGE_END(); } void NetMsg_AlienInfo_Hives(entvars_t* const pev, const HiveInfoListType& hives, const HiveInfoListType& client_hives) { if (pev == NULL) MESSAGE_BEGIN(MSG_SPEC, g_msgAlienInfo); else MESSAGE_BEGIN(MSG_ONE, g_msgAlienInfo, NULL, pev); WRITE_BYTE(hives.size()); HiveInfoListType::const_iterator current, end = hives.end(); int status, tech, index = 0; int change_flags = NO_CHANGE; for (current = hives.begin(); current != end; ++current, ++index) { //put together change bitfield if (client_hives.size() <= index || client_hives[index].mPosX != current->mPosX || client_hives[index].mPosY != current->mPosY || client_hives[index].mPosZ != current->mPosZ) { change_flags |= COORDS_CHANGED; } if (client_hives.size() <= index || client_hives[index].mStatus != current->mStatus || client_hives[index].mUnderAttack != current->mUnderAttack || client_hives[index].mTechnology != current->mTechnology) { change_flags |= STATUS_CHANGED; } if (client_hives.size() <= index || client_hives[index].mHealthPercentage != current->mHealthPercentage) { change_flags |= HEALTH_CHANGED; } WRITE_BYTE(change_flags); //send change data if (change_flags & COORDS_CHANGED) { WRITE_COORD(current->mPosX); WRITE_COORD(current->mPosY); WRITE_COORD(current->mPosZ); } if (change_flags & STATUS_CHANGED) { status = current->mStatus & 0x07; // 3 bits switch (current->mTechnology) // 2 bits { case MESSAGE_NULL: tech = 0; break; case ALIEN_BUILD_DEFENSE_CHAMBER: tech = 1; break; case ALIEN_BUILD_SENSORY_CHAMBER: tech = 2; break; case ALIEN_BUILD_MOVEMENT_CHAMBER: tech = 3; break; default: tech = 0; break; } status |= tech << 3; status |= current->mUnderAttack ? 0x80 : 0x00; // 1 bit WRITE_BYTE(status); } if (change_flags & HEALTH_CHANGED) { WRITE_BYTE(current->mHealthPercentage); } } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //TODO: sub rapid conversion as described in Game Programming Gems... union float_converter { float f; long l; }; #ifndef AVH_SERVER void NetMsg_BalanceVar(void* const buffer, const int size, string& name, BalanceMessageAction& action, int& ivalue, float& fvalue, string& svalue) { BEGIN_READ(buffer, size); action = static_cast(READ_BYTE()); switch (action) { case BALANCE_ACTION_INSERT_INT: { name = READ_STRING(); ivalue = READ_LONG(); break; } case BALANCE_ACTION_INSERT_FLOAT: { float_converter c; name = READ_STRING(); c.l = READ_LONG(); fvalue = c.f; break; } case BALANCE_ACTION_INSERT_STRING: { name = READ_STRING(); svalue = READ_STRING(); break; } case BALANCE_ACTION_REMOVE: { name = READ_STRING(); break; } case BALANCE_ACTION_CLEAR: case BALANCE_ACTION_NOTIFY_PENDING: case BALANCE_ACTION_NOTIFY_FINISHED: { break; } default: break; //todo: error condition here? } END_READ(); } #else void NetMsg_BalanceVarChangesPending(entvars_t* const pev, const bool pending) { MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(pending ? BALANCE_ACTION_NOTIFY_PENDING : BALANCE_ACTION_NOTIFY_FINISHED); MESSAGE_END(); } void NetMsg_BalanceVarInsertInt(entvars_t* const pev, const string& name, const int data) { MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(BALANCE_ACTION_INSERT_INT); WRITE_STRING(name.c_str()); WRITE_LONG(data); MESSAGE_END(); } void NetMsg_BalanceVarInsertFloat(entvars_t* const pev, const string& name, const float data) { float_converter c; c.f = data; MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(BALANCE_ACTION_INSERT_FLOAT); WRITE_STRING(name.c_str()); WRITE_LONG(c.l); MESSAGE_END(); } void NetMsg_BalanceVarInsertString(entvars_t* const pev, const string& name, const string& data) { MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(BALANCE_ACTION_INSERT_STRING); WRITE_STRING(name.c_str()); WRITE_STRING(data.c_str()); MESSAGE_END(); } void NetMsg_BalanceVarRemove(entvars_t* const pev, const string& name) { MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(BALANCE_ACTION_REMOVE); WRITE_STRING(name.c_str()); MESSAGE_END(); } void NetMsg_BalanceVarClear(entvars_t* const pev) { MESSAGE_BEGIN(MSG_ONE, g_msgBalanceVar, NULL, pev); WRITE_BYTE(BALANCE_ACTION_CLEAR); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_BlipList(void* const buffer, const int size, bool& friendly_blips, AvHVisibleBlipList& list) { int blip_count; int8 status, info; float X, Y, Z; list.Clear(); BEGIN_READ(buffer, size); int list_info = READ_BYTE(); friendly_blips = (list_info & 0x80) != 0; blip_count = (list_info & 0x7F); for (int counter = 0; counter < blip_count; counter++) { X = READ_COORD(); Y = READ_COORD(); Z = READ_COORD(); status = READ_BYTE(); info = friendly_blips ? READ_BYTE() : 0; list.AddBlip(X, Y, Z, status, info); } END_READ(); } #else void NetMsg_BlipList(entvars_t* const pev, const bool friendly_blips, const AvHVisibleBlipList& list) { int maxBlips = friendly_blips ? 20 : 25; maxBlips = min(list.mNumBlips, maxBlips); MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, g_msgBlipList, NULL, pev); //pack header - 7 bits for blip count (doesn't go over 40 in practice), 1 bit for Friend or Foe unsigned char list_info = maxBlips | (friendly_blips ? 0x80 : 0); WRITE_BYTE(list_info); //pack each blip - this could be optimized as follows once bit packer is implemented: // convert X, Y to integer values ranging from 0 to 2047 (11 bits each) based on map extents // convert Z to integer value ranging from 0 to 511 (9 bits) // 4 bits for status (range 0-15, 1-9 currently used) // 5 bits for info (range 1-32, refers to player number) // total is 40 bits = 5 bytes for friendly, 35 bits for foe. // savings would be 37.5% for friendly bytes. // blip precision would be equal to double large minimap precision, with worst case of 4 unit X,Y separation for MT. // because maps are much smaller vertically than horizontally as a rule, the worst case of 16 unit Z separation // will very rarely occur. for (int counter = 0; counter < maxBlips; counter++) { WRITE_COORD(list.mBlipPositions[counter][0]); WRITE_COORD(list.mBlipPositions[counter][1]); WRITE_COORD(list.mBlipPositions[counter][2]); WRITE_BYTE(list.mBlipStatus[counter]); if (friendly_blips) { WRITE_BYTE(list.mBlipInfo[counter]); } } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_BuildMiniMap(void* const buffer, const int size, string& name, int& num_samples, int& processed_samples, int& width, int& height, uint8** map, bool& finished) { BEGIN_READ(buffer, size); switch (READ_BYTE()) { case 0: name = READ_STRING(); num_samples = READ_LONG(); processed_samples = 0; width = READ_LONG(); height = READ_LONG(); *map = new uint8[num_samples]; finished = false; break; case 1: { int packet_samples = READ_BYTE(); for (int counter = 0; counter < packet_samples; counter++) { (*map)[processed_samples++] = READ_BYTE(); } finished = false; break; } case 2: finished = true; break; } END_READ(); } #else void NetMsg_BuildMiniMap_Initialize(entvars_t* const pev, const string& name, const int num_samples, const int width, const int height) { MESSAGE_BEGIN(MSG_ONE, g_msgBuildMiniMap, NULL, pev); WRITE_BYTE(0); WRITE_STRING(name.c_str()); WRITE_LONG(num_samples); WRITE_LONG(width); WRITE_LONG(height); MESSAGE_END(); } void NetMsg_BuildMiniMap_Update(entvars_t* const pev, const int num_samples, const uint8* const samples) { MESSAGE_BEGIN(MSG_ONE, g_msgBuildMiniMap, NULL, pev); WRITE_BYTE(1); WRITE_BYTE(num_samples); for (int counter = 0; counter < num_samples; counter++) { WRITE_BYTE(samples[counter]); } MESSAGE_END(); } void NetMsg_BuildMiniMap_Complete(entvars_t* const pev) { MESSAGE_BEGIN(MSG_ONE, g_msgBuildMiniMap, NULL, pev); WRITE_BYTE(2); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ClientScripts(void* const buffer, const int size, StringList& script_names) { script_names.clear(); BEGIN_READ(buffer, size); int num_scripts = READ_BYTE(); while (script_names.size() < num_scripts) { script_names.push_back(string(READ_STRING())); } END_READ(); } #else void NetMsg_ClientScripts(entvars_t* const pev, const StringList& script_names) { MESSAGE_BEGIN(MSG_ONE, g_msgClientScripts, NULL, pev); WRITE_BYTE(script_names.size()); StringList::const_iterator current, end = script_names.end(); for (current = script_names.begin(); current != end; ++current) { WRITE_STRING(current->c_str()); } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_DebugCSP(void* const buffer, const int size, weapon_data_t& weapon_data, float& next_attack) { BEGIN_READ(buffer, size); weapon_data.m_iId = READ_LONG(); weapon_data.m_iClip = READ_LONG(); weapon_data.m_flNextPrimaryAttack = READ_COORD(); weapon_data.m_flTimeWeaponIdle = READ_COORD(); next_attack = READ_COORD(); END_READ(); } #else void NetMsg_DebugCSP(entvars_t* const pev, const weapon_data_t& weapon_data, const float next_attack) { MESSAGE_BEGIN(MSG_ONE, g_msgDebugCSP, NULL, pev); WRITE_LONG(weapon_data.m_iId); WRITE_LONG(weapon_data.m_iClip); WRITE_COORD(weapon_data.m_flNextPrimaryAttack); WRITE_COORD(weapon_data.m_flTimeWeaponIdle); WRITE_COORD(next_attack); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_EditPS(void* const buffer, const int size, int& particle_index) { BEGIN_READ(buffer, size); particle_index = READ_SHORT(); END_READ(); } #else void NetMsg_EditPS(entvars_t* const pev, const int particle_index) { MESSAGE_BEGIN(MSG_ONE, g_msgEditPS, NULL, pev); WRITE_SHORT(particle_index); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_Fog(void* const buffer, const int size, bool& enabled, int& R, int& G, int& B, float& start, float& end) { BEGIN_READ(buffer, size); enabled = (READ_BYTE() != 0); if (enabled) { R = READ_BYTE(); G = READ_BYTE(); B = READ_BYTE(); start = READ_COORD(); end = READ_COORD(); } END_READ(); } #else void NetMsg_Fog(entvars_t* const pev, const bool enabled, const int R, const int G, const int B, const float start, const float end) { MESSAGE_BEGIN(MSG_ONE, g_msgFog, NULL, pev); WRITE_BYTE(enabled ? 1 : 0); if (enabled) { WRITE_BYTE(R); WRITE_BYTE(G); WRITE_BYTE(B); WRITE_COORD(start); WRITE_COORD(end); } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_GameStatus(void* const buffer, const int size, int& status_code, AvHMapMode& map_mode, int& game_time, int& timelimit, int& misc_data) { BEGIN_READ(buffer, size); status_code = READ_BYTE(); map_mode = (AvHMapMode)READ_BYTE(); switch (status_code) { case kGameStatusReset: case kGameStatusResetNewMap: case kGameStatusEnded: break; case kGameStatusGameTime: game_time = READ_SHORT(); timelimit = READ_SHORT(); misc_data = READ_BYTE(); break; case kGameStatusUnspentLevels: misc_data = READ_BYTE(); break; } END_READ(); } #else void NetMsg_GameStatus_State(const int status_code, const int map_mode) { MESSAGE_BEGIN(MSG_ALL, g_msgGameStatus); WRITE_BYTE(status_code); WRITE_BYTE(map_mode); MESSAGE_END(); } void NetMsg_GameStatus_State(entvars_t* const pev, const int status_code, const int map_mode) { MESSAGE_BEGIN(MSG_ONE, g_msgGameStatus, NULL, pev); WRITE_BYTE(status_code); WRITE_BYTE(map_mode); MESSAGE_END(); } void NetMsg_GameStatus_Time(const int status_code, const int map_mode, const int game_time, const int timelimit, const int attacking_team_number, const bool is_reliable) { int message_type = is_reliable ? MSG_ALL : MSG_BROADCAST; MESSAGE_BEGIN(message_type, g_msgGameStatus); WRITE_BYTE(status_code); WRITE_BYTE(map_mode); WRITE_SHORT(game_time); WRITE_SHORT(timelimit); WRITE_BYTE(attacking_team_number); MESSAGE_END(); } void NetMsg_GameStatus_UnspentLevels(entvars_t* const pev, const int status_code, const int map_mode, const int unspent_levels) { MESSAGE_BEGIN(MSG_ONE, g_msgGameStatus, NULL, pev); WRITE_BYTE(status_code); WRITE_BYTE(map_mode); WRITE_BYTE(unspent_levels); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ListPS(void* const buffer, const int size, string& system_name) { BEGIN_READ(buffer, size); system_name = READ_STRING(); END_READ(); } #else void NetMsg_ListPS(entvars_t* const pev, const string& system_name) { MESSAGE_BEGIN(MSG_ONE, g_msgListPS, NULL, pev); WRITE_STRING(system_name.c_str()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_HUDSetUpgrades(void* const buffer, const int size, int& upgradeMask) { BEGIN_READ(buffer, size); upgradeMask = READ_BYTE(); END_READ(); } #else void NetMsg_HUDSetUpgrades(int upgradeMask) { MESSAGE_BEGIN(MSG_ALL, g_msgHUDSetUpgrades); WRITE_BYTE(upgradeMask); MESSAGE_END(); } void NetMsg_HUDSetUpgrades(entvars_t* const pev, int upgradeMask) { MESSAGE_BEGIN(MSG_ONE, g_msgHUDSetUpgrades, NULL, pev); WRITE_BYTE(upgradeMask); MESSAGE_END(); } #endif #ifndef AVH_SERVER void NetMsg_PlayHUDNotification(void* const buffer, const int size, int& flags, int& sound, float& location_x, float& location_y) { BEGIN_READ(buffer, size); flags = READ_BYTE(); sound = READ_BYTE(); location_x = READ_COORD(); location_y = READ_COORD(); END_READ(); } #else void NetMsg_PlayHUDNotification(entvars_t* const pev, const int flags, const int sound, const float location_x, const float location_y) { MESSAGE_BEGIN(MSG_ONE, g_msgPlayHUDNotification, NULL, pev); WRITE_BYTE(flags); WRITE_BYTE(sound); WRITE_COORD(location_x); WRITE_COORD(location_y); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ProgressBar(void* const buffer, const int size, int& entity_number, int& progress, int& seconds) { BEGIN_READ(buffer, size); entity_number = READ_SHORT(); progress = READ_BYTE(); if (progress == 5) seconds = READ_BYTE(); END_READ(); } #else void NetMsg_ProgressBar(entvars_t* const pev, const int entity_number, const int progress, int seconds) { MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, g_msgProgressBar, NULL, pev); WRITE_SHORT(entity_number); WRITE_BYTE(progress); if (progress == 5) WRITE_BYTE(seconds); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_ServerVar(void* const buffer, const int size, string& name, int& value) { BEGIN_READ(buffer, size); name = READ_STRING(); value = READ_SHORT(); END_READ(); } #else void NetMsg_ServerVar(entvars_t* const pev, const string& name, const int& value) { MESSAGE_BEGIN(MSG_ONE, g_msgServerVar, NULL, pev); WRITE_STRING(name.c_str()); WRITE_SHORT(value); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetGammaRamp(void* const buffer, const int size, float& gamma) { BEGIN_READ(buffer, size); gamma = READ_BYTE() / 128.0f; END_READ(); } #else void NetMsg_SetGammaRamp(entvars_t* const pev, const float gamma) { MESSAGE_BEGIN(MSG_ONE, g_msgSetGammaRamp, NULL, pev); WRITE_BYTE(floor(min(max(gamma, 0.0f), 1.992f) * 128.0f)); MESSAGE_END(); } void NetMsgSpec_SetGammaRamp(const float gamma) { MESSAGE_BEGIN(MSG_SPEC, g_msgSetGammaRamp); WRITE_BYTE(floor(min(max(gamma, 0.0f), 1.992f) * 128.0f)); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetOrder(void* const buffer, const int size, AvHOrder& order) { EntityListType players; BEGIN_READ(buffer, size); order.SetReceiver(READ_BYTE()); order.SetOrderType((AvHOrderType)READ_BYTE()); //order.SetOrderTargetType((AvHOrderTargetType)READ_BYTE()); //this is a redundant byte because SetOrderType automatically sets the target type as well. switch (order.GetOrderTargetType()) { case ORDERTARGETTYPE_LOCATION: { vec3_t location; location.x = READ_COORD(); location.y = READ_COORD(); location.z = READ_COORD(); order.SetLocation(location); break; } case ORDERTARGETTYPE_TARGET: order.SetTargetIndex(READ_SHORT()); break; } order.SetUser3TargetType((AvHUser3)READ_BYTE()); order.SetOrderCompleted(READ_BYTE()); // : 1050 // Need to sync the order status as it is only manipulated by the serverside state machine order.SetOrderStatus(READ_BYTE()); END_READ(); } #else void NetMsg_SetOrder(entvars_t* const pev, const AvHOrder& order) { MESSAGE_BEGIN(MSG_ONE, g_msgSetOrder, NULL, pev); WRITE_BYTE(order.GetReceiver()); WRITE_BYTE(order.GetOrderType()); //WRITE_BYTE( order.GetOrderTargetType() ); //this is a redundant byte because SetOrderType automatically sets the target type as well. switch (order.GetOrderTargetType()) { case ORDERTARGETTYPE_LOCATION: { vec3_t location; order.GetLocation(location); WRITE_COORD(location.x); WRITE_COORD(location.y); WRITE_COORD(location.z); break; } case ORDERTARGETTYPE_TARGET: WRITE_SHORT(order.GetTargetIndex()); break; } WRITE_BYTE(order.GetTargetUser3Type()); WRITE_BYTE(order.GetOrderCompleted()); // : 1050 // Need to sync the order status as it is only manipulated by the serverside state machine WRITE_BYTE(order.GetOrderStatus()); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_DelParts(void* const buffer, const int size) { BEGIN_READ(buffer, size); READ_BYTE(); END_READ(); } void NetMsg_SetParticleTemplate(void* const buffer, const int size, int& index, AvHParticleTemplate& particle_template) { ParticleParams gen_params, vel_params; PSVector gravity; BEGIN_READ(buffer, size); index = READ_SHORT(); particle_template.SetName(string(READ_STRING())); particle_template.SetMaxParticles(READ_LONG()); particle_template.SetParticleSize(READ_COORD()); particle_template.SetSprite(string(READ_STRING())); particle_template.SetParticleSystemLifetime(READ_COORD()); particle_template.SetParticleLifetime(READ_COORD()); particle_template.SetAnimationSpeed(READ_COORD()); particle_template.SetNumSpriteFrames(READ_BYTE()); particle_template.SetParticleScaling(READ_COORD()); particle_template.SetRenderMode(READ_BYTE()); particle_template.SetGenerationRate(READ_LONG()); particle_template.SetGenerationShape(READ_BYTE()); for (int counter = 0; counter < 8; counter++) { gen_params[counter] = READ_LONG(); } particle_template.SetGenerationParams(gen_params); particle_template.SetGenerationEntityIndex(READ_LONG()); particle_template.SetGenerationEntityParameter(READ_COORD()); particle_template.SetStartingVelocityShape(READ_BYTE()); for (int counter = 0; counter < 8; counter++) { vel_params[counter] = READ_LONG(); } particle_template.SetStartingVelocityParams(vel_params); for (int counter = 0; counter < 3; counter++) { gravity[counter] = READ_COORD(); } particle_template.SetGravity(gravity); particle_template.SetMaxAlpha(READ_COORD()); particle_template.SetParticleSystemIndexToGenerate(READ_LONG()); particle_template.SetFlags(READ_LONG()); END_READ(); } #else void NetMsg_SetParticleTemplate(entvars_t* const pev, const int index, const AvHParticleTemplate& particle_template) { ParticleParams gen_params, vel_params; PSVector gravity; if (pev) MESSAGE_BEGIN(MSG_ONE, g_msgSetParticleTemplates, NULL, pev); else MESSAGE_BEGIN(MSG_SPEC, g_msgSetParticleTemplates); WRITE_SHORT(index); WRITE_STRING(particle_template.GetName().c_str()); WRITE_LONG(particle_template.GetMaxParticles()); WRITE_COORD(particle_template.GetParticleSize()); WRITE_STRING(particle_template.GetSprite().c_str()); WRITE_COORD(particle_template.GetParticleSystemLifetime()); WRITE_COORD(particle_template.GetParticleLifetime()); WRITE_COORD(particle_template.GetAnimationSpeed()); WRITE_BYTE(particle_template.GetNumSpriteFrames()); WRITE_COORD(particle_template.GetParticleScaling()); WRITE_BYTE(particle_template.GetRenderMode()); WRITE_LONG(particle_template.GetGenerationRate()); WRITE_BYTE(particle_template.GetGenerationShape()); particle_template.GetGenerationParams(gen_params); for (int counter = 0; counter < 8; counter++) { WRITE_LONG(gen_params[counter]); } WRITE_LONG(particle_template.GetGenerationEntityIndex()); WRITE_COORD(particle_template.GetGenerationEntityParameter()); WRITE_BYTE(particle_template.GetStartingVelocityShape()); particle_template.GetStartingVelocityParams(vel_params); for (int counter = 0; counter < 8; counter++) { WRITE_LONG(vel_params[counter]); } particle_template.GetGravity(gravity); for (int counter = 0; counter < 3; counter++) { WRITE_COORD(gravity[counter]); } WRITE_COORD(particle_template.GetMaxAlpha()); WRITE_LONG(particle_template.GetParticleSystemIndexToGenerate()); WRITE_LONG(particle_template.GetFlags()); MESSAGE_END(); } void NetMsg_DelParts(entvars_t* const pev) { if (pev) MESSAGE_BEGIN(MSG_ONE, g_msgDelParts, NULL, pev); else MESSAGE_BEGIN(MSG_SPEC, g_msgDelParts); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetSelect(void* const buffer, const int size, Selection& selection) { selection.selected_entities.clear(); BEGIN_READ(buffer, size); selection.group_number = READ_BYTE(); int num_entities = READ_BYTE(); for (int counter = 0; counter < num_entities; counter++) { selection.selected_entities.push_back(READ_SHORT()); } switch (selection.group_number) { case 0: selection.tracking_entity = (READ_BYTE() == 0) ? 0 : READ_SHORT(); break; case kSelectAllHotGroup: break; default: selection.group_type = (AvHUser3)READ_BYTE(); selection.group_alert = (AvHAlertType)READ_BYTE(); break; } END_READ(); } #else void NetMsg_SetSelect(entvars_t* const pev, Selection& selection) { MESSAGE_BEGIN(MSG_ONE, g_msgSetSelect, NULL, pev); WRITE_BYTE(selection.group_number); WRITE_BYTE(selection.selected_entities.size()); EntityListType::const_iterator current, end = selection.selected_entities.end(); for (current = selection.selected_entities.begin(); current != end; ++current) { WRITE_SHORT(*current); } switch (selection.group_number) { case 0: if (selection.tracking_entity != 0) { WRITE_BYTE(1); WRITE_SHORT(selection.tracking_entity); } else { WRITE_BYTE(0); } break; case kSelectAllHotGroup: break; default: WRITE_BYTE(selection.group_type); WRITE_BYTE(selection.group_alert); break; } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetRequest(void* const buffer, const int size, int& request_type, int& request_count) { BEGIN_READ(buffer, size); request_type = READ_BYTE(); request_count = READ_BYTE(); END_READ(); } #else void NetMsg_SetRequest(entvars_t* pev, const int request_type, const int request_count) { MESSAGE_BEGIN(MSG_ONE, g_msgSetRequest, NULL, pev); WRITE_BYTE(request_type); WRITE_BYTE(request_count); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetSoundNames(void* const buffer, const int size, bool& reset, string& sound_name) { BEGIN_READ(buffer, size); reset = (READ_BYTE() != 0) ? true : false; if (!reset) { sound_name = READ_STRING(); } END_READ(); } #else void NetMsg_SetSoundNames(entvars_t* pev, const bool reset, const string& sound_name) { MESSAGE_BEGIN(MSG_ONE, g_msgSetSoundNames, NULL, pev); WRITE_BYTE(reset ? 1 : 0); if (!reset) { WRITE_STRING(sound_name.c_str()); } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetTechNode(void* const buffer, const int size, AvHTechNode*& node) { BEGIN_READ(buffer, size); node = new AvHTechNode((AvHMessageID)READ_BYTE()); node->setTechID((AvHTechID)READ_BYTE()); node->setPrereqTechID1((AvHTechID)READ_BYTE()); node->setPrereqTechID2((AvHTechID)READ_BYTE()); node->setCost(READ_SHORT()); node->setBuildTime(READ_SHORT()); int flags = READ_BYTE(); node->setAllowMultiples((flags & 0x01) != 0); node->setResearchState((flags & 0x04) != 0); node->setResearchable((flags & 0x02) != 0); END_READ(); } #else void NetMsg_SetTechNode(entvars_t* pev, const AvHTechNode* node) { MESSAGE_BEGIN(MSG_ONE, g_msgSetTechNodes, NULL, pev); WRITE_BYTE(node->getMessageID()); WRITE_BYTE(node->getTechID()); WRITE_BYTE(node->getPrereqTechID1()); WRITE_BYTE(node->getPrereqTechID2()); WRITE_SHORT(node->getCost()); WRITE_SHORT(node->getBuildTime()); int flags = 0; if (node->getAllowMultiples()) { flags |= 0x01; } if (node->getIsResearchable()) { flags |= 0x02; } if (node->getIsResearched()) { flags |= 0x04; } WRITE_BYTE(flags); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetTechSlots(void* const buffer, const int size, AvHTechSlots& tech_slots) { BEGIN_READ(buffer, size); tech_slots.mUser3 = (AvHUser3)READ_BYTE(); for (int counter = 0; counter < kNumTechSlots; counter++) { tech_slots.mTechSlots[counter] = (AvHMessageID)READ_BYTE(); } END_READ(); } #else void NetMsg_SetTechSlots(entvars_t* pev, const AvHTechSlots& tech_slots) { MESSAGE_BEGIN(MSG_ONE, g_msgSetTechSlots, NULL, pev); WRITE_BYTE(tech_slots.mUser3); for (int counter = 0; counter < kNumTechSlots; counter++) { WRITE_BYTE(tech_slots.mTechSlots[counter]); } MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetTopDown(void* const buffer, const int size, bool& is_menu_tech, bool& is_top_down, float* position, int& tech_slots) { BEGIN_READ(buffer, size); is_menu_tech = (READ_BYTE() != 0); if (is_menu_tech) { tech_slots = READ_LONG(); } else { is_top_down = (READ_BYTE() != 0); position[0] = READ_COORD(); position[1] = READ_COORD(); position[2] = READ_COORD(); } END_READ(); } #else void NetMsg_SetTopDown_Position(entvars_t* const pev, const bool is_top_down, const float* const position) { MESSAGE_BEGIN(MSG_ONE, g_msgSetTopDown, NULL, pev); WRITE_BYTE(0); WRITE_BYTE(is_top_down ? 1 : 0); WRITE_COORD(position[0]); WRITE_COORD(position[1]); WRITE_COORD(position[2]); MESSAGE_END(); } void NetMsg_SetTopDown_TechSlots(entvars_t* const pev, const int tech_slots) { MESSAGE_BEGIN(MSG_ONE, g_msgSetTopDown, NULL, pev); WRITE_BYTE(1); WRITE_LONG(tech_slots); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_SetupMap(void* const buffer, const int size, bool& is_location, string& name, float* min_extents, float* max_extents, bool& draw_background) { BEGIN_READ(buffer, size); is_location = (READ_BYTE() != 0); name = READ_STRING(); if (is_location) { max_extents[0] = READ_COORD(); max_extents[1] = READ_COORD(); min_extents[0] = READ_COORD(); min_extents[1] = READ_COORD(); } else { min_extents[2] = READ_COORD(); max_extents[2] = READ_COORD(); min_extents[0] = READ_COORD(); min_extents[1] = READ_COORD(); max_extents[0] = READ_COORD(); max_extents[1] = READ_COORD(); draw_background = (READ_BYTE() != 0); } } #else void NetMsg_SetupMap_Extents(entvars_t* const pev, const string& name, const float* const min_extents, const float* const max_extents, const bool draw_background) { if (pev) MESSAGE_BEGIN(MSG_ONE, g_msgSetupMap, NULL, pev); else MESSAGE_BEGIN(MSG_SPEC, g_msgSetupMap); WRITE_BYTE(0); WRITE_STRING(name.c_str()); WRITE_COORD(min_extents[2]); WRITE_COORD(max_extents[2]); WRITE_COORD(min_extents[0]); WRITE_COORD(min_extents[1]); WRITE_COORD(max_extents[0]); WRITE_COORD(max_extents[1]); WRITE_BYTE(draw_background ? 1 : 0); MESSAGE_END(); } void NetMsg_SetupMap_Location(entvars_t* const pev, const string& name, const float* const min_extents, const float* const max_extents) { MESSAGE_BEGIN(MSG_ONE, g_msgSetupMap, NULL, pev); WRITE_BYTE(1); WRITE_STRING(name.c_str()); WRITE_COORD(max_extents[0]); WRITE_COORD(max_extents[1]); WRITE_COORD(min_extents[0]); WRITE_COORD(min_extents[1]); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #ifndef AVH_SERVER void NetMsg_UpdateCountdown(void* const buffer, const int size, int& countdown) { BEGIN_READ(buffer, size); countdown = READ_BYTE(); END_READ(); } #else void NetMsg_UpdateCountdown(const int countdown) { MESSAGE_BEGIN(MSG_ALL, g_msgUpdateCountdown); WRITE_BYTE(countdown); MESSAGE_END(); } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ const int kNumStatusBits = 6; const int kStatusMask = 0x3F; const int kNumTeamBits = 2; const int kTeamMask = 0x03; const int kNumPositionCoordinateBits = 12; const int kPositionCoordinateMask = 0xFFF; const int kPositionCoordinateOffset = 4096; const float kPositionCoordinateScale = 0.5f; const int kNumPositionBits = kNumPositionCoordinateBits * 2; const int kNumSquadBits = 3; const int kSquadMask = 0x07; const int kNumAngleBits = 4; const int kAngleMask = 0x0F; const int kNumPlayerIndexBits = 6; const int kPlayerIndexMask = 0x3F; const int kNumIndexBits = 14; const int kIndexMask = 0x3FFF; const int kNumFlagBits = 3; const int kFlagMask = 0x07; const int kEntHierFlagPlayer = 0x01; const int kEntHierFlagDeletion = 0x02; const int kEntHierFlagUnderAttack = 0x04; #ifndef AVH_SERVER //TODO : replace OldItems with vector void ReadEntHier(MapEntityMap& NewItems, EntityListType& OldItems, int short_data, int long_data); float UnpackageCoord(const int packaged_coord); void NetMsg_DelEntityHierarchy(void* const buffer, const int size) { BEGIN_READ(buffer, size); END_READ(); } void NetMsg_UpdateEntityHierarchy(void* const buffer, const int size, MapEntityMap& NewItems, EntityListType& OldItems) { NewItems.clear(); OldItems.clear(); int amnt_read = 0; int short_data, long_data = 0; BEGIN_READ(buffer, size); while (amnt_read < size) { short_data = READ_SHORT(); amnt_read += 2; if ((short_data & kEntHierFlagDeletion) == 0) { long_data = READ_LONG(); amnt_read += 4; } ReadEntHier(NewItems, OldItems, short_data, long_data); } END_READ(); } void ReadEntHier(MapEntityMap& NewItems, EntityListType& OldItems, int short_data, int long_data) { int flags = short_data & kFlagMask; short_data >>= kNumFlagBits; if ((flags & kEntHierFlagDeletion) == kEntHierFlagDeletion) // Deletion (player or otherwise) { OldItems.push_back(short_data & kIndexMask); return; } MapEntity ent; int index = 0; ent.mUnderAttack = ((flags & kEntHierFlagUnderAttack) == kEntHierFlagUnderAttack); ent.mUser3 = (AvHUser3)(long_data & kStatusMask); long_data >>= kNumStatusBits; ent.mTeam = (AvHTeamNumber)(long_data & kTeamMask); long_data >>= kNumTeamBits; ent.mY = UnpackageCoord(long_data & kPositionCoordinateMask); long_data >>= kNumPositionCoordinateBits; ent.mX = UnpackageCoord(long_data & kPositionCoordinateMask); if ((flags & kEntHierFlagPlayer) == kEntHierFlagPlayer) // Player added/changed { index = short_data & kPlayerIndexMask; short_data >>= kNumPlayerIndexBits; ent.mAngle = (short_data & kAngleMask) * 22.5f; short_data >>= kNumAngleBits; ent.mSquadNumber = short_data & kSquadMask; } else // Other item added/changed { index = short_data & kIndexMask; short_data >>= kNumIndexBits; ent.mSquadNumber = 0; ent.mAngle = 0; } NewItems.insert(MapEntityMap::value_type(index, ent)); } float UnpackageCoord(const int packaged_coord) { float returnVal = packaged_coord; returnVal /= kPositionCoordinateScale; returnVal -= kPositionCoordinateOffset; return returnVal; } #else void WriteEntHier(const int index, const MapEntity& ent, bool delete_flag, int& short_data, int& long_data); int PackageCoord(const float coord); void NetMsg_DelEntityHierarchy(entvars_t* const pev) { if (pev == NULL) { MESSAGE_BEGIN(MSG_SPEC, g_msgDelEntityHierarchy); } else { MESSAGE_BEGIN(MSG_ONE, g_msgDelEntityHierarchy, NULL, pev); } MESSAGE_END(); } void NetMsg_UpdateEntityHierarchy(entvars_t* const pev, const MapEntityMap& NewItems, const EntityListType& OldItems, bool specMsg) { const int kMaxUpdatesPerPacket = 30; if (NewItems.empty() && OldItems.empty()) { return; } //nothing to send! MapEntityMap::const_iterator new_current, new_end = NewItems.end(); MapEntity temp; EntityListType::const_iterator old_current, old_end = OldItems.end(); int short_data, long_data, count = 1; if (specMsg) { MESSAGE_BEGIN(MSG_SPEC, g_msgUpdateEntityHierarchy); } else { MESSAGE_BEGIN(MSG_ONE, g_msgUpdateEntityHierarchy, NULL, pev); } for (new_current = NewItems.begin(); new_current != new_end; ++new_current, ++count) { if (count % kMaxUpdatesPerPacket == 0) { MESSAGE_END(); if (specMsg) { MESSAGE_BEGIN(MSG_SPEC, g_msgUpdateEntityHierarchy); } else MESSAGE_BEGIN(MSG_ONE, g_msgUpdateEntityHierarchy, NULL, pev); } WriteEntHier(new_current->first, new_current->second, false, short_data, long_data); WRITE_SHORT(short_data); WRITE_LONG(long_data); } for (old_current = OldItems.begin(); old_current != old_end; ++old_current, ++count) { if (count % kMaxUpdatesPerPacket == 0) { MESSAGE_END(); if (specMsg) { MESSAGE_BEGIN(MSG_SPEC, g_msgUpdateEntityHierarchy); } else MESSAGE_BEGIN(MSG_ONE, g_msgUpdateEntityHierarchy, NULL, pev); } WriteEntHier(*old_current, temp, true, short_data, long_data); WRITE_SHORT(short_data); } MESSAGE_END(); } void WriteEntHier(const int index, const MapEntity& ent, bool delete_flag, int& short_data, int& long_data) { if (delete_flag) { ASSERT((index & ~kIndexMask) == 0); short_data = index; short_data <<= kNumFlagBits; ASSERT((short_data & kFlagMask) == 0); short_data |= kEntHierFlagDeletion; return; } long_data = PackageCoord(ent.mX); long_data <<= kNumPositionCoordinateBits; ASSERT((long_data & kPositionCoordinateMask) == 0); long_data |= PackageCoord(ent.mY); long_data <<= kNumTeamBits; ASSERT((long_data & kTeamMask) == 0); ASSERT((ent.mTeam & ~kTeamMask) == 0); long_data |= ent.mTeam & kTeamMask; long_data <<= kNumStatusBits; ASSERT((long_data & kStatusMask) == 0); ASSERT((ent.mUser3 & ~kStatusMask) == 0); long_data |= ent.mUser3 & kStatusMask; switch (ent.mUser3) { case AVH_USER3_MARINE_PLAYER: case AVH_USER3_COMMANDER_PLAYER: case AVH_USER3_ALIEN_PLAYER1: case AVH_USER3_ALIEN_PLAYER2: case AVH_USER3_ALIEN_PLAYER3: case AVH_USER3_ALIEN_PLAYER4: case AVH_USER3_ALIEN_PLAYER5: case AVH_USER3_ALIEN_EMBRYO: case AVH_USER3_HEAVY: { ASSERT((ent.mSquadNumber & ~kSquadMask) == 0); short_data = ent.mSquadNumber; short_data <<= kNumAngleBits; int angle = WrapFloat(ent.mAngle, 0, 360); angle /= 22.5f; ASSERT((short_data & kAngleMask) == 0); ASSERT((angle & ~kAngleMask) == 0); short_data |= angle & kAngleMask; short_data <<= kNumPlayerIndexBits; ASSERT((short_data & kPlayerIndexMask) == 0); ASSERT((index & ~kPlayerIndexMask) == 0); short_data |= index & kIndexMask; short_data <<= kNumFlagBits; ASSERT((short_data & kFlagMask) == 0); short_data |= kEntHierFlagPlayer; if (ent.mUnderAttack) short_data |= kEntHierFlagUnderAttack; break; } default: ASSERT((index & ~kIndexMask) == 0); short_data = index & kIndexMask; short_data <<= kNumFlagBits; ASSERT((short_data & kFlagMask) == 0); if (ent.mUnderAttack) { short_data |= kEntHierFlagUnderAttack; } } } int PackageCoord(const float coord) { float adjustedCoord = coord; adjustedCoord += kPositionCoordinateOffset; adjustedCoord *= kPositionCoordinateScale; int returnVal = adjustedCoord; ASSERT((returnVal & ~kPositionCoordinateMask) == 0); returnVal &= kPositionCoordinateMask; return returnVal; } #endif //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // : 0000971 #ifndef AVH_SERVER void NetMsg_IssueOrder(void* const buffer, const int size, int& ordertype, int& ordersource, int& ordertarget) { BEGIN_READ(buffer, size); ordertype = READ_BYTE(); ordersource = READ_LONG(); ordertarget = READ_LONG(); END_READ(); } #else void NetMsg_IssueOrder(entvars_t* const pev, const int ordertype, const int ordersource, const int ordertarget) { MESSAGE_BEGIN(MSG_ONE, g_msgIssueOrder, NULL, pev); WRITE_BYTE(ordertype); WRITE_LONG(ordersource); WRITE_LONG(ordertarget); MESSAGE_END(); } #endif // :