/* ================== CL_ParseClientdata Server information pertaining to this client only ================== */ void CL_ParseClientdata (int bits) { int i, j; if (bits & SU_VIEWHEIGHT) cl.viewheight = MSG_ReadChar (); if (bits & SU_IDEALPITCH) cl.idealpitch = MSG_ReadChar (); if (bits & SU_IDEALROLL) cl.idealroll = MSG_ReadChar (); VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); for (i=0 ; i<3 ; i++) { if (bits & (SU_PUNCH1<<i) ) cl.punchangle[i] = MSG_ReadChar(); if (bits & (SU_VELOCITY1<<i) ) cl.mvelocity[0][i] = MSG_ReadChar()*16; } if (cl.items != i) { // set flash times SB_Changed(); for (j=0 ; j<32 ; j++) if ( (i & (1<<j)) && !(cl.items & (1<<j))) cl.item_gettime[j] = cl.time; cl.items = i; } cl.onground = (bits & SU_ONGROUND) != 0; cl.inwater = (bits & SU_INWATER) != 0; if (bits & SU_WEAPONFRAME) cl.stats[STAT_WEAPONFRAME] = MSG_ReadByte (); if (bits & SU_ARMOR) { cl.stats[STAT_ARMOR] = MSG_ReadByte (); SB_Changed(); } if (bits & SU_WEAPON) { cl.stats[STAT_WEAPON] = MSG_ReadShort (); SB_Changed(); } }
/* ================== SCR_SetUpToDrawConsole ================== */ void SCR_SetUpToDrawConsole (void) { Con_CheckResize (); if (scr_drawloading) return; // never a console with loading plaque // decide on the height of the console con_forcedup = !cl.worldmodel || cls.signon != SIGNONS; if (con_forcedup) { scr_conlines = vid.height; // full screen scr_con_current = scr_conlines; } else if (key_dest == key_console) scr_conlines = vid.height/2; // half screen else scr_conlines = 0; // none visible if (scr_conlines < scr_con_current) { scr_con_current -= scr_conspeed.value*host_frametime; if (scr_conlines > scr_con_current) scr_con_current = scr_conlines; } else if (scr_conlines > scr_con_current) { scr_con_current += scr_conspeed.value*host_frametime; if (scr_conlines < scr_con_current) scr_con_current = scr_conlines; } if (clearconsole++ < vid.numpages) { scr_copytop = 1; Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current); SB_Changed(); } else if (clearnotify++ < vid.numpages) { scr_copytop = 1; Draw_TileClear (0,0,vid.width, con_notifylines); } else con_notifylines = 0; }
/* =============== SCR_BeginLoadingPlaque ================ */ void SCR_BeginLoadingPlaque (void) { S_StopAllSounds (true); if (cls.state != ca_connected) return; if (cls.signon != SIGNONS) return; // redraw with no console and the loading plaque Con_ClearNotify (); scr_centertime_off = 0; scr_con_current = 0; scr_drawloading = true; scr_fullupdate = 0; SB_Changed(); SCR_UpdateScreen (); scr_drawloading = false; scr_disabled_for_loading = true; scr_disabled_time = realtime; }
/* ================== SCR_UpdateScreen This is called every frame, and can also be called explicitly to flush text to the screen. WARNING: be very careful calling this from elsewhere, because the refresh needs almost the entire 256k of stack space! ================== */ void SCR_UpdateScreen (void) { static float oldscr_viewsize; static float oldlcd_x; vrect_t vrect; if (scr_skipupdate) return; scr_copytop = 0; scr_copyeverything = 0; if (scr_disabled_for_loading) { if (realtime - scr_disabled_time > 60) { scr_disabled_for_loading = false; total_loading_size = 0; loading_stage = 0; Con_Printf ("load failed.\n"); } else return; } if (cls.state == ca_dedicated) return; // stdout only if (!scr_initialized || !con_initialized) return; // not initialized yet if (scr_viewsize.value != oldscr_viewsize) { oldscr_viewsize = scr_viewsize.value; vid.recalc_refdef = 1; } // // check for vid changes // if (oldfov != scr_fov.value) { oldfov = scr_fov.value; vid.recalc_refdef = true; } if (oldlcd_x != lcd_x.value) { oldlcd_x = lcd_x.value; vid.recalc_refdef = true; } if (oldscreensize != scr_viewsize.value) { oldscreensize = scr_viewsize.value; vid.recalc_refdef = true; } if (vid.recalc_refdef) { // something changed, so reorder the screen SCR_CalcRefdef (); } // // do 3D refresh drawing, and then update the screen // D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly if (scr_needfull && (!plaquemessage || plaquemessage[0] == 0 || !SCR_CheckDrawCenterString2())) scr_fullupdate = 0; if (scr_fullupdate++ < vid.numpages) { // clear the entire screen scr_copyeverything = 1; Draw_TileClear (0,0,vid.width,vid.height); SB_Changed(); } else if (scr_topupdate++ < vid.numpages) { scr_copyeverything = 1; Draw_TileClear (0,0,vid.width,100); SB_Changed(); } pconupdate = NULL; SCR_SetUpToDrawConsole (); //SCR_EraseCenterString (); D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time if (cl.intermission < 1 || cl.intermission > 12) { VID_LockBuffer (); V_RenderView (); VID_UnlockBuffer (); } D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly if (scr_drawdialog) { SB_Draw(); Draw_FadeScreen (); SCR_DrawNotifyString (); scr_copyeverything = true; } else if (scr_drawloading) { SB_Draw(); Draw_FadeScreen (); SCR_DrawLoading (); } else if (cl.intermission >= 1 && cl.intermission <= 12) { SB_IntermissionOverlay(); if (cl.intermission < 12) { SCR_DrawConsole(); M_Draw(); } } /* else if (cl.intermission == 2 && key_dest == key_game) { SB_FinaleOverlay(); SCR_CheckDrawCenterString(); } else if (cl.intermission == 3 && key_dest == key_game) { SCR_CheckDrawCenterString (); }*/ else { SCR_DrawRam(); SCR_DrawNet(); SCR_DrawTurtle(); SCR_DrawPause(); SCR_CheckDrawCenterString(); SB_Draw(); Plaque_Draw(plaquemessage,0); SCR_DrawConsole(); M_Draw(); if (errormessage) Plaque_Draw(errormessage,1); if (info_up) { UpdateInfoMessage(); Info_Plaque_Draw(infomessage); } } if (loading_stage) SCR_DrawLoading(); D_DisableBackBufferAccess (); // for adapters that can't stay mapped in // for linear writes all the time if (pconupdate) { D_UpdateRects (pconupdate); } V_UpdatePalette (); // // update one of three areas // if (scr_copyeverything) { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; vrect.pnext = 0; VID_Update (&vrect); } else if (scr_copytop) { vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height - sb_lines; vrect.pnext = 0; VID_Update (&vrect); } else { vrect.x = scr_vrect.x; vrect.y = scr_vrect.y; vrect.width = scr_vrect.width; vrect.height = scr_vrect.height; vrect.pnext = 0; VID_Update (&vrect); } }
/* ================= SCR_CalcRefdef Must be called whenever vid changes Internal use only ================= */ static void SCR_CalcRefdef (void) { vrect_t vrect; float size; scr_fullupdate = 0; // force a background redraw vid.recalc_refdef = 0; // force the status bar to redraw SB_Changed(); //======================================== // bound viewsize if (scr_viewsize.value < 30) Cvar_Set ("viewsize","30"); if (scr_viewsize.value > 110) Cvar_Set ("viewsize","110"); // bound field of view if (scr_fov.value < 10) Cvar_Set ("fov","10"); if (scr_fov.value > 110) Cvar_Set ("fov","110"); // intermission is always full screen if (cl.intermission) size = 110; else size = scr_viewsize.value; /* if (size >= 120) sb_lines = 0; // no status bar at all else if (size >= 110) sb_lines = 24; // no inventory else sb_lines = 24+16+8; */ if(size >= 110) { // No status bar sb_lines = 0; } else { sb_lines = 46; } // these calculations mirror those in R_Init() for r_refdef, but take no // account of water warping vrect.x = 0; vrect.y = 0; vrect.width = vid.width; vrect.height = vid.height; R_SetVrect (&vrect, &scr_vrect, sb_lines); // guard against going from one mode to another that's less than half the // vertical resolution if (scr_con_current > vid.height) scr_con_current = vid.height; // notify the refresh of the change R_ViewChanged (&vrect, sb_lines, vid.aspect); }
/* ===================== CL_ParseServerMessage ===================== */ void CL_ParseServerMessage (void) { int cmd; int i,j,k; int EntityCount = 0; int EntitySize = 0; int before; static double lasttime; static qboolean packet_loss = false; entity_t *ent; short RemovePlace, OrigPlace, NewPlace, AddedIndex; int sc1, sc2; byte test; float compangles[2][3]; vec3_t deltaangles; // // if recording demos, copy the message out // if(net_message.cursize > LastServerMessageSize) { LastServerMessageSize = net_message.cursize; } if (cl_shownet.value == 1) { Con_Printf ("Time: %2.2f Pck: %i ",host_time-lasttime,net_message.cursize); lasttime = host_time; } else if (cl_shownet.value == 2) Con_Printf ("------------------\n"); cl.onground = false; // unless the server says otherwise // // parse the message // MSG_BeginReading (); while (1) { if (msg_badread) Host_Error ("CL_ParseServerMessage: Bad server message"); cmd = MSG_ReadByte (); if (cmd == -1) { if (cl_shownet.value == 1) Con_Printf ("Ent: %i (%i bytes)",EntityCount,EntitySize); SHOWNET("END OF MESSAGE"); return; // end of message } // if the high bit of the command byte is set, it is a fast update if (cmd & 128) { before = msg_readcount; SHOWNET("fast update"); if (packet_loss) CL_ParseUpdate2 (cmd&127); else CL_ParseUpdate (cmd&127); EntityCount++; EntitySize += msg_readcount - before + 1; continue; } SHOWNET(svc_strings[cmd]); // other commands switch (cmd) { default: Host_Error ("CL_ParseServerMessage: Illegible server message\n"); break; case svc_nop: // Con_Printf ("svc_nop\n"); break; case svc_time: cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = MSG_ReadFloat (); break; case svc_clientdata: i = MSG_ReadShort (); CL_ParseClientdata (i); break; case svc_version: i = MSG_ReadLong (); if (i != PROTOCOL_VERSION) Host_Error ("CL_ParseServerMessage: Server is protocol %i instead of %i\n", i, PROTOCOL_VERSION); break; case svc_disconnect: Host_EndGame ("Server disconnected\n"); case svc_print: if(intro_playing) MSG_ReadString (); else Con_Printf ("%s", MSG_ReadString ()); break; case svc_centerprint: //Bottom_Plaque_Draw(MSG_ReadString(),true); SCR_CenterPrint (MSG_ReadString ()); break; case svc_stufftext: Cbuf_AddText (MSG_ReadString ()); break; case svc_damage: V_ParseDamage (); break; case svc_serverinfo: CL_ParseServerInfo (); vid.recalc_refdef = true; // leave intermission full screen break; case svc_setangle: for (i=0 ; i<3 ; i++) cl.viewangles[i] = MSG_ReadAngle (); break; case svc_setangle_interpolate: compangles[0][0] = MSG_ReadAngle(); compangles[0][1] = MSG_ReadAngle(); compangles[0][2] = MSG_ReadAngle(); for (i=0 ; i<3 ; i++) { compangles[1][i] = cl.viewangles[i]; for (j=0 ; j<2 ; j++) {//standardize both old and new angles to +-180 if(compangles[j][i]>=360) compangles[j][i] -= 360*((int)(compangles[j][i]/360)); else if(compangles[j][i]<=360) compangles[j][i] += 360*(1+(int)(-compangles[j][i]/360)); if(compangles[j][i]>180) compangles[j][i]=-360 + compangles[j][i]; else if(compangles[j][i]<-180) compangles[j][i]=360 + compangles[j][i]; } //get delta deltaangles[i] = compangles[0][i] - compangles[1][i]; //cap delta to <=180,>=-180 if(deltaangles[i]>180) deltaangles[i]+=-360; else if(deltaangles[i]<-180) deltaangles[i]+=360; //add the delta cl.viewangles[i]+=(deltaangles[i]/8);//8 step interpolation //cap newangles to +-180 if(cl.viewangles[i]>=360) cl.viewangles[i] -= 360*((int)(cl.viewangles[i]/360)); else if(cl.viewangles[i]<=360) cl.viewangles[i] += 360*(1+(int)(-cl.viewangles[i]/360)); if(cl.viewangles[i]>180) cl.viewangles[i]+=-360; else if(cl.viewangles[i]<-180) cl.viewangles[i]+=360; } break; case svc_setview: cl.viewentity = MSG_ReadShort (); break; case svc_lightstyle: i = MSG_ReadByte (); if (i >= MAX_LIGHTSTYLES) Sys_Error ("svc_lightstyle > MAX_LIGHTSTYLES"); strcpy (cl_lightstyle[i].map, MSG_ReadString()); cl_lightstyle[i].length = strlen(cl_lightstyle[i].map); break; case svc_sound: CL_ParseStartSoundPacket(); break; case svc_sound_update_pos: {//FIXME: put a field on the entity that lists the channels //it should update when it moves- if a certain flag //is on the ent, this update_channels field could //be set automatically by each sound and stopSound //called for this ent? vec3_t pos; int channel, ent; channel = MSG_ReadShort (); ent = channel >> 3; channel &= 7; if (ent > MAX_EDICTS) Host_Error ("svc_sound_update_pos: ent = %i", ent); for (i=0 ; i<3 ; i++) pos[i] = MSG_ReadCoord (); S_UpdateSoundPos (ent, channel, pos); } break; case svc_stopsound: i = MSG_ReadShort(); S_StopSound(i>>3, i&7); break; case svc_updatename: SB_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); strcpy (cl.scores[i].name, MSG_ReadString ()); break; case svc_updateclass: SB_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updateclass > MAX_SCOREBOARD"); cl.scores[i].playerclass = (float)MSG_ReadByte(); CL_NewTranslation(i); // update the color break; case svc_updatefrags: SB_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); cl.scores[i].frags = MSG_ReadShort (); break; case svc_update_kingofhill: sv_kingofhill = MSG_ReadShort() - 1; break; case svc_updatecolors: SB_Changed(); i = MSG_ReadByte (); if (i >= cl.maxclients) Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); cl.scores[i].colors = MSG_ReadByte (); CL_NewTranslation (i); break; case svc_particle: R_ParseParticleEffect (); break; case svc_particle2: R_ParseParticleEffect2 (); break; case svc_particle3: R_ParseParticleEffect3 (); break; case svc_particle4: R_ParseParticleEffect4 (); break; case svc_spawnbaseline: i = MSG_ReadShort (); // must use CL_EntityNum() to force cl.num_entities up CL_ParseBaseline (CL_EntityNum(i)); break; case svc_spawnstatic: CL_ParseStatic (); break; case svc_raineffect: CL_ParseRainEffect(); break; case svc_temp_entity: CL_ParseTEnt (); break; case svc_setpause: { cl.paused = MSG_ReadByte (); if (cl.paused) { CDAudio_Pause (); #ifdef _WIN32 VID_HandlePause (true); #endif } else { CDAudio_Resume (); #ifdef _WIN32 VID_HandlePause (false); #endif } } break; case svc_signonnum: i = MSG_ReadByte (); if (i <= cls.signon) Host_Error ("Received signon %i when at %i", i, cls.signon); cls.signon = i; CL_SignonReply (); break; case svc_killedmonster: cl.stats[STAT_MONSTERS]++; break; case svc_foundsecret: cl.stats[STAT_SECRETS]++; break; case svc_updatestat: i = MSG_ReadByte (); if (i < 0 || i >= MAX_CL_STATS) Sys_Error ("svc_updatestat: %i is invalid", i); cl.stats[i] = MSG_ReadLong ();; break; case svc_spawnstaticsound: CL_ParseStaticSound (); break; case svc_cdtrack: cl.cdtrack = MSG_ReadByte (); cl.looptrack = MSG_ReadByte (); if (strcasecmp(bgmtype.string,"cd") == 0) { if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) CDAudio_Play ((byte)cls.forcetrack, true); else CDAudio_Play ((byte)cl.cdtrack, true); } else CDAudio_Stop(); break; case svc_midi_name: strcpy(cl.midi_name,MSG_ReadString ()); break; case svc_toggle_statbar: break; case svc_intermission: cl.intermission = MSG_ReadByte(); cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen if (oem.value && cl.intermission == 1) { cl.intermission = 9; } break; /* case svc_finale: cl.intermission = 2; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_cutscene: cl.intermission = 3; cl.completed_time = cl.time; vid.recalc_refdef = true; // go to full screen SCR_CenterPrint (MSG_ReadString ()); break; case svc_sellscreen: Cmd_ExecuteString ("help", src_command); break;*/ case svc_set_view_flags: cl.viewent.drawflags |= MSG_ReadByte(); break; case svc_clear_view_flags: cl.viewent.drawflags &= ~MSG_ReadByte(); break; case svc_start_effect: CL_ParseEffect(); break; case svc_end_effect: CL_EndEffect(); break; case svc_plaque: CL_Plaque(); break; case svc_particle_explosion: CL_ParticleExplosion(); break; case svc_set_view_tint: i = MSG_ReadByte(); cl.viewent.colorshade = i; break; case svc_reference: packet_loss = false; cl.last_frame = cl.current_frame; cl.last_sequence = cl.current_sequence; cl.current_frame = MSG_ReadByte(); cl.current_sequence = MSG_ReadByte(); if (cl.need_build == 2) { // Con_Printf("CL: NB2 CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); cl.frames[0].count = cl.frames[1].count = cl.frames[2].count = 0; cl.need_build = 1; cl.reference_frame = cl.current_frame; } else if (cl.last_sequence != cl.current_sequence) { // Con_Printf("CL: Sequence CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); if (cl.reference_frame >= 1 && cl.reference_frame <= MAX_FRAMES) { RemovePlace = OrigPlace = NewPlace = AddedIndex = 0; for(i=0;i<cl.num_entities;i++) { if (RemovePlace >= cl.NumToRemove || cl.RemoveList[RemovePlace] != i) { if (NewPlace < cl.frames[1].count && cl.frames[1].states[NewPlace].index == i) { cl.frames[2].states[AddedIndex] = cl.frames[1].states[NewPlace]; AddedIndex++; cl.frames[2].count++; } else if (OrigPlace < cl.frames[0].count && cl.frames[0].states[OrigPlace].index == i) { cl.frames[2].states[AddedIndex] = cl.frames[0].states[OrigPlace]; AddedIndex++; cl.frames[2].count++; } } else RemovePlace++; if (cl.frames[0].states[OrigPlace].index == i) OrigPlace++; if (cl.frames[1].states[NewPlace].index == i) NewPlace++; } cl.frames[0] = cl.frames[2]; } cl.frames[1].count = cl.frames[2].count = 0; cl.need_build = 1; cl.reference_frame = cl.current_frame; } else { // Con_Printf("CL: Normal CL(%d,%d) R(%d)\n", cl.current_sequence, cl.current_frame,cl.reference_frame); cl.need_build = 0; } for (i=1,ent=cl_entities+1 ; i<cl.num_entities ; i++,ent++) { ent->baseline.flags &= ~BE_ON; } for(i=0;i<cl.frames[0].count;i++) { ent = CL_EntityNum (cl.frames[0].states[i].index); ent->model = cl.model_precache[cl.frames[0].states[i].modelindex]; ent->baseline.flags |= BE_ON; } break; case svc_clear_edicts: j = MSG_ReadByte(); if (cl.need_build) { cl.NumToRemove = j; } for(i=0;i<j;i++) { k = MSG_ReadShort(); if (cl.need_build) cl.RemoveList[i] = k; ent = CL_EntityNum (k); ent->baseline.flags &= ~BE_ON; } break; case svc_update_inv: sc1 = sc2 = 0; test = MSG_ReadByte(); if (test & 1) sc1 |= ((int)MSG_ReadByte()); if (test & 2) sc1 |= ((int)MSG_ReadByte())<<8; if (test & 4) sc1 |= ((int)MSG_ReadByte())<<16; if (test & 8) sc1 |= ((int)MSG_ReadByte())<<24; if (test & 16) sc2 |= ((int)MSG_ReadByte()); if (test & 32) sc2 |= ((int)MSG_ReadByte())<<8; if (test & 64) sc2 |= ((int)MSG_ReadByte())<<16; if (test & 128) sc2 |= ((int)MSG_ReadByte())<<24; if (sc1 & SC1_HEALTH) cl.v.health = MSG_ReadShort(); if (sc1 & SC1_LEVEL) cl.v.level = MSG_ReadByte(); if (sc1 & SC1_INTELLIGENCE) cl.v.intelligence = MSG_ReadByte(); if (sc1 & SC1_WISDOM) cl.v.wisdom = MSG_ReadByte(); if (sc1 & SC1_STRENGTH) cl.v.strength = MSG_ReadByte(); if (sc1 & SC1_DEXTERITY) cl.v.dexterity = MSG_ReadByte(); if (sc1 & SC1_WEAPON) cl.v.weapon = MSG_ReadByte(); if (sc1 & SC1_BLUEMANA) cl.v.bluemana = MSG_ReadByte(); if (sc1 & SC1_GREENMANA) cl.v.greenmana = MSG_ReadByte(); if (sc1 & SC1_EXPERIENCE) cl.v.experience = MSG_ReadLong(); if (sc1 & SC1_CNT_TORCH) cl.v.cnt_torch = MSG_ReadByte(); if (sc1 & SC1_CNT_H_BOOST) cl.v.cnt_h_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_SH_BOOST) cl.v.cnt_sh_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_MANA_BOOST) cl.v.cnt_mana_boost = MSG_ReadByte(); if (sc1 & SC1_CNT_TELEPORT) cl.v.cnt_teleport = MSG_ReadByte(); if (sc1 & SC1_CNT_TOME) cl.v.cnt_tome = MSG_ReadByte(); if (sc1 & SC1_CNT_SUMMON) cl.v.cnt_summon = MSG_ReadByte(); if (sc1 & SC1_CNT_INVISIBILITY) cl.v.cnt_invisibility = MSG_ReadByte(); if (sc1 & SC1_CNT_GLYPH) cl.v.cnt_glyph = MSG_ReadByte(); if (sc1 & SC1_CNT_HASTE) cl.v.cnt_haste = MSG_ReadByte(); if (sc1 & SC1_CNT_BLAST) cl.v.cnt_blast = MSG_ReadByte(); if (sc1 & SC1_CNT_POLYMORPH) cl.v.cnt_polymorph = MSG_ReadByte(); if (sc1 & SC1_CNT_FLIGHT) cl.v.cnt_flight = MSG_ReadByte(); if (sc1 & SC1_CNT_CUBEOFFORCE) cl.v.cnt_cubeofforce = MSG_ReadByte(); if (sc1 & SC1_CNT_INVINCIBILITY) cl.v.cnt_invincibility = MSG_ReadByte(); if (sc1 & SC1_ARTIFACT_ACTIVE) cl.v.artifact_active = MSG_ReadFloat(); if (sc1 & SC1_ARTIFACT_LOW) cl.v.artifact_low = MSG_ReadFloat(); if (sc1 & SC1_MOVETYPE) cl.v.movetype = MSG_ReadByte(); if (sc1 & SC1_CAMERAMODE) cl.v.cameramode = MSG_ReadByte(); if (sc1 & SC1_HASTED) cl.v.hasted = MSG_ReadFloat(); if (sc1 & SC1_INVENTORY) cl.v.inventory = MSG_ReadByte(); if (sc1 & SC1_RINGS_ACTIVE) cl.v.rings_active = MSG_ReadFloat(); if (sc2 & SC2_RINGS_LOW) cl.v.rings_low = MSG_ReadFloat(); if (sc2 & SC2_AMULET) cl.v.armor_amulet = MSG_ReadByte(); if (sc2 & SC2_BRACER) cl.v.armor_bracer = MSG_ReadByte(); if (sc2 & SC2_BREASTPLATE) cl.v.armor_breastplate = MSG_ReadByte(); if (sc2 & SC2_HELMET) cl.v.armor_helmet = MSG_ReadByte(); if (sc2 & SC2_FLIGHT_T) cl.v.ring_flight = MSG_ReadByte(); if (sc2 & SC2_WATER_T) cl.v.ring_water = MSG_ReadByte(); if (sc2 & SC2_TURNING_T) cl.v.ring_turning = MSG_ReadByte(); if (sc2 & SC2_REGEN_T) cl.v.ring_regeneration = MSG_ReadByte(); if (sc2 & SC2_HASTE_T) cl.v.haste_time = MSG_ReadFloat(); if (sc2 & SC2_TOME_T) cl.v.tome_time = MSG_ReadFloat(); if (sc2 & SC2_PUZZLE1) sprintf(cl.puzzle_pieces[0], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE2) sprintf(cl.puzzle_pieces[1], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE3) sprintf(cl.puzzle_pieces[2], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE4) sprintf(cl.puzzle_pieces[3], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE5) sprintf(cl.puzzle_pieces[4], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE6) sprintf(cl.puzzle_pieces[5], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE7) sprintf(cl.puzzle_pieces[6], "%.9s", MSG_ReadString()); if (sc2 & SC2_PUZZLE8) sprintf(cl.puzzle_pieces[7], "%.9s", MSG_ReadString()); if (sc2 & SC2_MAXHEALTH) cl.v.max_health = MSG_ReadShort(); if (sc2 & SC2_MAXMANA) cl.v.max_mana = MSG_ReadByte(); if (sc2 & SC2_FLAGS) cl.v.flags = MSG_ReadFloat(); if (sc2 & SC2_OBJ) cl.info_mask = MSG_ReadLong(); if (sc2 & SC2_OBJ2) cl.info_mask2 = MSG_ReadLong(); if ((sc1 & SC1_STAT_BAR) || (sc2 & SC2_STAT_BAR)) SB_Changed(); if ((sc1 & SC1_INV) || (sc2 & SC2_INV)) SB_InvChanged(); break; } } }