//-------------------------------------------------------------------------- //--- ViewPreProcess //-------------------------------------------------------------------------- // Fetch all the data we need to work on. //-------------------------------------------------------------------------- void CPlayerView::ViewPreProcess(const CPlayer &rPlayer,SViewParams &viewParams,SViewStateIn &m_in) { // SViewStateIn --- the constants { m_in.lastPos=viewParams.position; m_in.lastQuat=viewParams.rotation; m_in.defaultFov= g_pGameCVars->cl_fov; m_in.frameTime=min(gEnv->pTimer->GetFrameTime(),0.1f); m_in.pCharacter = rPlayer.GetEntity()->GetCharacter(0); m_in.pVehicle=rPlayer.GetLinkedVehicle(); m_in.bIsGrabbing=false; /*if (rPlayer.m_grabStats.grabId>0) { m_in.bIsGrabbing=true; // ***** viewParams.nearplane = 0.1f; // ***** }*/ m_in.stats_isRagDoll=rPlayer.m_stats.isRagDoll; m_in.stats_isStandingUp=rPlayer.m_stats.isStandingUp; m_in.stats_isFrozen=rPlayer.m_stats.isFrozen.Value(); m_in.stats_isShattered=rPlayer.m_stats.isShattered.Value(); m_in.stats_followCharacterHead=rPlayer.m_stats.followCharacterHead.Value(); m_in.stats_flatSpeed=rPlayer.m_stats.speedFlat; m_in.stats_leanAmount=rPlayer.m_stats.leanAmount; m_in.stats_inAir=rPlayer.m_stats.inAir; m_in.stats_inWater=rPlayer.m_stats.inWaterTimer; m_in.stats_headUnderWater = (rPlayer.m_stats.headUnderWaterTimer > 0.0f); m_io.stats_jumped=rPlayer.m_stats.jumped; m_in.stats_firstPersonBody=rPlayer.m_stats.firstPersonBody.Value(); m_in.stats_onGround=rPlayer.m_stats.onGround; m_io.stats_landed=rPlayer.m_stats.landed; m_in.stats_velocity=rPlayer.m_stats.velocity; m_in.bSprinting=rPlayer.m_stats.bSprinting; m_io.stats_inFreefall=rPlayer.m_stats.inFreefall.Value(); m_in.stats_onLadder=rPlayer.m_stats.isOnLadder; m_in.bLookingAtFriendlyAI = rPlayer.m_stats.bLookingAtFriendlyAI; m_in.bIsGrabbed = rPlayer.m_stats.isGrabbed; m_in.params_viewFoVScale=rPlayer.m_params.viewFoVScale; m_in.params_viewPivot=rPlayer.m_params.viewPivot; m_in.params_viewDistance=rPlayer.m_params.viewDistance; m_in.params_weaponInertiaMultiplier=rPlayer.m_params.weaponInertiaMultiplier; m_in.params_hudAngleOffset=rPlayer.m_params.hudAngleOffset; m_in.params_hudOffset=rPlayer.m_params.hudOffset; m_in.params_viewHeightOffset=rPlayer.m_params.viewHeightOffset; m_in.params_weaponBobbingMultiplier=rPlayer.m_params.weaponBobbingMultiplier; m_io.bobMul=g_pGameCVars->cl_bob * m_in.params_weaponBobbingMultiplier; m_in.bIsThirdPerson=rPlayer.IsThirdPerson(); m_in.vEntityWorldPos=rPlayer.GetEntity()->GetWorldPos(); m_in.entityId=rPlayer.GetEntityId(); // use absolute entity matrix when frozen if (rPlayer.m_stats.isFrozen.Value()) m_in.entityWorldMatrix=Matrix34(rPlayer.GetEntity()->GetWorldTM()); else m_in.entityWorldMatrix=Matrix34(rPlayer.GetEntity()->GetSlotWorldTM(0)); m_in.localEyePos=rPlayer.GetLocalEyePos(); m_in.worldEyePos=m_in.entityWorldMatrix*m_in.localEyePos; m_in.headMtxLocal.SetIdentity(); if (m_in.stats_followCharacterHead) { int16 joint_id = rPlayer.GetBoneID(BONE_HEAD); if (joint_id>=0) m_in.headMtxLocal=Matrix33(m_in.pCharacter->GetISkeletonPose()->GetAbsJointByID(joint_id).q.GetNormalized()); } m_in.thirdPersonDistance=g_pGameCVars->cl_tpvDist; m_in.thirdPersonYaw=g_pGameCVars->cl_tpvYaw; EStance refStance((rPlayer.m_stance==STANCE_PRONE)?STANCE_PRONE:STANCE_STAND); m_in.stand_MaxSpeed=rPlayer.GetStanceInfo(refStance)->maxSpeed; m_in.standSpeed=rPlayer.GetStanceMaxSpeed(refStance); m_in.health=rPlayer.GetHealth(); m_in.stance=rPlayer.m_stance; m_in.shake= g_pGameCVars->cl_sprintShake; m_in.deathTime = rPlayer.GetDeathTime(); } // SViewStateInOut -- temporaries and output { //--- temporaries - FirstThird shared //m_io.bUsePivot //m_io.bobMul //m_io.viewQuatForWeapon //m_io.eyeOffsetGoal //--- temporaries - view shared m_io.wAngles=Ang3(0,0,0); //--- I/O //m_io.m_lastPos=rPlayer.m_lastPos; // Integ //if (m_io.m_lastPos.len2()>0.01f) //{ // m_io.blendViewOffset = m_io.m_lastPos - rPlayer.GetEntity()->GetWorldPos(); // m_io.m_lastPos.Set(0,0,0); //} } // ***** viewParams.fov = m_in.defaultFov*rPlayer.m_params.viewFoVScale*(gf_PI/180.0f); viewParams.nearplane = 0.0f; // ***** m_io.eyeOffsetViewGoal=rPlayer.GetStanceViewOffset(rPlayer.m_stance); m_io.viewQuatFinal=rPlayer.m_viewQuatFinal; m_io.viewQuat=rPlayer.m_viewQuat; m_io.stats_FPWeaponAngles=rPlayer.m_stats.FPWeaponAngles; m_io.stats_FPWeaponPos=rPlayer.m_stats.FPWeaponPos; m_io.vFPWeaponOffset=rPlayer.m_FPWeaponOffset; m_io.stats_FPSecWeaponAngles=rPlayer.m_stats.FPSecWeaponAngles; m_io.stats_FPSecWeaponPos=rPlayer.m_stats.FPSecWeaponPos; //m_io.viewShake=rPlayer.m_viewShake; m_io.eyeOffsetView=rPlayer.m_eyeOffsetView; m_io.baseQuat=rPlayer.m_baseQuat; m_io.vFPWeaponAngleOffset=rPlayer.m_FPWeaponAngleOffset; m_io.stats_bobCycle=rPlayer.m_stats.bobCycle; m_io.vFPWeaponLastDirVec=rPlayer.m_FPWeaponLastDirVec; m_io.bobOffset=rPlayer.m_bobOffset; m_io.angleOffset=rPlayer.m_angleOffset; m_io.viewAngleOffset = rPlayer.m_viewAnglesOffset; m_in.stats_flyMode=rPlayer.m_stats.flyMode; m_in.stats_spectatorMode=rPlayer.m_stats.spectatorMode; m_in.stats_spectatorTarget=rPlayer.m_stats.spectatorTarget; m_io.stats_smoothViewZ=rPlayer.m_stats.smoothViewZ; m_io.stats_smoothZType=rPlayer.m_stats.smoothZType; //-- Any individual PreProcess handlers should be called here }
void CMelee::StartFire() { if (!CanFire()) return; //Prevent fists melee exploit if ((m_pWeapon->GetEntity()->GetClass() == CItem::sFistsClass) && m_pWeapon->IsBusy()) return; CActor* pOwner = m_pWeapon->GetOwnerActor(); if(pOwner) { if(pOwner->GetStance()==STANCE_PRONE) return; if(SPlayerStats* stats = static_cast<SPlayerStats*>(pOwner->GetActorStats())) { if(stats->bLookingAtFriendlyAI) return; } } m_attacking = true; m_attacked = false; m_pWeapon->RequireUpdate(eIUS_FireMode); m_pWeapon->ExitZoom(); bool isClient = pOwner?pOwner->IsClient():false; if (g_pGameCVars->bt_end_melee && isClient) g_pGame->GetBulletTime()->Activate(false); float speedOverride = -1.0f; if(CActor* pOwner = m_pWeapon->GetOwnerActor()) { CPlayer *pPlayer = (CPlayer *)pOwner; if(CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode == NANOMODE_SPEED && pSuit->GetSuitEnergy() > NANOSUIT_ENERGY * 0.1f) speedOverride = 1.5f; } pPlayer->PlaySound(CPlayer::ESound_Melee); } m_pWeapon->PlayAction(m_meleeactions.attack.c_str(), 0, false, CItem::eIPAF_Default|CItem::eIPAF_CleanBlending, speedOverride); m_pWeapon->SetBusy(true); m_beginPos = m_pWeapon->GetSlotHelperPos(CItem::eIGS_FirstPerson, m_meleeparams.helper.c_str(), true); m_pWeapon->GetScheduler()->TimerAction(m_pWeapon->GetCurrentAnimationTime(CItem::eIGS_FirstPerson), CSchedulerAction<StopAttackingAction>::Create(this), true); m_delayTimer = m_meleeparams.delay; if (g_pGameCVars->dt_enable && m_delayTimer < g_pGameCVars->dt_time) m_delayTimer = g_pGameCVars->dt_time; m_durationTimer = m_meleeparams.duration; m_pWeapon->OnMelee(m_pWeapon->GetOwnerId()); m_pWeapon->RequestStartMeleeAttack(m_pWeapon->GetMeleeFireMode()==this); }
//------------------------------------------------------------------------ void CMelee::Impulse(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float impulseScale) { if(m_noImpulse) { m_noImpulse = false; return; } if (pCollider && m_meleeparams.impulse>0.001f) { bool strengthMode = false; CPlayer *pPlayer = (CPlayer *)m_pWeapon->GetOwnerActor(); if(pPlayer) { if (CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode == NANOMODE_STRENGTH) strengthMode = true; } } pe_status_dynamics dyn; if (!pCollider->GetStatus(&dyn)) { if(strengthMode) impulseScale *= 3.0f; } else impulseScale *= clamp((dyn.mass * 0.01f), 1.0f, 15.0f); //[kirill] add impulse to phys proxy - to make sure it's applied to cylinder as well (not only skeleton) - so that entity gets pushed // if no pEntity - do it old way IEntity * pEntity = (IEntity*) pCollider->GetForeignData(PHYS_FOREIGN_ID_ENTITY); if(gEnv->bMultiplayer && pEntity) { if(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()) == NULL) impulseScale *= 0.33f; } if(pEntity) { { IEntityPhysicalProxy* pPhysicsProxy = (IEntityPhysicalProxy*)pEntity->GetProxy(ENTITY_PROXY_PHYSICS); CActor* pActor = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()); if (pActor) { SActorStats* pAS = pActor->GetActorStats(); if (pAS && pAS->isRagDoll) { //marcok: talk to me before touching this impulseScale = 1.0f; //jan: melee impulses were scaled down, I made sure it still "barely moves" } } // scale impulse up a bit for player pPhysicsProxy->AddImpulse(partId, pt, dir*m_meleeparams.impulse*impulseScale*m_meleeScale, true, 1.f); } } else { pe_action_impulse ai; ai.partid = partId; ai.ipart = ipart; ai.point = pt; ai.iApplyTime = 0; ai.impulse = dir*(m_meleeparams.impulse*impulseScale*m_meleeScale); pCollider->Action(&ai); } ISurfaceTypeManager *pSurfaceTypeManager = gEnv->p3DEngine->GetMaterialManager()->GetSurfaceTypeManager(); int invId = pSurfaceTypeManager->GetSurfaceTypeByName("mat_invulnerable")->GetId(); // create a physical collision to break trees pe_action_register_coll_event collision; collision.collMass = 0.005f; // this is actually ignored collision.partid[1] = partId; // collisions involving partId<-1 are to be ignored by game's damage calculations // usually created articially to make stuff break. collision.partid[0] = -2; collision.idmat[1] = surfaceIdx; collision.idmat[0] = invId; collision.n = normal; collision.pt = pt; // scar bullet // m = 0.0125 // v = 800 // energy: 4000 // in this case the mass of the active collider is a player part // so we must solve for v given the same energy as a scar bullet Vec3 v = dir; float speed = cry_sqrtf(4000.0f/(80.0f*0.5f)); // 80.0f is the mass of the player // [marco] Check if an object. Should take lots of time to break stuff if not in nanosuit strength mode; // and still creates a very low impulse for stuff that might depend on receiving an impulse. IRenderNode *pBrush = (IRenderNode*)pCollider->GetForeignData(PHYS_FOREIGN_ID_STATIC); if (pBrush) { CActor *pActor = m_pWeapon->GetOwnerActor(); if (pActor && (pActor->GetActorClass() == CPlayer::GetActorClassType())) { CPlayer *pPlayer = (CPlayer *)pActor; if (CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode != NANOMODE_STRENGTH) speed =0.003f; } } } collision.vSelf = (v.normalized()*speed*m_meleeScale); collision.v = Vec3(0,0,0); collision.pCollider = pCollider; IEntity *pOwner = m_pWeapon->GetOwner(); if (pOwner && pOwner->GetCharacter(0) && pOwner->GetCharacter(0)->GetISkeletonPose()->GetCharacterPhysics()) { if (ISkeletonPose *pSkeletonPose=pOwner->GetCharacter(0)->GetISkeletonPose()) { if (pSkeletonPose && pSkeletonPose->GetCharacterPhysics()) pSkeletonPose->GetCharacterPhysics()->Action(&collision); } } } }
void CGameContext::OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId) { void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgId, pUnpacker); CPlayer *p = m_apPlayers[ClientId]; if(!pRawMsg) { dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", m_NetObjHandler.GetMsgName(MsgId), MsgId, m_NetObjHandler.FailedMsgOn()); return; } if(MsgId == NETMSGTYPE_CL_SAY) { CNetMsg_Cl_Say *pMsg = (CNetMsg_Cl_Say *)pRawMsg; int Team = pMsg->m_Team; if(Team) Team = p->GetTeam(); else Team = CGameContext::CHAT_ALL; if(g_Config.m_SvSpamprotection && p->m_Last_Chat && p->m_Last_Chat+Server()->TickSpeed() > Server()->Tick()) return; p->m_Last_Chat = Server()->Tick(); // check for invalid chars unsigned char *pMessage = (unsigned char *)pMsg->m_pMessage; while (*pMessage) { if(*pMessage < 32) *pMessage = ' '; pMessage++; } SendChat(ClientId, Team, pMsg->m_pMessage); } else if(MsgId == NETMSGTYPE_CL_CALLVOTE) { if(g_Config.m_SvSpamprotection && p->m_Last_VoteTry && p->m_Last_VoteTry+Server()->TickSpeed()*3 > Server()->Tick()) return; int64 Now = Server()->Tick(); p->m_Last_VoteTry = Now; if(m_VoteCloseTime) { SendChatTarget(ClientId, "Wait for current vote to end before calling a new one."); return; } int Timeleft = p->m_Last_VoteCall + Server()->TickSpeed()*60 - Now; if(p->m_Last_VoteCall && Timeleft > 0) { char aChatmsg[512] = {0}; str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d seconds before making another vote", (Timeleft/Server()->TickSpeed())+1); SendChatTarget(ClientId, aChatmsg); return; } char aChatmsg[512] = {0}; char aDesc[512] = {0}; char aCmd[512] = {0}; CNetMsg_Cl_CallVote *pMsg = (CNetMsg_Cl_CallVote *)pRawMsg; if(str_comp_nocase(pMsg->m_Type, "option") == 0) { CVoteOption *pOption = m_pVoteOptionFirst; while(pOption) { if(str_comp_nocase(pMsg->m_Value, pOption->m_aCommand) == 0) { str_format(aChatmsg, sizeof(aChatmsg), "%s called vote to change server option '%s'", Server()->ClientName(ClientId), pOption->m_aCommand); str_format(aDesc, sizeof(aDesc), "%s", pOption->m_aCommand); str_format(aCmd, sizeof(aCmd), "%s", pOption->m_aCommand); break; } pOption = pOption->m_pNext; } if(!pOption) { str_format(aChatmsg, sizeof(aChatmsg), "'%s' isn't an option on this server", pMsg->m_Value); SendChatTarget(ClientId, aChatmsg); return; } } else if(str_comp_nocase(pMsg->m_Type, "kick") == 0) { if(!g_Config.m_SvVoteKick) { SendChatTarget(ClientId, "Server does not allow voting to kick players"); return; } int KickId = str_toint(pMsg->m_Value); if(KickId < 0 || KickId >= MAX_CLIENTS || !m_apPlayers[KickId]) { SendChatTarget(ClientId, "Invalid client id to kick"); return; } str_format(aChatmsg, sizeof(aChatmsg), "%s called for vote to kick '%s'", Server()->ClientName(ClientId), Server()->ClientName(KickId)); str_format(aDesc, sizeof(aDesc), "Kick '%s'", Server()->ClientName(KickId)); if (!g_Config.m_SvVoteKickBantime) str_format(aCmd, sizeof(aCmd), "kick %d", KickId); else { char aBuf[64] = {0}; Server()->GetClientIP(KickId, aBuf, sizeof(aBuf)); str_format(aCmd, sizeof(aCmd), "ban %s %d", aBuf, g_Config.m_SvVoteKickBantime); } } if(aCmd[0]) { SendChat(-1, CGameContext::CHAT_ALL, aChatmsg); StartVote(aDesc, aCmd); p->m_Vote = 1; p->m_VotePos = m_VotePos = 1; m_VoteCreator = ClientId; p->m_Last_VoteCall = Now; } } else if(MsgId == NETMSGTYPE_CL_VOTE) { if(!m_VoteCloseTime) return; if(p->m_Vote == 0) { CNetMsg_Cl_Vote *pMsg = (CNetMsg_Cl_Vote *)pRawMsg; if(!pMsg->m_Vote) return; p->m_Vote = pMsg->m_Vote; p->m_VotePos = ++m_VotePos; m_VoteUpdate = true; } } else if (MsgId == NETMSGTYPE_CL_SETTEAM && !m_World.m_Paused) { CNetMsg_Cl_SetTeam *pMsg = (CNetMsg_Cl_SetTeam *)pRawMsg; if(p->GetTeam() == pMsg->m_Team || (g_Config.m_SvSpamprotection && p->m_Last_SetTeam && p->m_Last_SetTeam+Server()->TickSpeed()*3 > Server()->Tick())) return; // Switch team on given client and kill/respawn him if(m_pController->CanJoinTeam(pMsg->m_Team, ClientId)) { if(m_pController->CanChangeTeam(p, pMsg->m_Team)) { p->m_Last_SetTeam = Server()->Tick(); if(p->GetTeam() == -1 || pMsg->m_Team == -1) m_VoteUpdate = true; p->SetTeam(pMsg->m_Team); (void)m_pController->CheckTeamBalance(); } else SendBroadcast("Teams must be balanced, please join other team", ClientId); } else { char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Only %d active players are allowed", g_Config.m_SvMaxClients-g_Config.m_SvSpectatorSlots); SendBroadcast(aBuf, ClientId); } } else if (MsgId == NETMSGTYPE_CL_CHANGEINFO || MsgId == NETMSGTYPE_CL_STARTINFO) { CNetMsg_Cl_ChangeInfo *pMsg = (CNetMsg_Cl_ChangeInfo *)pRawMsg; if(g_Config.m_SvSpamprotection && p->m_Last_ChangeInfo && p->m_Last_ChangeInfo+Server()->TickSpeed()*5 > Server()->Tick()) return; p->m_Last_ChangeInfo = Server()->Tick(); p->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; p->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; p->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; // check for invalid chars unsigned char *pName = (unsigned char *)pMsg->m_pName; while (*pName) { if(*pName < 32) *pName = ' '; pName++; } // copy old name char aOldName[MAX_NAME_LENGTH]; str_copy(aOldName, Server()->ClientName(ClientId), MAX_NAME_LENGTH); Server()->SetClientName(ClientId, pMsg->m_pName); if(MsgId == NETMSGTYPE_CL_CHANGEINFO && str_comp(aOldName, Server()->ClientName(ClientId)) != 0) { char aChatText[256]; str_format(aChatText, sizeof(aChatText), "%s changed name to %s", aOldName, Server()->ClientName(ClientId)); SendChat(-1, CGameContext::CHAT_ALL, aChatText); } // set skin str_copy(p->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(p->m_TeeInfos.m_SkinName)); m_pController->OnPlayerInfoChange(p); if(MsgId == NETMSGTYPE_CL_STARTINFO) { // send vote options CNetMsg_Sv_VoteClearOptions ClearMsg; Server()->SendPackMsg(&ClearMsg, MSGFLAG_VITAL, ClientId); CVoteOption *pCurrent = m_pVoteOptionFirst; while(pCurrent) { CNetMsg_Sv_VoteOption OptionMsg; OptionMsg.m_pCommand = pCurrent->m_aCommand; Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, ClientId); pCurrent = pCurrent->m_pNext; } // send tuning parameters to client SendTuningParams(ClientId); // CNetMsg_Sv_ReadyToEnter m; Server()->SendPackMsg(&m, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientId); } } else if (MsgId == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused) { CNetMsg_Cl_Emoticon *pMsg = (CNetMsg_Cl_Emoticon *)pRawMsg; if(g_Config.m_SvSpamprotection && p->m_Last_Emote && p->m_Last_Emote+Server()->TickSpeed()*3 > Server()->Tick()) return; p->m_Last_Emote = Server()->Tick(); SendEmoticon(ClientId, pMsg->m_Emoticon); } else if (MsgId == NETMSGTYPE_CL_KILL && !m_World.m_Paused) { if(p->m_Last_Kill && p->m_Last_Kill+Server()->TickSpeed()*3 > Server()->Tick()) return; p->m_Last_Kill = Server()->Tick(); p->KillCharacter(WEAPON_SELF); p->m_RespawnTick = Server()->Tick()+Server()->TickSpeed()*3; } }
// Put this player in other players nearlist, if errm... the player is near, enough void CPlayer::UpdateOthersNearList ( void ) { m_llNearListUpdateTime = GetTickCount64_ (); // Get the two positions to check const CVector& vecPlayerPosition = GetPosition (); CVector vecCameraPosition; GetCamera ()->GetPosition ( vecCameraPosition ); // Fill resultNearBoth with rough list of nearby players CElementResult resultNearBoth; { // Calculate distance from player to his camera. (Note as spatial database is 2D, we can use the 2D distance here) const float fCameraDistance = DistanceBetweenPoints2D ( vecCameraPosition, vecPlayerPosition ); if ( fCameraDistance < 40.f ) { // // If player near his camera (which is the usual case), we can do optimized things // // Do one query with a slightly bigger sphere const CVector vecAvgPos = ( vecCameraPosition + vecPlayerPosition ) * 0.5f; GetSpatialDatabase()->SphereQuery ( resultNearBoth, CSphere ( vecAvgPos, DISTANCE_FOR_SLOW_SYNCRATE + fCameraDistance * 0.5f ) ); } else { // // Bit more complicated if camera is not near player // // Perform queries on spatial database CElementResult resultNearCamera; GetSpatialDatabase()->SphereQuery ( resultNearCamera, CSphere ( vecCameraPosition, DISTANCE_FOR_SLOW_SYNCRATE ) ); CElementResult resultNearPlayer; GetSpatialDatabase()->SphereQuery ( resultNearPlayer, CSphere ( vecPlayerPosition, DISTANCE_FOR_SLOW_SYNCRATE ) ); std::set < CPlayer* > mergedList; // Merge for ( CElementResult::const_iterator it = resultNearCamera.begin () ; it != resultNearCamera.end (); ++it ) if ( (*it)->GetType () == CElement::PLAYER ) mergedList.insert ( (CPlayer*)*it ); for ( CElementResult::const_iterator it = resultNearPlayer.begin () ; it != resultNearPlayer.end (); ++it ) if ( (*it)->GetType () == CElement::PLAYER ) mergedList.insert ( (CPlayer*)*it ); // Copy to resultNearBoth for ( std::set < CPlayer* > ::iterator it = mergedList.begin (); it != mergedList.end (); ++it ) resultNearBoth.push_back ( *it ); } } // Accurately check distance to other players, and put this player in their near list for ( CElementResult::const_iterator it = resultNearBoth.begin () ; it != resultNearBoth.end (); ++it ) { if ( (*it)->GetType () == CElement::PLAYER ) { CPlayer* pOtherPlayer = (CPlayer*)*it; if ( pOtherPlayer != this ) { const CVector& vecOtherPlayerPos = pOtherPlayer->GetPosition (); // Check distance is accurate if ( ( vecPlayerPosition - vecOtherPlayerPos ).LengthSquared () < DISTANCE_FOR_SLOW_SYNCRATE * DISTANCE_FOR_SLOW_SYNCRATE || ( vecCameraPosition - vecOtherPlayerPos ).LengthSquared () < DISTANCE_FOR_SLOW_SYNCRATE * DISTANCE_FOR_SLOW_SYNCRATE ) { // Check dimension matches if ( m_usDimension == pOtherPlayer->GetDimension () ) pOtherPlayer->RefreshNearPlayer ( this ); } } } } }
bool CLightsyncPacket::Write ( NetBitStreamInterface& BitStream ) const { bool bSyncPosition; if ( Count() == 0 ) return false; for ( std::vector<CPlayer *>::const_iterator iter = m_players.begin (); iter != m_players.end(); ++iter ) { CPlayer* pPlayer = *iter; CPlayer::SLightweightSyncData& data = pPlayer->GetLightweightSyncData (); CVehicle* pVehicle = pPlayer->GetOccupiedVehicle (); // Find the difference between now and the time the position last changed for the player long long llTicksDifference = GetTickCount64_ ( ) - pPlayer->GetPositionLastChanged ( ); // Right we need to sync the position if there is no vehicle or he's in a vehicle and the difference between setPosition is less than or equal to the slow sync rate // i.e. make sure his position has been updated more than 0.001f in the last 1500ms plus a small margin for error (probably not needed). // This will ensure we only send positions when the position has changed. bSyncPosition = ( !pVehicle || pPlayer->GetOccupiedVehicleSeat () == 0 ) && llTicksDifference <= SLOW_SYNCRATE + 100; BitStream.Write ( pPlayer->GetID () ); BitStream.Write ( (unsigned char)pPlayer->GetSyncTimeContext () ); unsigned short usLatency = pPlayer->GetPing (); BitStream.WriteCompressed ( usLatency ); BitStream.WriteBit ( data.health.bSync ); if ( data.health.bSync ) { SPlayerHealthSync health; health.data.fValue = pPlayer->GetHealth (); BitStream.Write ( &health ); SPlayerArmorSync armor; armor.data.fValue = pPlayer->GetArmor (); BitStream.Write ( &armor ); } BitStream.WriteBit ( bSyncPosition ); if ( bSyncPosition ) { SLowPrecisionPositionSync pos; pos.data.vecPosition = pPlayer->GetPosition (); BitStream.Write ( &pos ); bool bSyncVehicleHealth = data.vehicleHealth.bSync && pVehicle; BitStream.WriteBit ( bSyncVehicleHealth ); if ( bSyncVehicleHealth ) { SLowPrecisionVehicleHealthSync health; health.data.fValue = pVehicle->GetHealth (); BitStream.Write ( &health ); } } } return true; }
bool CPlayerPuresyncPacket::Read ( NetBitStreamInterface& BitStream ) { if ( m_pSourceElement ) { CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement ); // Read out the time context unsigned char ucTimeContext = 0; if ( !BitStream.Read ( ucTimeContext ) ) return false; // Only read this packet if it matches the current time context that // player is in. if ( !pSourcePlayer->CanUpdateSync ( ucTimeContext ) ) { return false; } // Read out keys CControllerState ControllerState; ReadFullKeysync ( ControllerState, BitStream ); pSourcePlayer->GetPad ()->NewControllerState ( ControllerState ); // Read the flags SPlayerPuresyncFlags flags; if ( !BitStream.Read ( &flags ) ) return false; pSourcePlayer->SetInWater ( flags.data.bIsInWater ); pSourcePlayer->SetOnGround ( flags.data.bIsOnGround ); pSourcePlayer->SetHasJetPack ( flags.data.bHasJetPack ); pSourcePlayer->SetDucked ( flags.data.bIsDucked ); pSourcePlayer->SetWearingGoggles ( flags.data.bWearsGoogles ); pSourcePlayer->SetChoking ( flags.data.bIsChoking ); pSourcePlayer->SetAkimboArmUp ( flags.data.bAkimboTargetUp ); pSourcePlayer->SetOnFire ( flags.data.bIsOnFire ); pSourcePlayer->SetStealthAiming ( flags.data.bStealthAiming ); // Contact element CElement* pContactElement = NULL; if ( flags.data.bHasContact ) { ElementID Temp; if ( !BitStream.Read ( Temp ) ) return false; pContactElement = CElementIDs::GetElement ( Temp ); } CElement * pPreviousContactElement = pSourcePlayer->GetContactElement (); pSourcePlayer->SetContactElement ( pContactElement ); if ( pPreviousContactElement != pContactElement ) { // Call our onPlayerContact event CLuaArguments Arguments; if ( pPreviousContactElement ) Arguments.PushElement ( pPreviousContactElement ); else Arguments.PushNil (); if ( pContactElement ) Arguments.PushElement ( pContactElement ); else Arguments.PushNil (); pSourcePlayer->CallEvent ( "onPlayerContact", Arguments ); } // Player position SPositionSync position ( false ); if ( !BitStream.Read ( &position ) ) return false; if ( pContactElement ) { pSourcePlayer->SetContactPosition ( position.data.vecPosition ); // Get the true position CVector vecTempPos = pContactElement->GetPosition (); position.data.vecPosition += vecTempPos; } pSourcePlayer->SetPosition ( position.data.vecPosition ); // Player rotation SPedRotationSync rotation; if ( !BitStream.Read ( &rotation ) ) return false; pSourcePlayer->SetRotation ( rotation.data.fRotation ); // Move speed vector if ( flags.data.bSyncingVelocity ) { SVelocitySync velocity; if ( !BitStream.Read ( &velocity ) ) return false; pSourcePlayer->SetVelocity ( velocity.data.vecVelocity ); } // Health ( stored with damage ) SPlayerHealthSync health; if ( !BitStream.Read ( &health ) ) return false; float fHealth = health.data.fValue; // Armor SPlayerArmorSync armor; if ( !BitStream.Read ( &armor ) ) return false; float fArmor = armor.data.fValue; float fOldArmor = pSourcePlayer->GetArmor (); float fArmorLoss = fOldArmor - fArmor; pSourcePlayer->SetArmor ( fArmor ); // Read out and set the camera rotation float fCameraRotation; if ( !BitStream.Read ( fCameraRotation ) ) return false; pSourcePlayer->SetCameraRotation ( fCameraRotation ); // Read the camera orientation CVector vecCamPosition, vecCamFwd; ReadCameraOrientation ( position.data.vecPosition, BitStream, vecCamPosition, vecCamFwd ); pSourcePlayer->SetCameraOrientation ( vecCamPosition, vecCamFwd ); if ( flags.data.bHasAWeapon ) { // Read client weapon data, but only apply it if the weapon matches with the server uchar ucUseWeaponType = pSourcePlayer->GetWeaponType (); bool bWeaponCorrect = true; // Check client has the weapon we think he has unsigned char ucClientWeaponType; if ( !BitStream.Read ( ucClientWeaponType ) ) return false; if ( pSourcePlayer->GetWeaponType () != ucClientWeaponType ) { bWeaponCorrect = false; // Possibly old weapon data. ucUseWeaponType = ucClientWeaponType; // Use the packet supplied weapon type to skip over the correct amount of data } // Update check counts pSourcePlayer->SetWeaponCorrect ( bWeaponCorrect ); // Current weapon slot SWeaponSlotSync slot; if ( !BitStream.Read ( &slot ) ) return false; unsigned int uiSlot = slot.data.uiSlot; // Set weapon slot if ( bWeaponCorrect ) pSourcePlayer->SetWeaponSlot ( uiSlot ); if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) ) { // Read out the ammo states SWeaponAmmoSync ammo ( ucUseWeaponType, true, true ); if ( !BitStream.Read ( &ammo ) ) return false; eWeaponType eWeapon = static_cast < eWeaponType > ( pSourcePlayer->GetWeaponType ( uiSlot ) ); float fSkill = pSourcePlayer->GetPlayerStat ( CWeaponStatManager::GetSkillStatIndex ( eWeapon ) ); float fWeaponRange = g_pGame->GetWeaponStatManager ( )->GetWeaponRangeFromSkillLevel ( eWeapon, fSkill ); // Read out the aim data SWeaponAimSync sync ( fWeaponRange, ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) ); if ( !BitStream.Read ( &sync ) ) return false; if ( bWeaponCorrect ) { // Set the ammo states pSourcePlayer->SetWeaponAmmoInClip ( ammo.data.usAmmoInClip ); pSourcePlayer->SetWeaponTotalAmmo ( ammo.data.usTotalAmmo ); // Set the arm directions and whether or not arms are up pSourcePlayer->SetAimDirection ( sync.data.fArm ); // Read the aim data only if he's shooting or aiming if ( sync.isFull() ) { pSourcePlayer->SetSniperSourceVector ( sync.data.vecOrigin ); pSourcePlayer->SetTargettingVector ( sync.data.vecTarget ); } } } else { if ( bWeaponCorrect ) { pSourcePlayer->SetWeaponAmmoInClip ( 1 ); pSourcePlayer->SetWeaponTotalAmmo ( 1 ); } } } else { pSourcePlayer->SetWeaponSlot ( 0 ); pSourcePlayer->SetWeaponAmmoInClip ( 1 ); pSourcePlayer->SetWeaponTotalAmmo ( 1 ); } // Read out damage info if changed if ( BitStream.ReadBit () == true ) { ElementID DamagerID; if ( !BitStream.Read ( DamagerID ) ) return false; SWeaponTypeSync weaponType; if ( !BitStream.Read ( &weaponType ) ) return false; SBodypartSync bodyPart; if ( !BitStream.Read ( &bodyPart ) ) return false; pSourcePlayer->SetDamageInfo ( DamagerID, weaponType.data.ucWeaponType, bodyPart.data.uiBodypart ); } // If we know the player's dead, make sure the health we send on is 0 if ( pSourcePlayer->IsDead () ) fHealth = 0.0f; float fOldHealth = pSourcePlayer->GetHealth (); float fHealthLoss = fOldHealth - fHealth; pSourcePlayer->SetHealth ( fHealth ); // Less than last packet's frame? if ( fHealthLoss > 0 || fArmorLoss > 0 ) { float fDamage = 0.0f; if ( fHealthLoss > 0 ) fDamage += fHealthLoss; if ( fArmorLoss > 0 ) fDamage += fArmorLoss; // Call the onPlayerDamage event CLuaArguments Arguments; CElement* pKillerElement = CElementIDs::GetElement ( pSourcePlayer->GetPlayerAttacker () ); if ( pKillerElement ) Arguments.PushElement ( pKillerElement ); else Arguments.PushNil (); Arguments.PushNumber ( pSourcePlayer->GetAttackWeapon () ); Arguments.PushNumber ( pSourcePlayer->GetAttackBodyPart () ); Arguments.PushNumber ( fDamage ); pSourcePlayer->CallEvent ( "onPlayerDamage", Arguments ); } // Success return true; } return false; }
void PlayerDeadState::Enter(BaseType::EntityType *entity, const AITransition &tran) { CPlayer *player = static_cast<CPlayer*>(entity->GetOwner()); player->OnDied(); }
//------------------------------------------------------------------------ int CScriptBind_Item::OnUsed(IFunctionHandler *pH, ScriptHandle userId) { CItem *pItem = GetItem(pH); if (!pItem) return pH->EndFunction(); CActor *pActor = GetActor((EntityId)userId.n); if (!pActor) return pH->EndFunction(); if (pItem->CanUse((EntityId)userId.n)) { if(IEntity* pParent = pItem->GetEntity()->GetParent()) { IVehicle* pVehicle = gEnv->pGame->GetIGameFramework()->GetIVehicleSystem()->GetVehicle(pParent->GetId()); if(pVehicle) { CPlayer* pPlayer = static_cast<CPlayer*>(pActor); IInteractor* pInteractor = pPlayer->GetInteractor(); return pH->EndFunction( pVehicle->OnUsed((EntityId)userId.n, pInteractor->GetOverSlotIdx()) ); } } pActor->UseItem(pItem->GetEntityId()); return pH->EndFunction(true); } else if (pItem->CanPickUp((EntityId)userId.n)) { //Should be always the client... if (pActor->IsClient()) { CPlayer* pClientPlayer = static_cast<CPlayer*>(pActor); const SInteractionInfo& interactionInfo = pClientPlayer->GetCurrentInteractionInfo(); bool expectedItem = (interactionInfo.interactiveEntityId == pItem->GetEntityId()); bool expectedInteraction = (interactionInfo.interactionType == eInteraction_PickupItem) || (interactionInfo.interactionType == eInteraction_ExchangeItem); if (!expectedItem || !expectedInteraction) { return pH->EndFunction(); } if (interactionInfo.interactionType == eInteraction_ExchangeItem) { IItemSystem* pItemSystem = g_pGame->GetIGameFramework()->GetIItemSystem(); CItem* pCurrentItem = static_cast<CItem*>(pActor->GetCurrentItem()); CItem* pExchangeItem = static_cast<CItem*>(pItemSystem->GetItem(interactionInfo.swapEntityId)); if (pExchangeItem && pCurrentItem) pExchangeItem->ScheduleExchangeToNextItem(pActor, pItem, pCurrentItem); } else { pActor->PickUpItem(pItem->GetEntityId(), true, true); } } else { pActor->PickUpItem(pItem->GetEntityId(), true, true); } return pH->EndFunction(true); } return pH->EndFunction(); }
void CStatusPlayPlanPage::Update() { // return if not all inits are complete if ((!m_bInitialized) || (pDOC == NULL)) return; if (!theApp.IsGameInProgress()) { m_strDeclarer = "None"; UpdateData(FALSE); return; } // clear existing items m_listPlayPlan.DeleteAllItems(); // get the declarer & his play engine int nDeclarer = pDOC->GetDeclarerPosition(); if (!ISPLAYER(nDeclarer)) return; CPlayer* pPlayer = pDOC->GetDeclarer(); CDeclarerPlayEngine* pPlayEngine = pPlayer->GetDeclarerEngine(); CPlayList& playPlan = pPlayEngine->GetPlayPlan(); // list declarer m_strDeclarer.Format("%s", PositionToString(pPlayer->GetPosition())); // & number of available plays int nCount = playPlan.GetSize(); m_strNumPlays.Format("%d",nCount); // also list the current play const CPlay* pPlay = pPlayEngine->GetCurrentPlay(); CString strFailedPlay = pPlayEngine->GetFailedPlayName(); if (pPlay) m_strCurrentPlay = (const_cast<CPlay*>(pPlay))->GetDescription(); else if (!strFailedPlay.IsEmpty()) m_strCurrentPlay = strFailedPlay; else m_strCurrentPlay = "None"; // now list the plays for(int i=0;i<nCount;i++) { CPlay* pPlay = playPlan[i]; // set number m_listPlayPlan.InsertItem(i, FormString(i+1)); // set name m_listPlayPlan.SetItem(i, 1, LVIF_TEXT, pPlay->GetPlayTypeName(), 0, 0, 0, 0L); // add description m_listPlayPlan.SetItem(i, 2, LVIF_TEXT, pPlay->GetDescription(), 0, 0, 0, 0L); // add winner coded int nProspect = pPlay->GetPlayProspect(); m_listPlayPlan.SetItem(i, 3, LVIF_TEXT, szProspectDescription[nProspect], 0, 0, 0, 0L); // add consumed card CCard* pConsumedCard = pPlay->GetConsumedCard(); m_listPlayPlan.SetItem(i, 4, LVIF_TEXT, (pConsumedCard? pConsumedCard->GetName() : ""), 0, 0, 0, 0L); // add target card CCard* pTargetCard = pPlay->GetTargetCard(); m_listPlayPlan.SetItem(i, 5, LVIF_TEXT, (pTargetCard? pTargetCard->GetName() : ""), 0, 0, 0, 0L); // add key cards CCardList* pKeyCards = pPlay->GetKeyCardsList(); m_listPlayPlan.SetItem(i, 6, LVIF_TEXT, (pKeyCards? pKeyCards->GetHoldingsString() : ""), 0, 0, 0, 0L); // add OR-Key cards CCardList* pORKeyCards = pPlay->GetOrKeyCardsList(); m_listPlayPlan.SetItem(i, 7, LVIF_TEXT, (pORKeyCards? pORKeyCards->GetHoldingsString() : ""), 0, 0, 0, 0L); // add OR-Key cards 2 CCardList* pORKeyCards2 = pPlay->GetOrKeyCardsList2(); m_listPlayPlan.SetItem(i, 8, LVIF_TEXT, (pORKeyCards2? pORKeyCards2->GetHoldingsString() : ""), 0, 0, 0, 0L); // add opponents' key cards CCardList* pOppKeyCards = pPlay->GetEnemyKeyCardsList(); m_listPlayPlan.SetItem(i, 9, LVIF_TEXT, (pOppKeyCards? pOppKeyCards->GetHoldingsString() : ""), 0, 0, 0, 0L); // add opponents' OR-Key cards CCardList* pOppORKeyCards = pPlay->GetEnemyOrKeyCardsList(); m_listPlayPlan.SetItem(i, 10, LVIF_TEXT, (pOppORKeyCards? pOppORKeyCards->GetHoldingsString() : ""), 0, 0, 0, 0L); // add required played cards CCardList* pReqPlayedCards = pPlay->GetRequiredPlayedCardsList(); m_listPlayPlan.SetItem(i, 11, LVIF_TEXT, (pReqPlayedCards? pReqPlayedCards->GetHoldingsString() : ""), 0, 0, 0, 0L); } // done UpdateData(FALSE); m_nPrevTooltipIndex = -1; }
void CBaseState::exitCurrentState(CPlayer& player, CBaseState* newState) { if (player.getState() != nullptr) { delete player.getState(); player.setState(newState); } }
void CStatusPlayPlanPage::UpdateToolTipText(CPoint point) { /* * code for standard tooltip control * // get the declarer & his play engine if (!theApp.IsGameInProgress()) return; CPlayer* pPlayer = pDOC->GetDeclarer(); CDeclarerPlayEngine* pPlayEngine = pPlayer->GetDeclarerEngine(); CPlayList& playPlan = pPlayEngine->GetPlayPlan(); // get number of available plays int nCount = playPlan.GetSize(); if (nCount == 0) { m_toolTip.UpdateTipText("", &m_listPlayPlan); return; } // get the index of the play under the cursor int nIndex = -1; int nFirstVisible = m_listPlayPlan.GetTopIndex(); int numVisible = m_listPlayPlan.GetCountPerPage(); for(int i=nFirstVisible;i<nFirstVisible+numVisible;i++) { CRect rect; if (m_listPlayPlan.GetItemRect(i, &rect, LVIR_BOUNDS)) { if (rect.PtInRect(point)) { nIndex = i; break; } } } // update text if ((nIndex >= 0) && (nIndex < nCount)) { if (nIndex != m_nPrevTooltipIndex) { CPlay* pPlay = playPlan[nIndex]; m_toolTip.UpdateTipText(pPlay->GetFullDescription(), &m_listPlayPlan); m_nPrevTooltipIndex = nIndex; } } else { m_toolTip.UpdateTipText("", &m_listPlayPlan); } */ // // new code // if (!m_bInitialized) return; // get client position CPoint clientPoint = point; m_listPlayPlan.ScreenToClient(&clientPoint); // get the declarer & his play engine if (!theApp.IsGameInProgress()) return; CPlayer* pPlayer = pDOC->GetDeclarer(); CDeclarerPlayEngine* pPlayEngine = pPlayer->GetDeclarerEngine(); CPlayList& playPlan = pPlayEngine->GetPlayPlan(); // get number of available plays int nCount = playPlan.GetSize(); if (nCount == 0) { m_pToolTip->SetText("", &point); return; } // get the index of the play under the cursor int nIndex = -1; int nFirstVisible = m_listPlayPlan.GetTopIndex(); int numVisible = m_listPlayPlan.GetCountPerPage(); CRect itemRect; for(int i=nFirstVisible;i<nFirstVisible+numVisible;i++) { if (m_listPlayPlan.GetItemRect(i, &itemRect, LVIR_BOUNDS)) { if (itemRect.PtInRect(clientPoint)) { nIndex = i; break; } } } // update text, if the cursor is on the right column if ((nIndex >= 0) && (nIndex < nCount)) { const int tnDescColumn = 2; BOOL bShow = FALSE; BOOL bInPosition = FALSE; // check if the cursor is within the description col CRect targetRect; m_listPlayPlan.ClientToScreen(&itemRect); targetRect.left = itemRect.left + m_listPlayPlan.GetColumnWidth(0) + m_listPlayPlan.GetColumnWidth(1); targetRect.right = targetRect.left + m_listPlayPlan.GetColumnWidth(tnDescColumn); if ((point.x >= targetRect.left) && (point.x <= targetRect.right)) { // check if we moved to a new line if (nIndex != m_nPrevTooltipIndex) { CPlay* pPlay = playPlan[nIndex]; // align the tooltip with list control entry's description point.x = targetRect.left; point.y = itemRect.top; // account for column padding point.x += 5; point.y -= 1; // m_pToolTip->SetText(pPlay->GetFullDescription(), &point); m_nPrevTooltipIndex = nIndex; m_pToolTip->Show(); } else { // on the same line; else leave the mesage as it is } } else { // not within the desc column m_pToolTip->Hide(); m_nPrevTooltipIndex = -1; } } else { // not on a valid line m_pToolTip->Hide(); m_nPrevTooltipIndex = -1; } // and show the tooltip }
void OnFollowMessage( CMessage* pMsg) { /// GS=GC的通信 TEAM_FOLLOW_TYPE type = (TEAM_FOLLOW_TYPE)pMsg->GetLong(); switch( type ) { /// 队长邀请队友跟随队长 case TF_Team_Leader_Invite: { CPlayer* pLeader = pMsg->GetPlayer(); if ( pLeader != NULL && pLeader->GetTeamID() != NULL_GUID ) { GSTeam *team = GetOrganiCtrl()->GetGameTeamByID( pLeader->GetTeamID() ); /// 如果是队长消息 if ( team != NULL && team->GetLeader() == pLeader->GetExID() ) { /// 给队员发送邀请请求 } else { //// 非队长的非法消息 } } } break; case TF_Team_Return_TeamFollow: { CGUID first,second; ///> 邀请者 pMsg->GetGUID( first ); ///> 被邀请者 pMsg->GetGUID( second ); } break; case TF_Team_Member_Follow_Leader: { CPlayer* player = pMsg->GetPlayer(); if ( player != NULL && player->GetTeamID() != NULL_GUID ) { GSTeam *team = GetOrganiCtrl()->GetGameTeamByID( player->GetTeamID() ); CPlayer* Leader = GetGame()->FindPlayer( team->GetLeader() ); if( !team || !Leader || Leader==player ) return ; /// 如果不是队长消息 player->SetCurrentProgress( CPlayer::PROGRESS_FOLLOW_LEADER ); long lRegionID = static_cast<CServerRegion*>(Leader->GetFather())->GetID(); long lPointx = Leader->GetTileX(); long lPointy = Leader->GetTileY(); /// 给队员发送邀请请求 CMessage Msg( MSG_S2C_FOLLOW_Leader ); Msg.Add( (long) TF_Team_Member_Follow_Leader); Msg.Add( (long) TF_Result_Follow_Success ); Msg.Add( lRegionID ); Msg.Add( lPointx ); Msg.Add( lPointy ); Msg.SendToPlayer( player->GetExID() ); } } break; case TF_Team_Stop_TeamFollow: { CPlayer* player = pMsg->GetPlayer(); if ( !player ) return ; GetInst(FollowManager).StopFollow( player ); } break; case TF_Team_Member_ChangeRgn: { } break; } }
void CPlayerView::ViewSpectatorTarget(SViewParams &viewParams) { CActor* pTarget = (CActor*)g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.stats_spectatorTarget); if(!pTarget) return; IVehicle* pVehicle = pTarget->GetLinkedVehicle(); static float defaultOffset = 0.3f; static float viewHeight = 1.8f; Matrix34 worldTM = pTarget->GetEntity()->GetWorldTM(); Vec3 worldPos = worldTM.GetTranslation(); if(!pVehicle) { const SStanceInfo* stanceInfo = pTarget->GetStanceInfo(pTarget->GetStance()); if(stanceInfo) { Interpolate(viewHeight, stanceInfo->viewOffset.z, 5.0f, viewParams.frameTime); worldPos.z += viewHeight + defaultOffset; } else { worldPos.z += 1.8f; } } else { // use vehicle pos/ori worldTM = pVehicle->GetEntity()->GetWorldTM(); worldPos = pVehicle->GetEntity()->GetWorldPos(); worldPos.z += 1.5f; } Ang3 worldAngles = Ang3::GetAnglesXYZ(Matrix33(worldTM)); float distance = 3; // if freelook allowed, get orientation and distance from player entity if(g_pGameCVars->g_spectate_FixedOrientation == 0) { CPlayer* pThisPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_in.entityId)); if(!pThisPlayer) return; Matrix34 ownOrientation = pThisPlayer->GetEntity()->GetWorldTM(); worldAngles += Ang3::GetAnglesXYZ(Matrix33(ownOrientation)); distance = pThisPlayer->GetSpectatorZoom(); } if(pVehicle) { distance *= 4.0f; // air vehicles need bigger distance if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air) distance *= 2.0f; } Vec3 goal; goal.x = distance * cos(worldAngles.z + gf_PI*1.5f) + worldPos.x; goal.y = distance * sin(worldAngles.z - gf_PI/2.0f) + worldPos.y; AABB targetBounds; pTarget->GetEntity()->GetLocalBounds(targetBounds); goal.z = targetBounds.max.z; float offset = defaultOffset; if(pVehicle) { if(pVehicle->GetMovement() && pVehicle->GetMovement()->GetMovementType() == IVehicleMovement::eVMT_Air) offset = 3.0f; else offset = 1.0f; } goal.z += pTarget->GetEntity()->GetWorldPos().z + offset; // store / interpolate the offset, not the world pos (reduces percieved jitter in vehicles) static Vec3 viewOffset(goal-worldPos); static Vec3 camPos(goal); static Vec3 entPos(worldPos); static EntityId lastSpectatorTarget(m_in.stats_spectatorTarget); // do a ray cast to check for camera intersection static ray_hit hit; IPhysicalEntity* pSkipEntities[10]; int nSkip = 0; if(pVehicle) { // vehicle drivers don't seem to have current items, so need to add the vehicle itself here nSkip = pVehicle->GetSkipEntities(pSkipEntities, 10); } else { IItem* pItem = pTarget->GetCurrentItem(); if (pItem) { CWeapon* pWeapon = (CWeapon*)pItem->GetIWeapon(); if (pWeapon) nSkip = CSingle::GetSkipEntities(pWeapon, pSkipEntities, 10); } } static float minDist = 0.4f; // how close we're allowed to get to the target static float wallSafeDistance = 0.3f; // how far to keep camera from walls Vec3 dir = goal - worldPos; primitives::sphere sphere; sphere.center = worldPos; sphere.r = wallSafeDistance; geom_contact *pContact = 0; float hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, dir, ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid, &pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip); // even when we have contact, keep the camera the same height above the target float minHeightDiff = dir.z; if(hitDist > 0 && pContact) { goal = worldPos + (hitDist * dir.GetNormalizedSafe()); if(goal.z - worldPos.z < minHeightDiff) { // can't move the camera far enough away from the player in this direction. Try moving it directly up a bit int numHits = 0; sphere.center = goal; // (move back just slightly to avoid colliding with the wall we've already found...) sphere.center -= dir.GetNormalizedSafe() * 0.05f; float newHitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, Vec3(0,0,minHeightDiff), ent_static|ent_terrain|ent_rigid|ent_sleeping_rigid, &pContact, 0, (geom_colltype_player<<rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0, pSkipEntities, nSkip); float raiseDist = minHeightDiff - (goal.z - worldPos.z) - wallSafeDistance; if(newHitDist != 0) { raiseDist = MIN(minHeightDiff, newHitDist); } raiseDist = MAX(0.0f, raiseDist); goal.z += raiseDist; worldPos.z += raiseDist*0.8f; } } int thisFrameId = gEnv->pRenderer->GetFrameID(); static int frameNo(thisFrameId); if(thisFrameId - frameNo > 5) { // reset positions viewOffset = goal - worldPos; entPos = worldPos; camPos = goal; } if(lastSpectatorTarget != m_in.stats_spectatorTarget) { viewOffset = goal - worldPos; entPos = worldPos; camPos = goal; lastSpectatorTarget = m_in.stats_spectatorTarget; } frameNo = thisFrameId; static float interpSpeed = 5.0f; static float interpSpeed2 = 5.0f; static float interpSpeed3 = 8.0f; if(pVehicle) { Interpolate(viewOffset, goal-worldPos, interpSpeed, viewParams.frameTime); entPos = worldPos; viewParams.position = worldPos + viewOffset; camPos = viewParams.position; } else { Vec3 camPosChange = goal - camPos; Vec3 entPosChange = worldPos - entPos; if(camPosChange.GetLengthSquared() > 100.0f) camPos = goal; if(entPosChange.GetLengthSquared() > 100.0f) entPos = worldPos; Interpolate(camPos, goal, interpSpeed2, viewParams.frameTime); Interpolate(entPos, worldPos, interpSpeed3, viewParams.frameTime); viewParams.position = camPos; } Matrix33 rotation = Matrix33::CreateRotationVDir((entPos - viewParams.position).GetNormalizedSafe()); viewParams.rotation = GetQuatFromMat33(rotation); m_io.bUsePivot = true; m_io.stats_bobCycle = 0.0; }
// Parse log messages here for any desired information (structure_built, etc.) // The following logs are needed: // "sawce<1><STEAM_0:1:4560311><alien1team>" triggered "structure_built" (type "defensechamber")` void AlertMessage_Post(ALERT_TYPE atype, const char *szFmt, ...) { if (atype != at_logged) { RETURN_META(MRES_IGNORED); } char *MessageStart; // original pointer to start of the message char *TypePointer; // pointer to the structure type char *CIDPointer; // pointer to the name text int CID; // connection ID of the player va_list LogArgs; va_start(LogArgs,szFmt); MessageStart=va_arg(LogArgs,char *); va_end(LogArgs); if (MessageStart==NULL) // Somehow got a null pointer, get out of here now { RETURN_META(MRES_IGNORED); } if ((TypePointer=strstr(MessageStart,"\"structure_built\""))==NULL) // was not found { RETURN_META(MRES_IGNORED); } if (*(TypePointer - 2) != 'd') // If this is not from a 'triggered "structure_built"', then ignore the message { RETURN_META(MRES_IGNORED); } // If we got here, then for all we can tell this message is good // Move up a few spaces TypePointer+=25; // strlen("\"structure_built\" (type \"")=25 // Now get the player's CID CIDPointer=MessageStart+1; // skip over the very first quotation mark while (*CIDPointer++ != '"') /*do nothing*/; --CIDPointer; // Move back past three < while (*CIDPointer-- != '<') /* do nothing*/; while (*CIDPointer-- != '<') /* do nothing*/; while (*CIDPointer-- != '<') /* do nothing*/; ++CIDPointer; // now skip past the < ++CIDPointer; // We now point to the CID string, atoi will stop at the > so just atoi it for the CID CID=atoi(CIDPointer); CPlayer *Player; if ((Player=UTIL_PlayerByCID(CID))==NULL) { RETURN_META(MRES_IGNORED); } // list of what impulses represent what type of structure building // use // 0 for unknown (shouldn't be used ever) // 1 for marine // 2 for alien // I'm marking the upgrades as marine structures just incase // they should never be used though! static int StructureTypes[128] = { 0, // 0 = unknown 0, // 1 = next weapon 0, // 2 = reload 0, // 3 = drop weapon 0, // 4 = unknown 0, // 5 = unknown 0, // 6 = unknown 0, // 7 = radio comm 0, // 8 = radio comm 0, // 9 = radio comm 0, // 10 = radio comm 0, // 11 = radio comm 0, // 12 = radio comm 0, // 13 = radio comm 0, // 14 = radio comm 0, // 15 = radio comm 0, // 16 = unknown 0, // 17 = unknown 0, // 18 = unknown 0, // 19 = unknown 1, // 20 = armor 1 1, // 21 = armor 2 1, // 22 = armor 3 1, // 23 = weapons 1 1, // 24 = weapons 2 1, // 25 = weapons 3 1, // 26 = siege upgrade 1, // 27 = drop catalyst 1, // 28 = research jp 1, // 29 = research ha 1, // 30 = distress beacon 1, // 31 = resupply (combat) 0, // 32 = unknown 1, // 33 = motion tracking 1, // 34 = phase gates upgrade 0, // 35 = unknown 1, // 36 = electricity upgrade 1, // 37 = handgrenades upgrade 1, // 38 = drop jetpack 1, // 39 = drop heavy armor 1, // 40 = infantry portal 1, // 41 = marine RT 0, // 42 = unused 1, // 43 = turret factory 0, // 44 = unused 1, // 45 = arms lab 1, // 46 = proto lab 1, // 47 = upgrade 1, // 48 = armory 1, // 49 = advanced armory 0, // 50 = unknown 1, // 51 = observatory 0, // 52 = unknown 1, // 53 = scanner sweep 0, // 54 = unknown 1, // 55 = build phase gate 1, // 56 = build turret 1, // 57 = build siege turret 1, // 58 = build command chair 1, // 59 = drop health pack 1, // 60 = drop ammo pack 1, // 61 = drop mine pack 1, // 62 = drop welder 0, // 63 = unknown 1, // 64 = drop shotgun 1, // 65 = drop heavymachinegun 1, // 66 = drop grenadelauncher 0, // 67 = unknown 0, // 68 = unknown 0, // 69 = unknown 0, // 70 = unknown 0, // 71 = unknown 0, // 72 = unknown 0, // 73 = unknown 0, // 74 = unknown 0, // 75 = unknown 0, // 76 = unknown 0, // 77 = unknown 0, // 78 = unknown 0, // 79 = unknown 0, // 80 = radio comm 0, // 81 = radio comm 1, // 82 = commander message 0, // 83 = commander message 0, // 84 = commander message 0, // 85 = unknown 0, // 86 = unknown 0, // 87 = unknown 0, // 88 = unknown 0, // 89 = unknown 2, // 90 = alienresourcetower 2, // 91 = offensechamber 2, // 92 = defensechamber 2, // 93 = sensorychamber 2, // 94 = movementchamber 2, // 95 = team_hive 0, // 96 = unknown 0, // 97 = unknown 0, // 98 = unknown 0, // 99 = unknown 0, // 100 = unknown 2, // 101 = carapace 2, // 102 = regeneration 2, // 103 = redemption 0, // 104 = unknown 1, // 105 = select all marines 0, // 106 = unknown 2, // 107 = celerity 2, // 108 = adrenaline 2, // 109 = silence 2, // 110 = cloaking 2, // 111 = focus 2, // 112 = scent of fear 2, // 113 = skulk 2, // 114 = gorge 2, // 115 = lerk 2, // 116 = fade 2, // 117 = onos 2, // 118 = unlock next ability (combat) 0, // 119 = unknown 0, // 120 = unknown 0, // 121 = unknown 0, // 122 = unknown 0, // 123 = unknown 0, // 124 = unknown 0, // 125 = unknown 2, // 126 = unlock next ability (combat) 0 // 127 = unknown }; int impulse=Player->GetPev()->impulse; if (impulse < 0 || impulse > 127) { RETURN_META(MRES_IGNORED); } if (impulse==95/*hive*/) { GameMan.ExecuteClientBuilt(Player->index(), UTIL_FindBuildingHive(), StructureTypes[impulse], impulse); } else { GameMan.ExecuteClientBuilt(Player->index(), ENTINDEX_NEW(GameMan.GetTemporaryEdict()), StructureTypes[impulse], impulse); } RETURN_META(MRES_IGNORED); }
bool CPokerCircle::onMessage(stMsg* prealMsg , eMsgPort eSenderPort , uint32_t nSessionID) { switch ( prealMsg->usMsgType ) { case MSG_CIRCLE_READ_TOPICS: { stMsgReadCircleTopicsRet* pRet = (stMsgReadCircleTopicsRet*)prealMsg ; stCircleTopicItem* pItem = (stCircleTopicItem*)(((char*)prealMsg) + sizeof(stMsgReadCircleTopicsRet)); while ( pRet->nCnt-- ) { stTopicDetail* pDetail = new stTopicDetail ; pDetail->nAuthorUID = pItem->nAuthorUID ; pDetail->nPublishTime = pItem->nPublishTime ; pDetail->nTopicID = pItem->nTopicID ; char* pContent = (char*)pItem; pContent = pContent + sizeof(stCircleTopicItem); pDetail->strContent.append(pContent,pItem->nContentLen) ; m_vListTopics.push_back(pDetail); pContent = pContent + pItem->nContentLen ; pItem = (stCircleTopicItem*)pContent ; if ( pDetail->nTopicID > m_nMaxTopicUID ) { m_nMaxTopicUID = pDetail->nTopicID ; } //LOGFMTI("read topic id = %d , content: %s",pDetail->nTopicID,pDetail->strContent.c_str()) ; std::sort(m_vListTopics.begin(),m_vListTopics.end(),TopicSort); } } break; case MSG_CIRCLE_PUBLISH_TOPIC: { stMsgPublishTopicRet msgBack ; stMsgPublishTopic* pRet = (stMsgPublishTopic*)prealMsg ; CPlayer* pPlayer = CGameServerApp::SharedGameServerApp()->GetPlayerMgr()->GetPlayerBySessionID(nSessionID); if ( pRet->nContentLen >= MAX_CIRCLE_CONTENT_LEN || pRet->nContentLen < 8 ) { msgBack.nRet = 2 ; msgBack.nTopicID = 0 ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; return true ; } //if ( pPlayer->GetBaseData()->GetData()->isRegister == 0 ) //{ // msgBack.nRet = 3 ; // msgBack.nTopicID = 0 ; // CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; // return true ; //} if ( pPlayer->GetBaseData()->GetAllCoin() < 200 ) { msgBack.nRet = 1 ; msgBack.nTopicID = 0 ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; return true ; } pPlayer->GetBaseData()->decressMoney(200); stTopicDetail* pDetail = new stTopicDetail ; pDetail->nAuthorUID = pPlayer->GetUserUID() ; pDetail->nPublishTime = time(nullptr) ; pDetail->nTopicID = ++m_nMaxTopicUID ; pDetail->strContent.append(((char*)prealMsg) + sizeof(stMsgPublishTopic),pRet->nContentLen) ; LOGFMTD("recive content = %s",pDetail->strContent.c_str()) ; m_vListTopics.push_back(pDetail); msgBack.nRet = 0 ; msgBack.nTopicID = pDetail->nTopicID ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; stMsgSaveAddCircleTopic msgAdd ; msgAdd.item.nAuthorUID = pDetail->nAuthorUID ; msgAdd.item.nPublishTime = pDetail->nPublishTime ; msgAdd.item.nTopicID = pDetail->nTopicID ; msgAdd.item.nContentLen = pDetail->strContent.size() ; CAutoBuffer auAddTopic(sizeof(msgAdd) + msgAdd.item.nContentLen ); auAddTopic.addContent(&msgAdd,sizeof(msgAdd)) ; auAddTopic.addContent(pDetail->strContent.c_str(),msgAdd.item.nContentLen) ; CGameServerApp::SharedGameServerApp()->sendMsg(0,auAddTopic.getBufferPtr(),auAddTopic.getContentSize()) ; } break; case MSG_CIRCLE_DELETE_TOPIC: { stMsgDeleteTopic* pDelete = (stMsgDeleteTopic*)prealMsg ; CPlayer* pPlayer = CGameServerApp::SharedGameServerApp()->GetPlayerMgr()->GetPlayerBySessionID(nSessionID); if ( pPlayer->GetUserUID() != MATCH_MGR_UID ) { return true ; } auto iter = m_vListTopics.begin() ; for ( ; iter != m_vListTopics.end() ; ++iter ) { if ( (*iter)->nTopicID == pDelete->nDelTopicID ) { delete (*iter) ; (*iter) = nullptr ; m_vListTopics.erase(iter) ; stMsgSaveDeleteCircleTopic msgDel ; msgDel.nTopicID = pDelete->nDelTopicID ; CGameServerApp::SharedGameServerApp()->sendMsg(0,(char*)&msgDel,sizeof(msgDel)) ; return true ; } } } break; case MSG_CIRCLE_REQUEST_TOPIC_LIST: { stMsgRequestTopicList* pRet = (stMsgRequestTopicList*)prealMsg ; stMsgRequestTopicListRet msgBack ; msgBack.nRet = 0 ; msgBack.nPageIdx = pRet->nPageIdx ; msgBack.nTotalPageCnt = ( m_vListTopics.size() + CIRCLE_TOPIC_CNT_PER_PAGE - 1 ) / CIRCLE_TOPIC_CNT_PER_PAGE ; memset(msgBack.vTopicIDs,0,sizeof(msgBack.vTopicIDs)) ; if ( pRet->nPageIdx >= msgBack.nTotalPageCnt ) { msgBack.nRet = 1 ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; return true ; } LOGFMTI("page idx = %d",pRet->nPageIdx); uint64_t nStartIdx = pRet->nPageIdx * CIRCLE_TOPIC_CNT_PER_PAGE ; for ( uint8_t nIdx =0 ; nStartIdx < m_vListTopics.size() && nIdx < CIRCLE_TOPIC_CNT_PER_PAGE ; ++nStartIdx, ++nIdx ) { uint64_t nReverIdx = m_vListTopics.size() - 1 - nStartIdx ; msgBack.vTopicIDs[nIdx] = m_vListTopics[nReverIdx]->nTopicID ; LOGFMTI("topic array idx = %d ,id = %I64d",nIdx,msgBack.vTopicIDs[nIdx]) ; } CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; } break; case MSG_CIRCLE_REQUEST_TOPIC_DETAIL: { stMsgRequestTopicDetail* pRet = (stMsgRequestTopicDetail*)prealMsg ; auto topic = getTopicByID(pRet->nTopicID) ; stMsgRequestTopicDetailRet msgBack ; msgBack.nRet = 0 ; if ( topic == nullptr ) { msgBack.nRet = 1 ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,(char*)&msgBack,sizeof(msgBack)) ; return true ; } msgBack.nAuthorUID = topic->nAuthorUID ; msgBack.nPublishTime = topic->nPublishTime ; msgBack.nTopicID = topic->nTopicID ; msgBack.nContentLen = topic->strContent.size() ; CAutoBuffer aubuff(sizeof(msgBack) + msgBack.nContentLen ); aubuff.addContent(&msgBack,sizeof(msgBack)) ; aubuff.addContent(topic->strContent.c_str(),msgBack.nContentLen) ; CGameServerApp::SharedGameServerApp()->sendMsg(nSessionID,aubuff.getBufferPtr(),aubuff.getContentSize()) ; LOGFMTD("send content = %s",topic->strContent.c_str()) ; } break; default: return false; } return true ; }
void IGameController::Tick() { // do warmup if(m_Warmup) { m_Warmup--; if(!m_Warmup) StartRound(); } if(m_GameOverTick != -1) { // game over.. wait for restart if(Server()->Tick() > m_GameOverTick+Server()->TickSpeed()*10) { CycleMap(); StartRound(); m_RoundCount++; } } // do team-balancing if (IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60) { GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams"); int aT[2] = {0,0}; float aTScore[2] = {0,0}; float aPScore[MAX_CLIENTS] = {0.0f}; for(int i = 0; i < MAX_CLIENTS; i++) { if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) { aT[GameServer()->m_apPlayers[i]->GetTeam()]++; aPScore[i] = GameServer()->m_apPlayers[i]->m_Score*Server()->TickSpeed()*60.0f/ (Server()->Tick()-GameServer()->m_apPlayers[i]->m_ScoreStartTick); aTScore[GameServer()->m_apPlayers[i]->GetTeam()] += aPScore[i]; } } // are teams unbalanced? if(absolute(aT[0]-aT[1]) >= 2) { int M = (aT[0] > aT[1]) ? 0 : 1; int NumBalance = absolute(aT[0]-aT[1]) / 2; do { CPlayer *pP = 0; float PD = aTScore[M]; for(int i = 0; i < MAX_CLIENTS; i++) { if(!GameServer()->m_apPlayers[i] || !CanBeMovedOnBalance(i)) continue; // remember the player who would cause lowest score-difference if(GameServer()->m_apPlayers[i]->GetTeam() == M && (!pP || absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i])) < PD)) { pP = GameServer()->m_apPlayers[i]; PD = absolute((aTScore[M^1]+aPScore[i]) - (aTScore[M]-aPScore[i])); } } // move the player to the other team int Temp = pP->m_LastActionTick; pP->SetTeam(M^1); pP->m_LastActionTick = Temp; pP->Respawn(); pP->m_ForceBalanced = true; } while (--NumBalance); m_ForceBalanced = true; } m_UnbalancedTick = -1; } // check for inactive players if(g_Config.m_SvInactiveKickTime > 0) { for(int i = 0; i < MAX_CLIENTS; ++i) { if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS && !Server()->IsAuthed(i)) { if(Server()->Tick() > GameServer()->m_apPlayers[i]->m_LastActionTick+g_Config.m_SvInactiveKickTime*Server()->TickSpeed()*60) { switch(g_Config.m_SvInactiveKick) { case 0: { // move player to spectator GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS); } break; case 1: { // move player to spectator if the reserved slots aren't filled yet, kick him otherwise int Spectators = 0; for(int j = 0; j < MAX_CLIENTS; ++j) if(GameServer()->m_apPlayers[j] && GameServer()->m_apPlayers[j]->GetTeam() == TEAM_SPECTATORS) ++Spectators; if(Spectators >= g_Config.m_SvSpectatorSlots) Server()->Kick(i, "Kicked for inactivity"); else GameServer()->m_apPlayers[i]->SetTeam(TEAM_SPECTATORS); } break; case 2: { // kick the player Server()->Kick(i, "Kicked for inactivity"); } } } } } } DoWincheck(); }
void CNetGame::BroadcastData( RakNet::BitStream *bitStream, PacketPriority priority, PacketReliability reliability, char orderingStream, BYTE byteExcludedPlayer, BOOL bBroadcastLocalRangeOnly, BOOL bAimSync ) { // Use UNASSIGNED_PLAYER_ID to broadcast to all. BYTE x=0; int r=0,send_rate=0; float fDistance; CPlayer *pPlayer; int iExVW = m_pPlayerPool->GetPlayerVirtualWorld(byteExcludedPlayer); while(x!=MAX_PLAYERS) { if( (m_pPlayerPool->GetSlotState(x) == TRUE) && (x != byteExcludedPlayer) ) { pPlayer = m_pPlayerPool->GetAt(x); if (m_pPlayerPool->GetPlayerVirtualWorld(x) == iExVW) { fDistance = m_pPlayerPool->GetDistanceFromPlayerToPlayer(byteExcludedPlayer,x); // Special Condition For Spectators. if( pPlayer->GetState() == PLAYER_STATE_SPECTATING && pPlayer->m_SpectateID == byteExcludedPlayer ) { fDistance = 0.0f; // forces it to sync as if right there. } if(bBroadcastLocalRangeOnly) { // data is synced/broadcast in range of near players only. if(fDistance < LOCAL_RANGE) { m_pRak->Send(bitStream,priority,reliability,orderingStream, m_pRak->GetPlayerIDFromIndex(x),FALSE); } } else { // Get the once in however many sends send_rate = GetBroadcastSendRateFromPlayerDistance(fDistance); // Generate a random number based on send_rate. if(send_rate > 0) { r = (int)(rand() % send_rate); } else { r = 0; } // The reason we send randomly is because otherwise we'd // have to track send occurances from each player to player. // Over time, random averages out to be the same. if(!r) { m_pRak->Send(bitStream,priority,reliability,orderingStream, m_pRak->GetPlayerIDFromIndex(x),FALSE); } } } } x++; } }
int main(int argc, char* argv[]) { int nResult = false; int nRetCode = false; int i = 0; printf("%s\n", argv[0]); srand( (unsigned)time( NULL ) ); memset(g_szGMCommandList, 0, MAX_GM_COUNT * MAX_GM_SIZE); nRetCode = ProcessArg(argc, argv); if (!nRetCode) { Help(); goto Exit0; } //g_thePlayers.empty(); for (i = g_AccoutIDMin; i <= g_AccoutIDMax; i++) { char szAccountName[0x100]; sprintf(szAccountName, "Robot%04d", i); printf("Create %s ... ", szAccountName); IPlayer *pPlayer = new CPlayer( g_szServerIP, g_nServerPort, szAccountName ); //Sleep(300); if (!pPlayer) { printf("fail!\n"); continue; } printf("ok!\n"); // flying add these, make the robot at the specified position if (g_nFlgSetPos) pPlayer->SetPos(g_ptBirthPos.x, g_ptBirthPos.y); // flying add these, make the robot auto attack to the NPCs if (g_nFlgSetAttack) pPlayer->SetAttack(); pPlayer->SetSilence(g_nFlgSetSilence); pPlayer->SetChatTimer(g_nFlgChatTimer); pPlayer->ConnectToGateway(); g_thePlayers.push_back( pPlayer ); } printf("Press \'Q\' to End Program\n"); while (true) { int ch = 0; PLAYER_LIST::iterator it; for ( it = g_thePlayers.begin(); it != g_thePlayers.end(); it ++ ) { while (true) { if (!kbhit()) break; ch = getch(); ch = toupper(ch); if ((ch == 'Q') || (ch == 27)) // ESC break; } if ((ch == 'Q') || (ch == 27)) // ESC break; //Sleep(rand() % 40); CPlayer *pPlayer = (CPlayer *)(*it); if (pPlayer == NULL) { Sleep(100); continue; } if ((pPlayer->GetStatus()) != CPlayer::enumExitGame) continue; OnlineGameLib::Win32::_tstring sAccountName; pPlayer->GetAccountName(sAccountName); delete pPlayer; pPlayer = NULL; *it = NULL; printf("Destory %s ... ok!\n", sAccountName.c_str()); if (g_nAddRoleFlag || g_nDeleteRoleFlag) continue; printf("ReCreate %s ... ", sAccountName.c_str()); pPlayer = new CPlayer( g_szServerIP, g_nServerPort, sAccountName.c_str() ); Sleep(300); if (!pPlayer) { printf("fail!\n"); continue; } printf("ok!\n"); pPlayer->ConnectToGateway(); *it = pPlayer; } if ((ch == 'Q') || (ch == 27)) // ESC break; Sleep(rand() % 1000); } { PLAYER_LIST::iterator it; for ( it = g_thePlayers.begin(); it != g_thePlayers.end(); it ++ ) { IPlayer *pPlayer = ( *it ); if ( pPlayer ) { delete pPlayer; } } } nResult = true; Exit0: return nResult; }
// This cleans up our clients mess :P void CWorldServer::OnClientDisconnect( CClientSocket* thisclient ) { if(thisclient->player==NULL) return; CPlayer* player = (CPlayer*)thisclient->player; if(!player->Session->isLoggedIn) return; if(!player->Saved) { player->savedata(); player->Session->isLoggedIn = false; //send packet to change messenger status (offline) BEGINPACKET( pak, 0x7e1 ); ADDBYTE ( pak, 0xfa ); ADDWORD ( pak, player->CharInfo->charid ); ADDBYTE ( pak, 0x00 ); cryptPacket( (char*)&pak, NULL ); send( csock, (char*)&pak, pak.Size, 0 ); } if ( player->Fairy ){ GServer->FairyList.at(player->FairyListIndex)->assigned = false; GServer->FairyList.at(player->FairyListIndex)->LastTime = clock(); GServer->FairyList.at(player->FairyListIndex)->ListIndex = 0; GServer->FairyList.at(player->FairyListIndex)->WaitTime = GServer->Config.FairyWait * (rand()% GServer->GetFairyRange(1)+ GServer->GetFairyRange(0)); player->Fairy = false; player->FairyListIndex = 0; GServer->DoFairyStuff(player, 0); // recalculate FairyMax int oldFairyMax = GServer->Config.FairyMax; GServer->Config.FairyMax = (int)ceil((float)GServer->ClientList.size() / 50.0); //(1 fairy more every 50 player) if( oldFairyMax > GServer->Config.FairyMax ){ GServer->FairyList.erase( GServer->FairyList.begin() + GServer->FairyList.size() ); } } if(player->Party->party!=NULL) { CParty* party = player->Party->party; BEGINPACKET( pak, 0x7d2 ); ADDWORD ( pak, 0xff00 ); ADDDWORD ( pak, player->CharInfo->charid ); bool pflag = false; party->RemovePlayer( player ); if(party->Members.size()>1) { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); if(!pflag) { ADDDWORD( pak, othermember->CharInfo->charid ); if(player->Party->IsMaster) othermember->Party->IsMaster = true; pflag = true; } othermember->client->SendPacket( &pak ); } } else { for(UINT i=0;i<party->Members.size();i++) { CPlayer* othermember = party->Members.at(i); BEGINPACKET( pak, 0x7d1 ); ADDBYTE ( pak, 0x05 ); ADDWORD ( pak, 0x0000 ); ADDWORD ( pak, 0x0000 ); othermember->client->SendPacket( &pak ); othermember->Party->party = NULL; othermember->Party->IsMaster = true; } RemoveParty( party ); delete party; party = NULL; } } DB->QExecute("UPDATE accounts SET online=false where id=%u", player->Session->userid ); }
bool CPlayerPuresyncPacket::Write ( NetBitStreamInterface& BitStream ) const { if ( m_pSourceElement ) { CPlayer * pSourcePlayer = static_cast < CPlayer * > ( m_pSourceElement ); ElementID PlayerID = pSourcePlayer->GetID (); unsigned short usLatency = pSourcePlayer->GetPing (); const CControllerState& ControllerState = pSourcePlayer->GetPad ()->GetCurrentControllerState (); CElement* pContactElement = pSourcePlayer->GetContactElement (); // Get current weapon slot unsigned char ucWeaponSlot = pSourcePlayer->GetWeaponSlot (); // Flags SPlayerPuresyncFlags flags; flags.data.bIsInWater = ( pSourcePlayer->IsInWater () == true ); flags.data.bIsOnGround = ( pSourcePlayer->IsOnGround () == true ); flags.data.bHasJetPack = ( pSourcePlayer->HasJetPack () == true ); flags.data.bIsDucked = ( pSourcePlayer->IsDucked () == true ); flags.data.bWearsGoogles = ( pSourcePlayer->IsWearingGoggles () == true ); flags.data.bHasContact = ( pContactElement != NULL ); flags.data.bIsChoking = ( pSourcePlayer->IsChoking () == true ); flags.data.bAkimboTargetUp = ( pSourcePlayer->IsAkimboArmUp () == true ); flags.data.bIsOnFire = ( pSourcePlayer->IsOnFire () == true ); flags.data.bHasAWeapon = ( ucWeaponSlot != 0 ); flags.data.bSyncingVelocity = ( !flags.data.bIsOnGround || pSourcePlayer->IsSyncingVelocity () ); flags.data.bStealthAiming = ( pSourcePlayer->IsStealthAiming () == true ); CVector vecPosition = pSourcePlayer->GetPosition (); if ( pContactElement ) pSourcePlayer->GetContactPosition ( vecPosition ); float fCameraRotation = pSourcePlayer->GetCameraRotation (); BitStream.Write ( PlayerID ); // Write the time context BitStream.Write ( pSourcePlayer->GetSyncTimeContext () ); BitStream.WriteCompressed ( usLatency ); WriteFullKeysync ( ControllerState, BitStream ); /* // Figure out what to send SPlayerPuresyncSentHeader sent; sent.bFlags = CompareAndSet ( usFlags, pSourcePlayer->lastSent.usFlags ); sent.bPosition = CompareAndSet ( vecPosition, pSourcePlayer->lastSent.vecPosition ); sent.bRotation = CompareAndSet ( fRotation, pSourcePlayer->lastSent.fRotation ); sent.bVelocity = CompareAndSet ( vecVelocity, pSourcePlayer->lastSent.vecVelocity ); sent.bHealth = CompareAndSet ( ucHealth, pSourcePlayer->lastSent.ucHealth ); sent.bArmor = CompareAndSet ( ucArmor, pSourcePlayer->lastSent.ucArmor ); sent.bCameraRotation = CompareAndSet ( fCameraRotation, pSourcePlayer->lastSent.fCameraRotation ); sent.bWeaponType = CompareAndSet ( ucWeaponType, pSourcePlayer->lastSent.ucWeaponType ); sent.Write ( BitStream ); if ( sent.bPosition ) { BitStream.Write ( vecPosition.fX ); BitStream.Write ( vecPosition.fY ); BitStream.Write ( vecPosition.fZ ); } if ( sent.bRotation ) BitStream.Write ( fRotation ); etc... Could also do a 'sent' header in WriteFullKeysync */ BitStream.Write ( &flags ); if ( pContactElement ) BitStream.Write ( pContactElement->GetID () ); SPositionSync position ( false ); position.data.vecPosition = vecPosition; BitStream.Write ( &position ); SPedRotationSync rotation; rotation.data.fRotation = pSourcePlayer->GetRotation (); BitStream.Write ( &rotation ); if ( flags.data.bSyncingVelocity ) { SVelocitySync velocity; pSourcePlayer->GetVelocity ( velocity.data.vecVelocity ); BitStream.Write ( &velocity ); } // Player health and armor SPlayerHealthSync health; health.data.fValue = pSourcePlayer->GetHealth (); BitStream.Write ( &health ); SPlayerArmorSync armor; armor.data.fValue = pSourcePlayer->GetArmor (); BitStream.Write ( &armor ); BitStream.Write ( fCameraRotation ); if ( flags.data.bHasAWeapon ) { unsigned int uiSlot = ucWeaponSlot; SWeaponSlotSync slot; slot.data.uiSlot = uiSlot; BitStream.Write ( &slot ); if ( CWeaponNames::DoesSlotHaveAmmo ( uiSlot ) ) { unsigned short usWeaponAmmoInClip = pSourcePlayer->GetWeaponAmmoInClip (); /* // Figure out what to send SPlayerPuresyncWeaponSentHeader sent; sent.bWeaponAmmoInClip = CompareAndSet ( usWeaponAmmoInClip, pSourcePlayer->lastSent.usWeaponAmmoInClip ); sent.bAimDirectionX = CompareAndSet ( fAimDirectionX, pSourcePlayer->lastSent.fAimDirectionX ); sent.bAimDirectionY = CompareAndSet ( fAimDirectionY, pSourcePlayer->lastSent.fAimDirectionY ); sent.bSniperSource = CompareAndSet ( vecSniperSource, pSourcePlayer->lastSent.vecSniperSource ); sent.bTargetting = CompareAndSet ( vecTargetting, pSourcePlayer->lastSent.vecTargetting ); sent.Write ( BitStream ); if ( sent.bWeaponAmmoInClip ) BitStream.Write ( usWeaponAmmoInClip ); if ( sent.bAimDirectionX ) BitStream.Write ( fAimDirectionX ); if ( sent.bAimDirectionY ) BitStream.Write ( fAimDirectionY ); etc... */ SWeaponAmmoSync ammo ( pSourcePlayer->GetWeaponType (), false, true ); ammo.data.usAmmoInClip = usWeaponAmmoInClip; BitStream.Write ( &ammo ); SWeaponAimSync aim ( 0.0f, ( ControllerState.RightShoulder1 || ControllerState.ButtonCircle ) ); aim.data.fArm = pSourcePlayer->GetAimDirection (); // Write the aim data only if he's aiming or shooting if ( aim.isFull() ) { aim.data.vecOrigin = pSourcePlayer->GetSniperSourceVector (); pSourcePlayer->GetTargettingVector ( aim.data.vecTarget ); } BitStream.Write ( &aim ); } } // Success return true; } return false; }
void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) { void *pRawMsg = m_NetObjHandler.SecureUnpackMsg(MsgID, pUnpacker); CPlayer *pPlayer = m_apPlayers[ClientID]; if(!pRawMsg) { char aBuf[256]; str_format(aBuf, sizeof(aBuf), "dropped weird message '%s' (%d), failed on '%s'", m_NetObjHandler.GetMsgName(MsgID), MsgID, m_NetObjHandler.FailedMsgOn()); Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "server", aBuf); return; } if(MsgID == NETMSGTYPE_CL_SAY) { CNetMsg_Cl_Say *pMsg = (CNetMsg_Cl_Say *)pRawMsg; int Team = pMsg->m_Team; if(Team) Team = pPlayer->GetTeam(); else Team = CGameContext::CHAT_ALL; if(g_Config.m_SvSpamprotection && pPlayer->m_LastChat && pPlayer->m_LastChat+Server()->TickSpeed() > Server()->Tick()) return; pPlayer->m_LastChat = Server()->Tick(); // check for invalid chars unsigned char *pMessage = (unsigned char *)pMsg->m_pMessage; while (*pMessage) { if(*pMessage < 32) *pMessage = ' '; pMessage++; } SendChat(ClientID, Team, pMsg->m_pMessage); } else if(MsgID == NETMSGTYPE_CL_CALLVOTE) { if(g_Config.m_SvSpamprotection && pPlayer->m_LastVoteTry && pPlayer->m_LastVoteTry+Server()->TickSpeed()*3 > Server()->Tick()) return; int64 Now = Server()->Tick(); pPlayer->m_LastVoteTry = Now; if(pPlayer->GetTeam() == TEAM_SPECTATORS) { SendChatTarget(ClientID, "Spectators aren't allowed to start a vote."); return; } if(m_VoteCloseTime) { SendChatTarget(ClientID, "Wait for current vote to end before calling a new one."); return; } int Timeleft = pPlayer->m_LastVoteCall + Server()->TickSpeed()*60 - Now; if(pPlayer->m_LastVoteCall && Timeleft > 0) { char aChatmsg[512] = {0}; str_format(aChatmsg, sizeof(aChatmsg), "You must wait %d seconds before making another vote", (Timeleft/Server()->TickSpeed())+1); SendChatTarget(ClientID, aChatmsg); return; } char aChatmsg[512] = {0}; char aDesc[VOTE_DESC_LENGTH] = {0}; char aCmd[VOTE_CMD_LENGTH] = {0}; CNetMsg_Cl_CallVote *pMsg = (CNetMsg_Cl_CallVote *)pRawMsg; const char *pReason = pMsg->m_Reason[0] ? pMsg->m_Reason : "No reason given"; if(str_comp_nocase(pMsg->m_Type, "option") == 0) { CVoteOptionServer *pOption = m_pVoteOptionFirst; while(pOption) { if(str_comp_nocase(pMsg->m_Value, pOption->m_aDescription) == 0) { str_format(aChatmsg, sizeof(aChatmsg), "'%s' called vote to change server option '%s' (%s)", Server()->ClientName(ClientID), pOption->m_aDescription, pReason); str_format(aDesc, sizeof(aDesc), "%s", pOption->m_aDescription); str_format(aCmd, sizeof(aCmd), "%s", pOption->m_aCommand); break; } pOption = pOption->m_pNext; } if(!pOption) { str_format(aChatmsg, sizeof(aChatmsg), "'%s' isn't an option on this server", pMsg->m_Value); SendChatTarget(ClientID, aChatmsg); return; } } else if(str_comp_nocase(pMsg->m_Type, "kick") == 0) { if(!g_Config.m_SvVoteKick) { SendChatTarget(ClientID, "Server does not allow voting to kick players"); return; } if(g_Config.m_SvVoteKickMin) { int PlayerNum = 0; for(int i = 0; i < MAX_CLIENTS; ++i) if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) ++PlayerNum; if(PlayerNum < g_Config.m_SvVoteKickMin) { str_format(aChatmsg, sizeof(aChatmsg), "Kick voting requires %d players on the server", g_Config.m_SvVoteKickMin); SendChatTarget(ClientID, aChatmsg); return; } } int KickID = str_toint(pMsg->m_Value); if(KickID < 0 || KickID >= MAX_CLIENTS || !m_apPlayers[KickID]) { SendChatTarget(ClientID, "Invalid client id to kick"); return; } if(KickID == ClientID) { SendChatTarget(ClientID, "You can't kick yourself"); return; } if(Server()->IsAuthed(KickID)) { SendChatTarget(ClientID, "You can't kick admins"); char aBufKick[128]; str_format(aBufKick, sizeof(aBufKick), "'%s' called for vote to kick you", Server()->ClientName(ClientID)); SendChatTarget(KickID, aBufKick); return; } str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to kick '%s' (%s)", Server()->ClientName(ClientID), Server()->ClientName(KickID), pReason); str_format(aDesc, sizeof(aDesc), "Kick '%s'", Server()->ClientName(KickID)); if (!g_Config.m_SvVoteKickBantime) str_format(aCmd, sizeof(aCmd), "kick %d Kicked by vote", KickID); else { char aAddrStr[NETADDR_MAXSTRSIZE] = {0}; Server()->GetClientAddr(KickID, aAddrStr, sizeof(aAddrStr)); str_format(aCmd, sizeof(aCmd), "ban %s %d Banned by vote", aAddrStr, g_Config.m_SvVoteKickBantime); } } else if(str_comp_nocase(pMsg->m_Type, "spectate") == 0) { if(!g_Config.m_SvVoteSpectate) { SendChatTarget(ClientID, "Server does not allow voting to move players to spectators"); return; } int SpectateID = str_toint(pMsg->m_Value); if(SpectateID < 0 || SpectateID >= MAX_CLIENTS || !m_apPlayers[SpectateID] || m_apPlayers[SpectateID]->GetTeam() == TEAM_SPECTATORS) { SendChatTarget(ClientID, "Invalid client id to move"); return; } if(SpectateID == ClientID) { SendChatTarget(ClientID, "You can't move yourself"); return; } str_format(aChatmsg, sizeof(aChatmsg), "'%s' called for vote to move '%s' to spectators (%s)", Server()->ClientName(ClientID), Server()->ClientName(SpectateID), pReason); str_format(aDesc, sizeof(aDesc), "move '%s' to spectators", Server()->ClientName(SpectateID)); str_format(aCmd, sizeof(aCmd), "set_team %d -1 %d", SpectateID, g_Config.m_SvVoteSpectateRejoindelay); } if(aCmd[0]) { SendChat(-1, CGameContext::CHAT_ALL, aChatmsg); StartVote(aDesc, aCmd, pReason); pPlayer->m_Vote = 1; pPlayer->m_VotePos = m_VotePos = 1; m_VoteCreator = ClientID; pPlayer->m_LastVoteCall = Now; } } else if(MsgID == NETMSGTYPE_CL_VOTE) { if(!m_VoteCloseTime) return; if(pPlayer->m_Vote == 0) { CNetMsg_Cl_Vote *pMsg = (CNetMsg_Cl_Vote *)pRawMsg; if(!pMsg->m_Vote) return; pPlayer->m_Vote = pMsg->m_Vote; pPlayer->m_VotePos = ++m_VotePos; m_VoteUpdate = true; } } else if (MsgID == NETMSGTYPE_CL_SETTEAM && !m_World.m_Paused) { CNetMsg_Cl_SetTeam *pMsg = (CNetMsg_Cl_SetTeam *)pRawMsg; if(pPlayer->GetTeam() == pMsg->m_Team || (g_Config.m_SvSpamprotection && pPlayer->m_LastSetTeam && pPlayer->m_LastSetTeam+Server()->TickSpeed()*3 > Server()->Tick())) return; if(pPlayer->m_TeamChangeTick > Server()->Tick()) { pPlayer->m_LastSetTeam = Server()->Tick(); int TimeLeft = (pPlayer->m_TeamChangeTick - Server()->Tick())/Server()->TickSpeed(); char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Time to wait before changing team: %02d:%02d", TimeLeft/60, TimeLeft%60); SendBroadcast(aBuf, ClientID); return; } // Switch team on given client and kill/respawn him if(m_pController->CanJoinTeam(pMsg->m_Team, ClientID)) { if(m_pController->CanChangeTeam(pPlayer, pMsg->m_Team)) { pPlayer->m_LastSetTeam = Server()->Tick(); if(pPlayer->GetTeam() == TEAM_SPECTATORS || pMsg->m_Team == TEAM_SPECTATORS) m_VoteUpdate = true; pPlayer->SetTeam(pMsg->m_Team); (void)m_pController->CheckTeamBalance(); pPlayer->m_TeamChangeTick = Server()->Tick(); } else SendBroadcast("Teams must be balanced, please join other team", ClientID); } else { char aBuf[128]; str_format(aBuf, sizeof(aBuf), "Only %d active players are allowed", Server()->MaxClients()-g_Config.m_SvSpectatorSlots); SendBroadcast(aBuf, ClientID); } } else if (MsgID == NETMSGTYPE_CL_SETSPECTATORMODE && !m_World.m_Paused) { CNetMsg_Cl_SetSpectatorMode *pMsg = (CNetMsg_Cl_SetSpectatorMode *)pRawMsg; if(pPlayer->GetTeam() != TEAM_SPECTATORS || pPlayer->m_SpectatorID == pMsg->m_SpectatorID || ClientID == pMsg->m_SpectatorID || (g_Config.m_SvSpamprotection && pPlayer->m_LastSetSpectatorMode && pPlayer->m_LastSetSpectatorMode+Server()->TickSpeed()*3 > Server()->Tick())) return; pPlayer->m_LastSetSpectatorMode = Server()->Tick(); if(pMsg->m_SpectatorID != SPEC_FREEVIEW && (!m_apPlayers[pMsg->m_SpectatorID] || m_apPlayers[pMsg->m_SpectatorID]->GetTeam() == TEAM_SPECTATORS)) SendChatTarget(ClientID, "Invalid spectator id used"); else pPlayer->m_SpectatorID = pMsg->m_SpectatorID; } else if (MsgID == NETMSGTYPE_CL_STARTINFO) { if(pPlayer->m_IsReady) return; CNetMsg_Cl_StartInfo *pMsg = (CNetMsg_Cl_StartInfo *)pRawMsg; pPlayer->m_LastChangeInfo = Server()->Tick(); // set start infos Server()->SetClientName(ClientID, pMsg->m_pName); Server()->SetClientClan(ClientID, pMsg->m_pClan); Server()->SetClientCountry(ClientID, pMsg->m_Country); str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName)); pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; m_pController->OnPlayerInfoChange(pPlayer); // send vote options CNetMsg_Sv_VoteClearOptions ClearMsg; Server()->SendPackMsg(&ClearMsg, MSGFLAG_VITAL, ClientID); CNetMsg_Sv_VoteOptionListAdd OptionMsg; int NumOptions = 0; OptionMsg.m_pDescription0 = ""; OptionMsg.m_pDescription1 = ""; OptionMsg.m_pDescription2 = ""; OptionMsg.m_pDescription3 = ""; OptionMsg.m_pDescription4 = ""; OptionMsg.m_pDescription5 = ""; OptionMsg.m_pDescription6 = ""; OptionMsg.m_pDescription7 = ""; OptionMsg.m_pDescription8 = ""; OptionMsg.m_pDescription9 = ""; OptionMsg.m_pDescription10 = ""; OptionMsg.m_pDescription11 = ""; OptionMsg.m_pDescription12 = ""; OptionMsg.m_pDescription13 = ""; OptionMsg.m_pDescription14 = ""; CVoteOptionServer *pCurrent = m_pVoteOptionFirst; while(pCurrent) { switch(NumOptions++) { case 0: OptionMsg.m_pDescription0 = pCurrent->m_aDescription; break; case 1: OptionMsg.m_pDescription1 = pCurrent->m_aDescription; break; case 2: OptionMsg.m_pDescription2 = pCurrent->m_aDescription; break; case 3: OptionMsg.m_pDescription3 = pCurrent->m_aDescription; break; case 4: OptionMsg.m_pDescription4 = pCurrent->m_aDescription; break; case 5: OptionMsg.m_pDescription5 = pCurrent->m_aDescription; break; case 6: OptionMsg.m_pDescription6 = pCurrent->m_aDescription; break; case 7: OptionMsg.m_pDescription7 = pCurrent->m_aDescription; break; case 8: OptionMsg.m_pDescription8 = pCurrent->m_aDescription; break; case 9: OptionMsg.m_pDescription9 = pCurrent->m_aDescription; break; case 10: OptionMsg.m_pDescription10 = pCurrent->m_aDescription; break; case 11: OptionMsg.m_pDescription11 = pCurrent->m_aDescription; break; case 12: OptionMsg.m_pDescription12 = pCurrent->m_aDescription; break; case 13: OptionMsg.m_pDescription13 = pCurrent->m_aDescription; break; case 14: { OptionMsg.m_pDescription14 = pCurrent->m_aDescription; OptionMsg.m_NumOptions = NumOptions; Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, ClientID); OptionMsg = CNetMsg_Sv_VoteOptionListAdd(); NumOptions = 0; OptionMsg.m_pDescription1 = ""; OptionMsg.m_pDescription2 = ""; OptionMsg.m_pDescription3 = ""; OptionMsg.m_pDescription4 = ""; OptionMsg.m_pDescription5 = ""; OptionMsg.m_pDescription6 = ""; OptionMsg.m_pDescription7 = ""; OptionMsg.m_pDescription8 = ""; OptionMsg.m_pDescription9 = ""; OptionMsg.m_pDescription10 = ""; OptionMsg.m_pDescription11 = ""; OptionMsg.m_pDescription12 = ""; OptionMsg.m_pDescription13 = ""; OptionMsg.m_pDescription14 = ""; } } pCurrent = pCurrent->m_pNext; } if(NumOptions > 0) { OptionMsg.m_NumOptions = NumOptions; Server()->SendPackMsg(&OptionMsg, MSGFLAG_VITAL, ClientID); NumOptions = 0; } // send tuning parameters to client SendTuningParams(ClientID); // client is ready to enter pPlayer->m_IsReady = true; CNetMsg_Sv_ReadyToEnter m; Server()->SendPackMsg(&m, MSGFLAG_VITAL|MSGFLAG_FLUSH, ClientID); } else if (MsgID == NETMSGTYPE_CL_CHANGEINFO) { if(g_Config.m_SvSpamprotection && pPlayer->m_LastChangeInfo && pPlayer->m_LastChangeInfo+Server()->TickSpeed()*5 > Server()->Tick()) return; CNetMsg_Cl_ChangeInfo *pMsg = (CNetMsg_Cl_ChangeInfo *)pRawMsg; pPlayer->m_LastChangeInfo = Server()->Tick(); // set infos char aOldName[MAX_NAME_LENGTH]; str_copy(aOldName, Server()->ClientName(ClientID), sizeof(aOldName)); Server()->SetClientName(ClientID, pMsg->m_pName); if(str_comp(aOldName, Server()->ClientName(ClientID)) != 0) { char aChatText[256]; str_format(aChatText, sizeof(aChatText), "'%s' changed name to '%s'", aOldName, Server()->ClientName(ClientID)); SendChat(-1, CGameContext::CHAT_ALL, aChatText); } Server()->SetClientClan(ClientID, pMsg->m_pClan); Server()->SetClientCountry(ClientID, pMsg->m_Country); str_copy(pPlayer->m_TeeInfos.m_SkinName, pMsg->m_pSkin, sizeof(pPlayer->m_TeeInfos.m_SkinName)); pPlayer->m_TeeInfos.m_UseCustomColor = pMsg->m_UseCustomColor; pPlayer->m_TeeInfos.m_ColorBody = pMsg->m_ColorBody; pPlayer->m_TeeInfos.m_ColorFeet = pMsg->m_ColorFeet; m_pController->OnPlayerInfoChange(pPlayer); } else if (MsgID == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused) { CNetMsg_Cl_Emoticon *pMsg = (CNetMsg_Cl_Emoticon *)pRawMsg; if(g_Config.m_SvSpamprotection && pPlayer->m_LastEmote && pPlayer->m_LastEmote+Server()->TickSpeed()*3 > Server()->Tick()) return; pPlayer->m_LastEmote = Server()->Tick(); SendEmoticon(ClientID, pMsg->m_Emoticon); } else if (MsgID == NETMSGTYPE_CL_KILL && !m_World.m_Paused) { if(pPlayer->m_LastKill && pPlayer->m_LastKill+Server()->TickSpeed()*3 > Server()->Tick()) return; pPlayer->m_LastKill = Server()->Tick(); pPlayer->KillCharacter(WEAPON_SELF); } }
// 响应SKILL消息 void OnSkillMessage(CMessage* pMsg) { switch(pMsg->GetType()) { case MSG_S2C_SKILL_LOCK_GOODS: { long lExtendID = pMsg->GetLong(); long lPos = pMsg->GetLong(); CPlayer* pMainPlayer = GetGame()->GetMainPlayer(); if (pMainPlayer!=NULL) { CGoods* pGoods = pMainPlayer->GetGoodsByPosition(lExtendID,lPos); if (pGoods!=NULL&&!pGoods->IsLocked()) { pGoods->Lock(); //CItemPageEx* pPage = GetGame()->GetCGuiEx()->GetItemPageEx(); //if (pPage!=NULL) //{ // pPage->UpdateGoodsShow(lExtendID,(int)lPos); //} } } } break; case MSG_S2C_SKILL_UNLOCK_GOODS: { DWORD lExtendID = pMsg->GetDWord(); DWORD lPos = pMsg->GetDWord(); CPlayer* pMainPlayer = GetGame()->GetMainPlayer(); if (pMainPlayer!=NULL) { CGoods* pGoods = pMainPlayer->GetGoodsByPosition(lExtendID,lPos); if (pGoods!=NULL&&pGoods->IsLocked()) { pGoods->UnLock(); CMainPlayerHand* pHand = 0;//GetGame()->GetCGuiEx()->GetPMainPlayerHand(); if (pHand!=NULL&&pHand->GetPGoodsOfMainPlayerHand()!=NULL&& pHand->GetPGoodsOfMainPlayerHand()->GetExID()==pGoods->GetExID()) { pGoods->SetHaveShadowState(true); } } } } break; case MSG_S2C_SKILL_STATE_CHANGE: //##同步状态消息 { LONG lType = pMsg -> GetLong(); CGUID ID; pMsg->GetGUID(ID); DWORD dwHP = pMsg -> GetDWord(); WORD wMP = pMsg -> GetWord(); WORD eg = pMsg -> GetWord(); if(lType==TYPE_PLAYER) { CPlayer* pMainPlayer = pMsg -> GetPlayer(); //是自己则改变自己 if(pMainPlayer->GetExID() == ID) { pMainPlayer -> SetHp( dwHP ); pMainPlayer -> SetMp(wMP); pMainPlayer -> SetEnergy(eg); //pMainPlayer -> SetRP( wRP ); //pMainPlayer -> SetYP( wYP ); } else { //看是否是队友 vector<CPlayer::tagTeammate>& vTeammate = pMainPlayer -> GetTeam(); for( size_t i = 0; i < vTeammate.size(); i ++ ) { if( vTeammate[i].ID == ID ) { vTeammate[i].wHP = (WORD)dwHP; break; } } } } else { //改变怪物状态 CMoveShape* pShape = (CMoveShape*)GetGame()->GetRegion()->FindChildObject(lType, ID); if (pShape) { pShape->SetHp(dwHP); } } } break; case MSG_S2C_SKILL_USE: { CHAR cResult = pMsg->GetChar(); DWORD dwCurTime = GetCurTickCount(); switch(cResult) { case SKILL_USE_RESULT_BEGIN: { CGUID ID; pMsg->GetGUID(ID); float fDir = pMsg->GetFloat(); // 释放者朝向 long lSkillKey = pMsg->GetDWord(); // 从服务器取得技能键值和ID long lSkillID = pMsg -> GetLong(); long lLevel = pMsg->GetByte(); // 技能等级 long lCurType = pMsg->GetByte(); // 技能的释放状态(吟唱/释放) long lTime = pMsg->GetLong(); // 技能的吟唱时间(吟唱阶段有用) long lRestoreTime = pMsg->GetLong(); // 技能的冷却时间 long lDestX = pMsg->GetShort(); // 释放目标的坐标(x,y) long lDestY = pMsg->GetShort(); long lTypeSize = pMsg->GetByte(); // 释放目标的个数 vector<long> vecType; // 目标类型列表 vector<CGUID> vecID; // 目标类型的GUID CGUID destID; for (int i =0; i<lTypeSize; i++) { vecType.push_back(pMsg->GetLong()); pMsg->GetGUID(destID); vecID.push_back(destID); } // 确定基本攻击技能 if(lSkillID == SKILL_BASE_BUFF) lSkillID = GetGame()->GetMainPlayer()->GetDefaultAttackSkillID(); // 技能释放者 CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID); if(pMoveShape) { long lType = pMoveShape->GetType(); //判断是否是怪物,如果是怪物,播放怪物音效 if(lType == TYPE_MONSTER) { GetGame()->GetAudioList()->Play(pMoveShape,TYPE_MONSTER,0xFFF0,Vector3(pMoveShape->GetPosY(),pMoveShape->GetHeight(),pMoveShape->GetPosX())); } if(lCurType == 1) // 吟唱阶段 { CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID); if(ptagS) { UpdateHotKeyCoolDownEffect(lSkillID); } if(pMoveShape->GetType() == TYPE_PET) { CPet *pPet = (CPet*)pMoveShape; //更新当前技能的开始冷却时间 tagPetSkillInfo *pSkill = pPet->GetPetSkillInfoByID(lSkillID); if(pSkill) pSkill->lRestorTimeLength = lRestoreTime; pPet->SkillSuccReceived(); } /***********************************************************************/ /* 赵航 fix */ //CSkillXml *m_pSkill = new CSkillXml(); /***********************************************************************/ ConcreteSkillComp* SkillCom = new ConcreteSkillComp(); //SkillCom的内存交给了CSkillXml的析构来管理 CSkillXml* pSkill = new ConcreteDecSkillXml(SkillCom); CSkillListXml::tagSkill *pTagSkill = CSkillListXml::GetProperty(lSkillID); if (pTagSkill && pTagSkill->dwSkillType == CSkillListXml::SKILLTYPE_PLAY) // 直接施放 { // 引导类技能添加吟唱条显示时间 DWORD dwlev = pTagSkill->vectorLevels.size() >= (DWORD)lLevel? (DWORD)lLevel-1:((DWORD)pTagSkill->vectorLevels.size() - 1); long lAiID = pTagSkill->vectorLevels[dwlev].dwSkillLevelAI; if(pTagSkill->bIsLead) pSkill->IntonateTime(lTime); // 直接从开始阶段执行 if(pSkill->StepBegin(lSkillID, lLevel, lType, ID, lDestX, lDestY,fDir,vecType, vecID)) { pSkill->SetSkillKey(lSkillKey); pMoveShape->AddCurSkillList(lSkillKey,pSkill); } else SAFE_DELETE(pSkill); // 如果开始阶段成功就直接执行施放阶段 if(pSkill&&pSkill->StepRun(lSkillID, lLevel, lType, ID, lDestX, lDestY, fDir, vecType, vecID) == false) { //pSkill->SetIsDeleted(true); pMoveShape->DeleteCurSkill(lSkillKey); } if(lType == TYPE_PLAYER ) { if (GetGame()->GetMainPlayer()->GetExID()==ID) { GetGame()->GetGameControl()->SetControlAble(true); GetGame()->GetGameControl()->SetMoveAble(true); /***********************************************************************/ /* zhaohang fix */ /***********************************************************************/ // 引导类技能 if(pTagSkill->bIsLead) GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey); else GetGame()->GetMainPlayer()->SetIntonateSkillKey(0); // 自动攻击累计发送次数清0 GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0); if(g_bDebug) { Log4c::Trace(ROOT_MODULE,"直接使用技能,次数清0:%d,key:%d",lSkillID,lSkillKey); } }else if (lSkillID>=50000&&lSkillID<=50006) { if (lSkillID>=50000&&lSkillID<=50002) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Collection); }else if (lSkillID>=50003&&lSkillID<=50005) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Facture); }else if (lSkillID==50006) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_TaskCollection,lLevel); } } ///////////////////////////////////////////////////////////////// //char strInfo[512]=""; //_snprintf(strInfo,512,"SKILLTYPE_PLAY_Set Intonate Skill Key:%d",0); //PutStringToFile("IntonateSkillTest",strInfo); ///////////////////////////////////////////////////////////////// } else if (lType == TYPE_PET) { CPet *pPet = (CPet*)pMoveShape; if (pPet->IsMainPlayerPet()) { /***********************************************************************/ /* zhaohang fix */ /***********************************************************************/ if(pTagSkill->bIsLead) pPet->SetIntonateSkillKey(lSkillKey); else pPet->SetIntonateSkillKey(0); } } } else if(pTagSkill && pTagSkill->dwSkillType == CSkillListXml::SKILLTYPE_INTONATE) // 吟唱施放 { pSkill->IntonateTime(lTime); if(g_bDebug && lType == TYPE_PLAYER) { dwCurTime = GetCurTickCount(); Log4c::Trace(ROOT_MODULE,"吟唱技能设置时间:%d,%d,%d",lSkillID,lTime,dwCurTime); } /***********************************************************************/ /* zhaohang fix */ /***********************************************************************/ bool bIsLead = pTagSkill->bIsLead; pTagSkill->bIsLead = false; if(pSkill->StepBegin(lSkillID, lLevel, lType, ID, lDestX, lDestY,fDir,vecType, vecID)) { /***********************************************************************/ /* zhaohang fix */ /***********************************************************************/ pTagSkill->bIsLead = bIsLead; pSkill->SetSkillKey(lSkillKey); pMoveShape->AddCurSkillList(lSkillKey,pSkill); } else SAFE_DELETE(pSkill); if( lType == TYPE_PLAYER ) { if (GetGame()->GetMainPlayer()->GetExID()==ID) { // 吟唱阶段允许玩家移动取消技能 GetGame()->GetGameControl()->SetControlAble(true); GetGame()->GetGameControl()->SetMoveAble(true); GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey); // 自动攻击累计发送次数清0 GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0); /*if(g_bDebug) { char strInfo[512]=""; _snprintf(strInfo,512,"技能吟唱中,次数清0:%d,key:%d",lSkillID,lSkillKey); PutStringToFile("SkillTimesTest",strInfo); }*/ }else if (lSkillID>=50000&&lSkillID<=50006) { if (lSkillID>=50000&&lSkillID<=50002) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Collection); }else if (lSkillID>=50003&&lSkillID<=50005) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_Facture); }else if (lSkillID==50006) { ((CPlayer*)pMoveShape)->SetToolsID(CDeputyOccuSystemClient::OB_TaskCollection,lLevel); } } ///////////////////////////////////////////////////////////////// //char strInfo[512]=""; //_snprintf(strInfo,512,"SKILLTYPE_INTONATE_Set Intonate Skill Key:%d",lSkillKey); //PutStringToFile("IntonateSkillTest",strInfo); ///////////////////////////////////////////////////////////////// } } else { SAFE_DELETE(pSkill); return; } pMoveShape->SetDirEx(fDir); // 更新快捷栏的冷却动画 if(pMoveShape==GetGame()->GetMainPlayer()) { GetGame()->GetMainPlayer()->UpdateSkillCoolDownTime(true); //CSkillListXml::tagSkill *pS = CSkillListXml::GetProperty(lSkillID); /***********************************************************************/ /* zhaohang fix */ /***********************************************************************/ if(ptagS && pTagSkill && pTagSkill->dwSkillState != 0 && !pTagSkill->bLockSkill) { ptagS->dwUseingStartTime = timeGetTime(); } } } else // 施放阶段 { /***********************************************************************/ /* 赵航 fix */ //CSkillXml *m_pSkill = new CSkillXml(); /***********************************************************************/ ConcreteSkillComp* SkillCom = new ConcreteSkillComp(); //SkillCom的内存交给了CSkillXml的析构来管理 CSkillXml* pSkill = new ConcreteDecSkillXml(SkillCom); pSkill->IntonateTime(lTime); if(pSkill&&pSkill->StepRun(lSkillID, lLevel, lType, ID, lDestX, lDestY, fDir, vecType, vecID) ) { pSkill->SetSkillKey(lSkillKey); pMoveShape->AddCurSkillList(lSkillKey,pSkill); CSkillListXml::tagSkill *pTagSkill = CSkillListXml::GetProperty(lSkillID); // 引导类技能 if(pTagSkill && pTagSkill->bIsLead) GetGame()->GetMainPlayer()->SetIntonateSkillKey(lSkillKey); } else { SAFE_DELETE(pSkill); } if(lType == TYPE_PLAYER ) { if (GetGame()->GetMainPlayer()->GetExID()==ID) { GetGame()->GetGameControl()->SetControlAble(true); GetGame()->GetMainPlayer()->SetIntonateSkillKey(0); // 自动攻击累计发送次数清0 GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0); if(g_bDebug) { Log4c::Trace(ROOT_MODULE,"吟唱技能释放阶段,次数清0,吟唱清空:%d,key:%d",lSkillID,lSkillKey); } } if (lSkillID>=50000&&lSkillID<=50006) { ((CPlayer*)pMoveShape)->SetToolsID(0); } ///////////////////////////////////////////////////////////////// //char strInfo[512]=""; //_snprintf(strInfo,512,"STEP_PLAY Set Intonate Skill Key:%d",0); //PutStringToFile("IntonateSkillTest",strInfo); ///////////////////////////////////////////////////////////////// } } } else { /////////////////////////////////////////////////////////////start //test add or delete shape,(author:wangqiao) char pszTestInfo[1024]=""; char pszGUID[64]=""; ID.tostring(pszGUID); //_snprintf(pszTestInfo,1024,"When Use skill,the Firer is not exist.(type:%d,id:%s)", // lType,pszGUID); //PutStringToFile("AddDelShapeTest",pszTestInfo); ////////////////////////////////////////////////////////////end } } break; case SKILL_USE_RESULT_END: { CGUID ID; pMsg->GetGUID(ID); float fDir = pMsg->GetFloat(); long lSkillKey = pMsg->GetDWord(); // 从服务器取得技能键值 long lSkillID = pMsg -> GetLong(); long lLevel = pMsg->GetByte(); long lCurType = pMsg->GetByte(); CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID); if(pMoveShape) { long lType = pMoveShape->GetType(); CSkillXml* pSkill = pMoveShape->GetCurSkill(lSkillKey); if(pSkill) { pSkill->StepEnd(lSkillID, lLevel, lType, ID, fDir); pMoveShape->DeleteCurSkill(lSkillKey); } if(lType == TYPE_PLAYER ) { if (lSkillID>=50000&&lSkillID<=50006) { ((CPlayer*)pMoveShape)->SetToolsID(0); } if(GetGame()->GetMainPlayer()->GetExID() == ID) { // 自动攻击累计发送次数清0 GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0); GetGame()->GetGameControl()->SetControlAble(true); // 结束的技能是正在吟唱的技能,取消吟唱 if(lSkillKey == GetGame()->GetMainPlayer()->GetIntonateKey()) //|| lSkillID == GetGame()->GetMainPlayer()->GetIntonateState()) { GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0); GetGame()->GetMainPlayer()->SetIntonateSkillKey(0); if(g_bDebug) { Log4c::Trace(ROOT_MODULE,"技能结束,吟唱清空,次数清0:%d,key:%d",lSkillID,lSkillKey); } } else { // 光环类技能重设使用状态 CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID); if(ptagS) ptagS->dwUseingStartTime = 0; } // 当使用的是制作的技能时,进行特殊的处理 if (lSkillID>=50003&&lSkillID<=50005) { //CFacturePageEx* pFacturePage = GetGame()->GetCGuiEx()->GetFacturePageEx(); //if (lCurType==2&&pFacturePage!=NULL) //{ // pFacturePage->UpdateInputNum(); // pFacturePage->SetFactureState(false); // if ((CFacturePageEx::eErrorNotice)pFacturePage->IsCanFacture()==CFacturePageEx::eErrorNotice_NoError) // { // pFacturePage->SendFactureOneMes(); // } //pFacturePage->UpdateFactureLevelExpProcessBar(); //} } } } if (lType == TYPE_PET) { CPet *pPet = (CPet*)pMoveShape; if (pPet->IsMainPlayerPet()) { if(lSkillKey == pPet->GetIntonateKey() && lSkillID == pPet->GetIntonateState()) { GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0); GetGame()->GetMainPlayer()->SetIntonateSkillKey(0); } tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(lSkillID); if(pPetSkill) pPetSkill->bIsSkillUsingEnd = true; } } } } break; case SKILL_USE_RESULT_FAILED: CGUID ID; pMsg->GetGUID(ID); long lSkillID = pMsg->GetLong(); long lLevel = pMsg->GetByte(); long lSkillKey = pMsg->GetLong(); long lFaildRet = pMsg->GetByte(); // 将该技能结束 CMoveShape* pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(ID); if(pMoveShape) { long lType = pMoveShape->GetType(); CSkillXml* pSkill = pMoveShape->GetCurSkill(lSkillKey); if(pSkill) { pSkill->StepEnd(lSkillID, lLevel, lType, ID, pMoveShape->GetDirEx()); pMoveShape->DeleteCurSkill(lSkillKey); } if(pMoveShape->GetType() == TYPE_PET) { CPet *pPet = (CPet*)pMoveShape; tagPetSkillInfo *pPetSkill = pPet->GetPetSkillInfoByID(lSkillID); if(pPetSkill) pPetSkill->bIsSkillUsingEnd = true; pPet->SkillFailReceived(); } // 其他对象的技能,不提示 if( pMoveShape == GetGame()->GetMainPlayer()) { // 自动攻击累计发送次数清0 GetGame()->GetGameControl()->SetSendedUseSkillMsgCount(0); // 如果是本玩家释放的技能,且失败技能为连续技能,停止本玩家自动攻击状态 CSkillListXml::tagSkill *pS = CSkillListXml::GetProperty(lSkillID); if(pS && pS->bLockSkill) { // 连续攻击技能的mp不足,切换到基本攻击 if(lFaildRet == SKILL_USE_FAILED_INVALID_MP) { DWORD dwID = GetGame()->GetMainPlayer()->GetDefaultAttackSkillID(); GetGame()->GetGameControl()->SetBufferSkillID(dwID); CPlayer::tagSkill * pPlayerSkill = GetGame()->GetMainPlayer()->GetSkill(dwID); if(pPlayerSkill) pPlayerSkill->dwUseingStartTime = timeGetTime(); } if(lFaildRet == SKILL_USE_FAILED_INVALID_HP || lFaildRet == SKILL_USE_FAILED_INVALID_RP) GetGame()->GetGameControl()->AutoAttactStop(); } // 光环类技能重设使用状态 CPlayer::tagSkill *ptagS = GetGame()->GetMainPlayer()->GetSkill(lSkillID); if(ptagS && pS && !pS->bLockSkill) ptagS->dwUseingStartTime = 0; // 结束的技能是正在吟唱的技能,取消吟唱 if(lSkillKey > 0 && lSkillKey == GetGame()->GetMainPlayer()->GetIntonateKey()) { GetGame()->GetMainPlayer()->SetCurIntonateTime(0,0); GetGame()->GetMainPlayer()->SetIntonateSkillKey(0); if(g_bDebug) { Log4c::Trace(ROOT_MODULE,"技能使用失败,次数清0,吟唱清空:%d,类型:%d,key:%d",lSkillID,lFaildRet,lSkillKey); } } if (lSkillID>=50000&&lSkillID<=50006) { ((CPlayer*)pMoveShape)->SetToolsID(0); } // 如果正处于制作过程中 //CFacturePageEx* pFacturePage = GetGame()->GetCGuiEx()->GetFacturePageEx(); /*if (pFacturePage!=NULL && pFacturePage->IsOpen()) { pFacturePage->SetFactureState(false); if (pFacturePage->GetCurFactureNum()!=0 || pFacturePage->GetAllFactureState()) { pFacturePage->ClearFactureNum(); } }*/ } } GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-48.wav"); if(pMoveShape && (pMoveShape == GetGame()->GetMainPlayer() || pMoveShape->GetType() == TYPE_PET && ((CPet*)pMoveShape)->IsMainPlayerPet() )) { switch (lFaildRet) { case SKILL_USE_FAILED_INVALID_STATE: { // 自动攻击技能 if(GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID) GetGame()->GetGameControl()->SetAutoSkillID(0); //GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, //CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_STATE), //D3DCOLOR_ARGB(255,255,0,0)); } break; case SKILL_USE_FAILED_INVALID_HP: //GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_HP), // D3DCOLOR_ARGB(255,255,0,0)); break; case SKILL_USE_FAILED_INVALID_MP: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MP), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_RP: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NP), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_YP: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_YVALUE), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_TARGET: { // 自动攻击技能 if(GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID) GetGame()->GetGameControl()->SetAutoSkillID(0); //GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OBJERROR), // D3DCOLOR_ARGB(255,255,0,0)); } break; case SKILL_USE_FAILED_INVALID_DISTANT: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OUTAREA), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_SKILL: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NOSKILL), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_TIME: //##允许再次使用技能的时间未到达 { /*if(GetGame()->GetGameControl()->GetAutoSkillID() != lSkillID) GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_COOLTIME), D3DCOLOR_ARGB(255,255,0,0)); else GetGame()->GetGameControl()->SetBufferSkillID(SKILL_BASE_BUFF);*/ if( GetGame()->GetGameControl()->GetAutoSkillID() == lSkillID) GetGame()->GetGameControl()->SetBufferSkillID(SKILL_BASE_BUFF); } break; case SKILL_USE_FAILED_CANNOTCOLLECTION_STATE: //当前状态(人物的状态)不能采集 { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(205,18), D3DCOLOR_ARGB(255,255,0,0));*/ } break; case SKILL_USE_FAILED_CANNOTFACTURE_STATE: //当前状态(人物的状态)不能制作 { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(205,19), D3DCOLOR_ARGB(255,255,0,0));*/ } break; case SKILL_USE_FAILED_INVALID_EQUIP: //##无效的装备 /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_ARM), D3DCOLOR_ARGB(255,255,0,0));*/ // 取消连续攻击技能 GetGame()->GetGameControl()->SetAutoSkillID(0); break; case SKILL_USE_FAILED_BLOCKED: //##被阻挡了 /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_BLOCK), D3DCOLOR_ARGB(255,255,0,0));*/ // 取消连续攻击技能 GetGame()->GetGameControl()->SetAutoSkillID(0); break; case SKILL_USE_FAILED_BREAK: { if (lSkillID>=50000&&lSkillID<=50007) { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(205,40), D3DCOLOR_ARGB(255,255,0,0));*/ } else { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_DELSKILL), D3DCOLOR_ARGB(255,255,0,0));*/ } // 取消连续攻击技能 if(lSkillID != GetGame()->GetGameControl()->GetAutoSkillID()) { GetGame()->GetGameControl()->SetAutoSkillID(0); GetGame()->GetMainPlayer()->SetAction(CShape::ACT_STAND); } } break; case SKILL_USE_FAILED_NOOBJECT: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_NOOBJ), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_INTONATE: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_INTTIME), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_OCCUPATION: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_OUCC), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_FACTURE: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MADE), D3DCOLOR_ARGB(255,255,0,0)); GetGame()->GetCGuiEx()->GetFacturePageEx()->Close();*/ break; case SKILL_USE_FAILED_INVALID_COLLECT: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_COLLECTION), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_ACT: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_ACTING), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_INVALID_MOVING: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_USE_UNSUCCESS_MOVEING), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_NOCOLLECTION: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOOBJ), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_STATE_ERROR: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_STATE), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_UNKNOW_COLLECTION: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOINFO), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_DOCCU_ERROR: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_OCCUEX), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_LEVEL_ERROR: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_LEV), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_GOODSCONDITION_ERROR: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_GOODS), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_NO_BAGSPACE: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_PACK), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_NOT_ROLECOLLECTION: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_NOTQUESTOBJ), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_QUESTSTEP_ERROR: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_SPECQUEST), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_C_UNKOWN_COLLECTTYPE: /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_CONDITION_TYPE), D3DCOLOR_ARGB(255,255,0,0));*/ break; case SKILL_USE_FAILED_F_NO_FACTURE: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NOOBJ), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_DOCCU_ERROR: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_OCCUEX), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_NOTHAS_FACTURE: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NOSKILL), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_GOODSCONDITION_ERROR: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_TOOL), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_MATERIALS_ERROR: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_GOODS), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_NPC_ERROR: { /*GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_NPCDEST), D3DCOLOR_ARGB(255,255,0,0));*/ GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; case SKILL_USE_FAILED_F_NO_BAGSPACE: { // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_MADE_PACK), // D3DCOLOR_ARGB(255,255,0,0)); GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-12.wav"); } break; // 场景错误 case SKILL_USE_FAILED_INVALID_REGION: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_ERROR_BYREGION), // D3DCOLOR_ARGB(255,255,0,0)); break; default: break; } } break; } } break; case MSG_S2C_SKILL_ADD_EX_STATE: // 加入一个异常状态 { // 状态承受着的类型和GUID long lType = pMsg->GetLong(); CGUID ID; pMsg->GetGUID(ID); // 状态ID DWORD dwStateID = pMsg->GetDWord(); DWORD dwLevel = pMsg->GetDWord(); // 状态等级 DWORD dwRemainedTime = pMsg->GetDWord(); BYTE bFlag = pMsg->GetByte(); CMoveShape *pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(lType, ID); if (pMoveShape) { pMoveShape->AddStateEx(dwStateID, dwLevel, dwRemainedTime,0,bFlag); } } break; case MSG_S2C_SKILL_END_EX_STATE: // 结束一个异常状态 { long lType = pMsg->GetLong(); CGUID ID; pMsg->GetGUID(ID); DWORD dwStateID = pMsg->GetDWord(); DWORD dwlev = pMsg->GetDWord(); CMoveShape *pMoveShape = (CMoveShape*)pMsg->GetRegion()->FindChildObject(lType, ID); if (pMoveShape) { pMoveShape->RemoveStateEx(dwStateID,dwlev); } } break; case MSG_S2C_SKILL_EX_STATE_ADDITIONAL_DATA: { long lType = pMsg->GetLong(); CGUID ID; pMsg->GetGUID(ID); long lStateID = pMsg->GetLong(); DWORD dwValue = pMsg->GetDWord(); if( lStateID == STATE_TEAM ) { CPlayer *pPlayer = dynamic_cast<CPlayer*>(pMsg->GetRegion()->FindChildObject(lType, ID)); if (pPlayer) pPlayer->SetTeammateAmount(dwValue&0xffff); } } break; // 打开技能学习页面 case MSG_S2C_SKILL_STUDY_BEGIN: { CGUID guid; pMsg->GetGUID(guid); long num = pMsg->GetLong(); if(num > 0) { //GetGame()->GetCGuiEx()->GetLearnSkillPage()->Close(); for(long i=0; i<num; ++i) { BYTE bType = pMsg->GetByte(); DWORD dwSkillID = pMsg->GetDWord(); //if(dwSkillID > 0) // GetGame()->GetCGuiEx()->GetLearnSkillPage()->PushSkillID(dwSkillID,bType); } //GetGame()->GetCGuiEx()->GetLearnSkillPage()->Open(); //GetGame()->GetCGuiEx()->GetLearnSkillPage()->SetNpcGUID(guid); //GetGame()->GetCGuiEx()->GetLearnSkillPage()->OpenPage(CLearnSkillPage::TYPE_FIGHTSKILLPAGE); GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-20.wav"); } // 职业不符,弹出警告对话框 else { } } break; // 打开制作技能学习页面 case MSG_S2C_OCCUSKILL_STUDY_BEGIN: { CGUID guid; pMsg->GetGUID(guid); //GetGame()->GetCGuiEx()->GetLearnSkillPage()->Close(); long num = pMsg->GetDWord(); for(WORD i=0; i<num; ++i) { DWORD dwSkillID = pMsg->GetDWord(); DWORD dwSkillCost = pMsg->GetDWord(); //if(dwSkillID > 0) // GetGame()->GetCGuiEx()->GetLearnSkillPage()->AddOccuSkill(dwSkillID,dwSkillCost); } //GetGame()->GetCGuiEx()->GetLearnSkillPage()->SetNpcGUID(guid); //GetGame()->GetCGuiEx()->GetLearnSkillPage()->OpenPage(CLearnSkillPage::TYPE_ASSITSKILLPAGE); } break; case MSG_S2C_OCCUSKILL_STUDY: { long lBeSucceed = pMsg->GetLong(); DWORD dwFactureID = pMsg->GetDWord(); if (lBeSucceed!=0) { //GetGame()->GetCGuiEx()->GetLearnSkillPage()->ChoseNextSkill(dwFactureID); } //GetGame()->GetCGuiEx()->GetLearnSkillPage()->StudyOccuSkillResult(lBeSucceed,dwFactureID); //long lOccType = GetGame()->GetCGuiEx()->GetMainBarPageEx()->GetOuccType(); //GetGame()->GetCGuiEx()->GetMainBarPageEx()->SetOccuButtonSpecialState(true,lOccType); //GetGame()->GetAudioList()->Play2DSound("SOUNDS\\interfaces\\i-27.wav"); } break; case MSG_S2C_OCCUSKILL_DELETE: { GetGame()->GetMainPlayer()->DeleteAllFactureSkill(); //DWORD dwBeSucceed = pMsg->GetDWord(); //DWORD dwFactureID = pMsg->GetDWord(); //GetGame()->GetCGuiEx()->GetLearnSkillPage()->StudyOccuSkillResult(dwBeSucceed,dwFactureID); }break; // 技能学习失败 case MSG_S2C_SKILL_STUDY_FAILED: { long lFaildRet = pMsg->GetLong(); switch (lFaildRet) { //职业不符合学习条件 case SKILL_STUDY_FAILED_OCCUPATION: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_OUCC), // D3DCOLOR_ARGB(255,255,0,0)); break; //等级不符合学习条件 case SKILL_STUDY_FAILED_RANK: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_LEV), // D3DCOLOR_ARGB(255,255,0,0)); break; //SP不符合学习条件 case SKILL_STUDY_FAILED_SP: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_SP), // D3DCOLOR_ARGB(255,255,0,0)); break; //前置技能不符合学习条件 case SKILL_STUDY_FAILED_SKILL: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_PRESKILL), // D3DCOLOR_ARGB(255,255,0,0)); break; //前置限制技能不符合条件 case SKILL_STUDY_FAILED_LIMIT_SKILL: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_LIMITSKILL), // D3DCOLOR_ARGB(255,255,0,0)); break; //物品 case SKILL_STUDY_FAILED_GOOD: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_GOODS), // D3DCOLOR_ARGB(255,255,0,0)); break; //金币不足 case SKILL_STUDY_FAILED_GOLD: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_NOGOLDS), // D3DCOLOR_ARGB(255,255,0,0)); break; //银币不足 case SKILL_STUDY_FAILED_SILVER: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_NOSILVER), // D3DCOLOR_ARGB(255,255,0,0)); //职业等级不符合条件 case SKILL_STUDY_FAILED_OCCULV: // GetGame()->GetCGuiEx()->GetMainBarPageEx()->AddText(eNOTIFYPOS_CENTER, // CStringReading::LoadText(eIDS_SKILL,eIDS_STUDY_FAILED_OCCULV), // D3DCOLOR_ARGB(255,255,0,0)); break; } } break; // 宠物添加技能 case MSG_S2C_SKILL_ADD_PET: { //得到宠物GUID CGUID guid; pMsg->GetGUID(guid); tagPetSkillInfo skill; pMsg->GetEx(&skill, sizeof(tagSkill)); //技能冷却总时间长度 skill.lRestorTimeLength = pMsg->GetLong(); //技能当前冷却时间 skill.lStartCoolTime = 0; // 技能范围改为float TODO:修改客户端技能范围相关逻辑 //最小攻击距离 skill.lMinAtkDistance = (long)pMsg->GetFloat(); //最大攻击距离 skill.lMaxAtkDistance = (long)pMsg->GetFloat(); //需要花费MP值 skill.lCostMp = pMsg->GetLong(); CPet* pPet = dynamic_cast<CPet*>(GetGame()->GetRegion()->FindChildObject(TYPE_PET,guid)) ; if (pPet == NULL) return; if (skill.lPos == 0) { skill.bAuto = true; //如果是第一个技能 则打开自动释放 } pPet->AddSkill(skill); //CPetPageEx *pPage = GetGame()->GetCGuiEx()->GetPetPageEx(); //if (pPage) // pPage->LearnedNewSkill(pPet,&skill); } break; /***********************************************************************/ /* zhaohang 2010-10-18 //技能免疫*/ /***********************************************************************/ //case MSG_S2C_SHAPE_ATK_IMMUNITY: // { // } // break; } }
void CPedSync::Packet_PedSync ( CPedSyncPacket& Packet ) { // Grab the player CPlayer* pPlayer = Packet.GetSourcePlayer (); if ( pPlayer && pPlayer->IsJoined () ) { // Apply the data for each ped in the packet vector < CPedSyncPacket::SyncData* > ::const_iterator iter = Packet.IterBegin (); for ( ; iter != Packet.IterEnd (); iter++ ) { CPedSyncPacket::SyncData* pData = *iter; // Grab the ped this packet is for CElement* pPedElement = CElementIDs::GetElement ( pData->Model ); if ( pPedElement && IS_PED ( pPedElement ) ) { // Convert to a CPed CPed* pPed = static_cast < CPed* > ( pPedElement ); // Is the player syncing this ped? // this packet if the time context matches. if ( pPed->GetSyncer () == pPlayer && pPed->CanUpdateSync ( pData->ucSyncTimeContext ) ) { // Apply the data to the ped if ( pData->ucFlags & 0x01 ) { pPed->SetPosition ( pData->vecPosition ); g_pGame->GetColManager()->DoHitDetection ( pPed->GetLastPosition (), pPed->GetPosition (), 0.0f, pPed ); } if ( pData->ucFlags & 0x02 ) pPed->SetRotation ( pData->fRotation ); if ( pData->ucFlags & 0x04 ) pPed->SetVelocity ( pData->vecVelocity ); if ( pData->ucFlags & 0x08 ) { // Less health than last time? float fPreviousHealth = pPed->GetHealth (); pPed->SetHealth ( pData->fHealth ); if ( pData->fHealth < fPreviousHealth ) { // Grab the delta health float fDeltaHealth = fPreviousHealth - pData->fHealth; if ( fDeltaHealth > 0.0f ) { // Call the onPedDamage event CLuaArguments Arguments; Arguments.PushNumber ( fDeltaHealth ); pPed->CallEvent ( "onPedDamage", Arguments ); } } } if ( pData->ucFlags & 0x10 ) pPed->SetArmor ( pData->fArmor ); // Send this sync pData->bSend = true; } } } // Tell everyone m_pPlayerManager->BroadcastOnlyJoined ( Packet, pPlayer ); } }
/* * 功能: 渲染列表中的对象 * 摘要: - * 参数: - * 返回值: - * 作者: lpf * 创建日期: 2008.10.13 * 修改日志: * 2008.10.21 - lpf * 增加了在渲染特效时,对其进行纹理动画,可见动画,UV流动等等的处理; * 2008.10.23 - lpf * 增加了对坐骑显示的处理; * 2008.10.31 - lpf * 增加了处理渐出效果时,对投影纹理的渐出; * 2008.12.12 - lpf * 取消了渐出时的阴影渲染; * 2008.12.30 - lpf * 增加了对渐出模型列表中,显示模型是否读取完毕的判断,避免由此带来的当机问题; * 2009.04.24 - lpf * 玩家显示时,传入对象指针采用了dynamic_cast形式,检查错误的转换; */ void CAlphaFadeObjectList::Render() { CClientRegion * pRegion = GetGame()->GetRegion(); if (pRegion == NULL) return; for (size_t st = 0; st < m_vecObjectList.size(); ++st) { CShape * pTmp = m_vecObjectList[st]; if (pTmp->GetDisplayModel() == NULL || pTmp->GetDisplayModel()->GetLoadState() != Load_Did) continue; pTmp->GetDisplayModel()->SetDirLightEnable(GetGame()->GetSetup()->lLight>0); pTmp->GetAnimInfo()->SetViewMatrix(pRegion->GetCamera()->GetViewMatrix()); pTmp->GetAnimInfo()->SetProjectedMatrix(pRegion->GetCamera()->GetProjectionMatrix()); switch (pTmp->GetType()) { case TYPE_PLAYER: { CPlayer * pPlayer = (CPlayer *)pTmp; if (pPlayer->IsRide()) pPlayer->GetHorse()->Display(dynamic_cast<CMoveShape *>(pTmp), false); pTmp->GetDisplayModel()->ProcessAnimJoint(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessLocator(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->MultiplyModelAlpha(pTmp->GetAlphaValue()); pTmp->GetDisplayModel()->RenderModelTransparent(); pPlayer->GetLeftHandWeapon()->Display(dynamic_cast<CShape *>(pTmp)); pPlayer->GetRightHandWeapon()->Display(dynamic_cast<CShape *>(pTmp)); pPlayer->GetWing()->Display(dynamic_cast<CShape *>(pTmp)); //RenderShadow(pTmp); //渲染阴影 } break; case TYPE_PET: case TYPE_MONSTER: case TYPE_COLLECTION: { pTmp->GetDisplayModel()->ProcessAnimJoint(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessLocator(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->MultiplyModelAlpha(pTmp->GetAlphaValue()); pTmp->GetDisplayModel()->RenderModelTransparent(); //RenderShadow(pTmp); //渲染阴影 } break; case TYPE_EFFECT: { float fX = pTmp->GetPosX(); float fY = pTmp->GetPosY(); float fH = pTmp->GetHeight(); float fNowDir = pTmp->GetNowDir(); CEffect * pEffect = dynamic_cast<CEffect *>(pTmp); if (pEffect && pEffect->GetHostType() !=0 && pEffect->GetHostID() != CGUID::GUID_INVALID) { CShape * pShape = dynamic_cast<CShape *>(pRegion->FindChildObject(pEffect->GetHostType(), pEffect->GetHostID())); if (pShape) { pShape->GetLocatorPos(pEffect->GetHostLocator(), fX, fY, fH); fNowDir = pShape->GetNowDir(); } } pTmp->GetAnimInfo()->SetupAnimInfo(fX, fY, fH, fNowDir, pRegion->GetCamera()); pTmp->GetAnimInfo()->SetTextureProjectiveAlpha(pTmp->GetAlphaValue()); pTmp->GetDisplayModel()->ProcessAnimJoint(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessLocator(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessVisibility(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessAnimUV(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessAnimTexture(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->ProcessTextureProjective(pTmp->GetAnimInfo()); pTmp->GetDisplayModel()->MultiplyModelAlpha(pTmp->GetAlphaValue()); pTmp->GetDisplayModel()->RenderModelTransparent(); } break; } } }
int32_t CBuildPlayerDataNoticeMessageEvent::OnMessageEvent(MessageHeadSS * pMsgHead, IMsgBody* pMsgBody, const uint16_t nOptionLen, const void *pOptionData) { if(pMsgBody==NULL || pMsgHead==NULL) { WRITE_ERROR_LOG("null pointer:{pMsgBody=0x%08x, pMsgHead=0x%08x}\n",pMsgBody,pMsgHead); return E_NULLPOINTER; } CBuildPlayerDataNoti *pBuildPlayerDataNotice = dynamic_cast<CBuildPlayerDataNoti *>(pMsgBody); if(NULL == pBuildPlayerDataNotice) { WRITE_ERROR_LOG("pMsgBody transform to class child failed{ret=0x%08x}\n",E_NULLPOINTER); return E_NULLPOINTER; } WRITE_DEBUG_LOG("recv BuildPlayerDataNotice{nPlayerCount=%d}\n",pBuildPlayerDataNotice->nPlayerCount); for(int32_t i = 0; i < pBuildPlayerDataNotice->nPlayerCount; ++i) { CPlayer *pLocalPlayer = NULL; PlayerIndex nLocalPlayerIndex = enmInvalidPlayerIndex; int32_t ret = g_PlayerMgt.GetPlayer(pBuildPlayerDataNotice->arrRoleID[i], pLocalPlayer, nLocalPlayerIndex); //本地roomserver上没有这个玩家 if(ret < 0 || pLocalPlayer == NULL) { ret = g_PlayerMgt.CreatePlayer(pBuildPlayerDataNotice->arrRoleID[i], pLocalPlayer, nLocalPlayerIndex); if(ret < 0 || pLocalPlayer == NULL) { WRITE_ERROR_LOG("null pointer:{pLocalPlayer=0x%08x, pMsgHead=0x%08x}\n",pLocalPlayer); continue; } uint32_t nStartPos = pLocalPlayer->GetStartPos(); uint32_t nEndPos = pLocalPlayer->GetEndPos(); uint32_t nPlayerDataSize = nEndPos - nStartPos; if(nPlayerDataSize >= pBuildPlayerDataNotice->arrPlayerDataSize[i]) { memcpy(((uint8_t *)pLocalPlayer) + nStartPos, pBuildPlayerDataNotice->arrPlayerData[i], pBuildPlayerDataNotice->arrPlayerDataSize[i]); } RoomID arrRoomID[MaxEnterRoomCount]; int32_t nEnterRoomCount = 0; pLocalPlayer->GetAllEnterRoom(arrRoomID, MaxEnterRoomCount, nEnterRoomCount); WRITE_DEBUG_LOG("building player data:{nEnterCount=%d}\n",nEnterRoomCount); for(int32_t j = 0; j < nEnterRoomCount; ++j) { CRoom *pRoom = NULL; RoomIndex nRoomIndex = enmInvalidRoomIndex; ret = g_RoomMgt.GetRoom(arrRoomID[j], pRoom, nRoomIndex); if(ret < 0 || nRoomIndex == enmInvalidRoomIndex) { WRITE_WARNING_LOG("building player data:but it's not found room object,or room is not rebulid!{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrRoomID[j]); continue; } if(pRoom->IsPlayerInRoom(nLocalPlayerIndex)||pRoom->IsRebotPlayerInRoom(pBuildPlayerDataNotice->arrRoleID[i])) { WRITE_NOTICE_LOG("building player data:player in this room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i], arrRoomID[j]); continue; } //将玩家添加到房间对象中去 if(pLocalPlayer->IsReboot()) { pRoom->AddRebotPlayer(pBuildPlayerDataNotice->arrRoleID[i]); } else { pRoom->AddPlayer(nLocalPlayerIndex, pLocalPlayer->GetVipLevel(), pLocalPlayer->IsHideEnter()); } WRITE_NOTICE_LOG("building player data:player rebulid in room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrRoomID[j]); } } else { CPlayer stPlayer; CPlayer *pRemotePlayer = &stPlayer; uint32_t nStartPos = pRemotePlayer->GetStartPos(); uint32_t nEndPos = pRemotePlayer->GetEndPos(); uint32_t nPlayerDataSize = nEndPos - nStartPos; if(nPlayerDataSize >= pBuildPlayerDataNotice->arrPlayerDataSize[i]) { memcpy(((uint8_t *)pRemotePlayer) + nStartPos, pBuildPlayerDataNotice->arrPlayerData[i], pBuildPlayerDataNotice->arrPlayerDataSize[i]); } PlayerRoomInfo arrPlayerRoomInfo[MaxEnterRoomCount]; int32_t nRoomInfoCount = 0; pRemotePlayer->GetPlayerRoomInfo(arrPlayerRoomInfo, MaxEnterRoomCount, nRoomInfoCount); //只合并目前本地服务器上已有的房间数据 int32_t nEnterRoomCount = nRoomInfoCount; nRoomInfoCount = 0; for(int32_t j = 0; j < nEnterRoomCount; ++j) { CRoom *pRoom = NULL; RoomIndex nRoomIndex = enmInvalidRoomIndex; ret = g_RoomMgt.GetRoom(arrPlayerRoomInfo[j].nRoomID, pRoom, nRoomIndex); if(ret < 0 || pRoom == NULL) { WRITE_WARNING_LOG("building player data:but it's not found room object,or room is not rebulid!{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrPlayerRoomInfo[j].nRoomID); continue; } //将玩家添加到房间对象中去(修改于2012.6.5) if(pRoom->IsPlayerInRoom(nLocalPlayerIndex)||pRoom->IsRebotPlayerInRoom(pBuildPlayerDataNotice->arrRoleID[i])) { WRITE_NOTICE_LOG("building player data:player in this room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i], arrPlayerRoomInfo[j].nRoomID); continue; } if(pRemotePlayer->IsReboot()) { pRoom->AddRebotPlayer(pBuildPlayerDataNotice->arrRoleID[i]); } else { pRoom->AddPlayer(nLocalPlayerIndex, pRemotePlayer->GetVipLevel(), pRemotePlayer->IsHideEnter()); } arrPlayerRoomInfo[nRoomInfoCount] = arrPlayerRoomInfo[j]; ++nRoomInfoCount; WRITE_NOTICE_LOG("building player data:player rebulid in room{nRoleID=%d, nRoomID=%d}\n", pBuildPlayerDataNotice->arrRoleID[i],arrPlayerRoomInfo[j].nRoomID); } //合并player pLocalPlayer->MergePlayerRoomInfo(arrPlayerRoomInfo, nRoomInfoCount); } } return S_OK; }
//------------------------------------------------------------------------ void CMelee::Hit(const Vec3 &pt, const Vec3 &dir, const Vec3 &normal, IPhysicalEntity *pCollider, int partId, int ipart, int surfaceIdx, float damageScale, bool remote) { // generate the damage IEntity *pTarget = gEnv->pEntitySystem->GetEntityFromPhysics(pCollider); // Report punch to AI system. // The AI notification must come before the game rules are // called so that the death handler in AIsystem understands that the hit // came from the player. CActor *pActor = m_pWeapon->GetOwnerActor(); if (pActor && pActor->GetActorClass() == CPlayer::GetActorClassType()) { CPlayer *pPlayer = (CPlayer *)pActor; if (pPlayer && pPlayer->GetNanoSuit()) { if (pPlayer->GetEntity() && pPlayer->GetEntity()->GetAI()) { SAIEVENT AIevent; AIevent.targetId = pTarget ? pTarget->GetId() : 0; // pPlayer->GetNanoSuit()->GetMode() == NANOMODE_STRENGTH pPlayer->GetEntity()->GetAI()->Event(AIEVENT_PLAYER_STUNT_PUNCH, &AIevent); } } } bool ok = true; if(pTarget) { if(!gEnv->bMultiplayer && pActor && pActor->IsPlayer()) { IActor* pAITarget = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pTarget->GetId()); if(pAITarget && pTarget->GetAI() && !pTarget->GetAI()->IsHostile(pActor->GetEntity()->GetAI(),false)) { ok = false; m_noImpulse = true; } } if(ok) { CGameRules *pGameRules = g_pGame->GetGameRules(); int damage = m_meleeparams.damage; if(pActor && !pActor->IsPlayer()) damage = m_meleeparams.damageAI; HitInfo info(m_pWeapon->GetOwnerId(), pTarget->GetId(), m_pWeapon->GetEntityId(), m_pWeapon->GetFireModeIdx(GetName()), 0.0f, pGameRules->GetHitMaterialIdFromSurfaceId(surfaceIdx), partId, pGameRules->GetHitTypeId(m_meleeparams.hit_type.c_str()), pt, dir, normal); info.remote = remote; if (!remote) info.seq=m_pWeapon->GenerateShootSeqN(); info.damage = m_meleeparams.damage; if (m_pWeapon->GetForcedHitMaterial() != -1) info.material=pGameRules->GetHitMaterialIdFromSurfaceId(m_pWeapon->GetForcedHitMaterial()); pGameRules->ClientHit(info); } } // play effects if(ok) { IMaterialEffects* pMaterialEffects = gEnv->pGame->GetIGameFramework()->GetIMaterialEffects(); TMFXEffectId effectId = pMaterialEffects->GetEffectId("melee", surfaceIdx); if (effectId != InvalidEffectId) { SMFXRunTimeEffectParams params; params.pos = pt; params.playflags = MFX_PLAY_ALL | MFX_DISABLE_DELAY; params.soundSemantic = eSoundSemantic_Player_Foley; pMaterialEffects->ExecuteEffect(effectId, params); } } ApplyCameraShake(true); m_pWeapon->PlayAction(m_meleeactions.hit.c_str()); }
BOOL CExState1::OnUpdateProperties() { CMoveShape* pUser = GetSufferer(); if( pUser == NULL ) return FALSE; if( m_pCurrentVisualEffect ) { m_pCurrentVisualEffect -> UpdateVisualEffect( this, 0 ); } if( pUser -> GetType() == TYPE_PLAYER ) { CPlayer* pPlayer = (CPlayer*)( pUser ); if( pPlayer ) { if( m_stStateParam.maxhp ) pPlayer->SetMaxHP( pPlayer->GetMaxHP() + m_stStateParam.maxhp ); if( m_stStateParam.maxmp ) pPlayer->SetMaxMP( pPlayer->GetMaxMP() + m_stStateParam.maxmp ); if( m_stStateParam.minatk ) pPlayer->SetMinAtk( pPlayer->GetMinAtk() + m_stStateParam.minatk ); if( m_stStateParam.maxatk ) pPlayer->SetMaxAtk( pPlayer->GetMaxAtk() + m_stStateParam.maxatk ); if( m_stStateParam.elm ) pPlayer->SetElementModify( pPlayer->GetElementModify() + m_stStateParam.elm ); if( m_stStateParam.def ) pPlayer->SetDef( pPlayer->GetDef() + m_stStateParam.def); if( m_stStateParam.elmdef ) pPlayer->SetElementResistant( pPlayer->GetElementResistant() + m_stStateParam.elmdef ); if( m_stStateParam.cch ) pPlayer->SetCCH( pPlayer->GetCCH() + m_stStateParam.cch); if( m_stStateParam.fullmiss ) pPlayer->SetFullMiss( pPlayer->GetFullMiss() + m_stStateParam.fullmiss ); if( m_stStateParam.atkavoid ) pPlayer->SetAttackAvoid( pPlayer->GetAttackAvoid() + m_stStateParam.atkavoid); if( m_stStateParam.elmavoid ) pPlayer->SetElementAvoid( pPlayer->GetElementAvoid() + m_stStateParam.elmavoid ); if( m_stStateParam.hit ) pPlayer->SetHit( pPlayer->GetHit() + m_stStateParam.hit); if( m_stStateParam.dodge ) pPlayer->SetDodge( pPlayer->GetDodge() + m_stStateParam.dodge ); } } return TRUE; }
//------------------------------------------------------------------------ void CMelee::Update(float frameTime, uint frameId) { FUNCTION_PROFILER( GetISystem(), PROFILE_GAME ); bool requireUpdate = false; if (m_attacking) { requireUpdate = true; if (m_delayTimer>0.0f) { m_delayTimer-=frameTime; if (m_delayTimer<=0.0f) m_delayTimer=0.0f; } else { if (!m_attacked) { m_attacked = true; CActor *pActor = m_pWeapon->GetOwnerActor(); if(!pActor) return; Vec3 pos(ZERO); Vec3 dir(ZERO); IMovementController * pMC = pActor->GetMovementController(); if (!pMC) return; float strength = 1.0f;//pActor->GetActorStrength(); if (pActor->GetActorClass() == CPlayer::GetActorClassType()) { CPlayer *pPlayer = (CPlayer *)pActor; if (CNanoSuit *pSuit = pPlayer->GetNanoSuit()) { ENanoMode curMode = pSuit->GetMode(); if (curMode == NANOMODE_STRENGTH) { strength = pActor->GetActorStrength(); strength = strength * (1.0f + 2.0f * pSuit->GetSlotValue(NANOSLOT_STRENGTH)* STRENGTH_MULT); if(!pPlayer->IsPlayer() && g_pGameCVars->g_difficultyLevel < 4) strength *= g_pGameCVars->g_AiSuitStrengthMeleeMult; } } } SMovementState info; pMC->GetMovementState(info); pos = info.eyePosition; dir = info.eyeDirection; if (!PerformRayTest(pos, dir, strength, false)) if(!PerformCylinderTest(pos, dir, strength, false)) ApplyCameraShake(false); m_ignoredEntity = 0; m_meleeScale = 1.0f; m_pWeapon->RequestMeleeAttack(m_pWeapon->GetMeleeFireMode()==this, pos, dir, m_pWeapon->GetShootSeqN()); } } } if (requireUpdate) m_pWeapon->RequireUpdate(eIUS_FireMode); }
//-------------------------------------------------------------------------- //--- ViewPostProcess //-------------------------------------------------------------------------- // Commit all the changes //-------------------------------------------------------------------------- void CPlayerView::ViewPostProcess(CPlayer &rPlayer,SViewParams &viewParams) { /*IEntity *pLinked = rPlayer.GetLinkedEntity(); if (pLinked && rPlayer.m_stats.linkedFreeLook) { viewParams.rotation = Quat(pLinked->GetWorldTM()) * viewParams.rotation; }*/ // update the player rotation if view control is taken from somewhere else (e.g. animation or vehicle) ViewExternalControlPostProcess(rPlayer,viewParams); //set first person weapon position/rotation FirstPersonWeaponPostProcess(rPlayer,viewParams); ViewShakePostProcess(rPlayer,viewParams); //-------------------------- // Output changed temporaries - debugging. //-------------------------- //-------------------------- // Output changed state. //-------------------------- //rPlayer.m_lastPos=m_io.m_lastPos; rPlayer.m_viewQuat=m_io.viewQuat; //FIXME:updating the baseMatrix due being in a vehicle or having a first person animations playing has to be moved somewhere else rPlayer.m_baseQuat=m_io.baseQuat; if (!rPlayer.IsTimeDemo()) { rPlayer.m_viewQuatFinal=m_io.viewQuatFinal; } rPlayer.m_stats.FPWeaponAngles=m_io.stats_FPWeaponAngles; rPlayer.m_stats.FPWeaponPos=m_io.stats_FPWeaponPos; rPlayer.m_stats.FPSecWeaponAngles=m_io.stats_FPSecWeaponAngles; rPlayer.m_stats.FPSecWeaponPos=m_io.stats_FPSecWeaponPos; //rPlayer.m_viewShake=m_io.viewShake; rPlayer.m_eyeOffsetView=m_io.eyeOffsetView; rPlayer.m_stats.bobCycle=m_io.stats_bobCycle; rPlayer.m_FPWeaponAngleOffset=m_io.vFPWeaponAngleOffset; rPlayer.m_FPWeaponLastDirVec=m_io.vFPWeaponLastDirVec; rPlayer.m_FPWeaponOffset=m_io.vFPWeaponOffset; rPlayer.m_bobOffset=m_io.bobOffset; rPlayer.m_angleOffset=m_io.angleOffset; rPlayer.m_viewAnglesOffset = m_io.viewAngleOffset; rPlayer.m_stats.landed=m_io.stats_landed; rPlayer.m_stats.jumped=m_io.stats_jumped; rPlayer.m_stats.smoothViewZ = m_io.stats_smoothViewZ; rPlayer.m_stats.smoothZType = m_io.stats_smoothZType; //-------------------------- rPlayer.m_stats.shakeAmount = viewParams.shakingRatio; HandsPostProcess(rPlayer,viewParams); }