//===========================================================================// // File: NetWeapon.cpp //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 01/06/2000 JSE Inital coding //---------------------------------------------------------------------------// // Copyright (C) 1998, Microsoft Corp. // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4Headers.hpp" #include "NetWeapon.hpp" #include "MWEntityManager.hpp" #include "SubsystemClassData.hpp" #include "Weapon.hpp" #include "MissileWeapon.hpp" // MSL 5.03 RTX //#include "rtxweaponsub.hpp" #include "Mech.hpp" #include #include Stuff::MemoryBlock* WeaponUpdate::AllocatedMemory = NULL; void WeaponUpdate::InitializeClass() { Verify(!AllocatedMemory); AllocatedMemory = new Stuff::MemoryBlock( sizeof(WeaponUpdate), 10, 2, "WeaponUpdates" ); Register_Object(AllocatedMemory); } void WeaponUpdate::TerminateClass() { Unregister_Object(AllocatedMemory); delete AllocatedMemory; AllocatedMemory = NULL; } void MechWarrior4::NetWeaponSecurityCheckStart() { _asm { nop } } //########################################################################## //########################### FirstPersonWeaponCommand //########################################################################## #define DEFAULT_RANGE 15.f #define VEHICLE_RANGE 5.f #define MECH_RANGE 5.f void WeaponCommand::SpecialDecode(int connection, int type, WeaponUpdate &weapon_command, MemoryStream *memory_stream) { // SPEW(("jerryeds", "REC-FIRE")); weapon_command.obsolete = false; memory_stream->ReadBits(&weapon_command.weaponFired, 32); memory_stream->ReadBits(&weapon_command.lockTime, 32); switch(type) { case MWEntityManager::FirstPersonWeaponToMechCommandMessageID: { // originator connection id is derived from packet header // target id is the full entity id // offset is default if (((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection] != NULL) { Check_Object(((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]); weapon_command.originator.Add(((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]); BYTE connection_id; WORD local_id; memory_stream->ReadBits(&connection_id, 8); memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(connection_id, local_id); Connection *connection = Network::GetInstance()->GetConnection(connection_id); if (connection != NULL) { Check_Object(connection); Entity *target = (Entity *) connection->FindReplicator(repid); if (target != NULL) { Check_Object(target); weapon_command.target.Add(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "First Person To Mech Read - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::ThirdPersonWeaponToMechCommandMessageID: // originator id is in the packet // target id is the full entity id // offset is default { BYTE originator_id; memory_stream->ReadBits(&originator_id, 8); Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[originator_id]; if(originator != NULL) { weapon_command.originator.Add(originator); Check_Object(originator); BYTE connection_id; WORD local_id; memory_stream->ReadBits(&connection_id, 8); memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(connection_id, local_id); Connection *connection = Network::GetInstance()->GetConnection(connection_id); if (connection != NULL) { Check_Object(connection); Entity *target = (Entity *) connection->FindReplicator(repid); if (target != NULL) { weapon_command.target.Add(target); Check_Object(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person To Mech Read - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); //SPEW(("jerryeds", "CLIENT SAW : %d: HIT : %d:%d - %f:%f:%f", originator_id, connection_id, local_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); //SPEW(("jerryeds", "CLIENT SAW: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::AIWeaponCommandToMechtMessageID: // originator connection id is server and local is in packet // target id is the full entity id // offset is default { WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *originator = (Entity *) Connection::Server->FindReplicator(repid); if(originator != NULL) { Check_Object(originator); weapon_command.originator.Add(originator); BYTE connection_id; memory_stream->ReadBits(&connection_id, 8); memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(connection_id, local_id); Connection *connection = Network::GetInstance()->GetConnection(connection_id); if (connection != NULL) { Check_Object(connection); Entity *target = (Entity *) connection->FindReplicator(repid); if (target != NULL) { Check_Object(target); weapon_command.target.Add(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::FirstPersonWeaponToGroundCommandMessageID: // originator connection id is derived from packet header // target id is the ground // offset is larger { Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]; if (originator != NULL) { weapon_command.originator.Add(originator); Check_Object(originator); Check_Object(Map::GetInstance()); weapon_command.target.Add( Map::GetInstance() ); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); // find the y component Check_Object(MWEntityManager::GetInstance()); weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z); //SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } break; case MWEntityManager::ThirdPersonWeaponToGroundCommandMessageID: // originator id is in the packet // target id is the ground // offset is larger { BYTE connection_id; memory_stream->ReadBits(&connection_id, 8); Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection_id]; if (originator != NULL) { weapon_command.originator.Add(originator); Check_Object(originator); Check_Object(Map::GetInstance()); weapon_command.target.Add( Map::GetInstance() ); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); // find the y component Check_Object(MWEntityManager::GetInstance()); weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z); //SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } break; case MWEntityManager::AIWeaponCommandToGroundtMessageID: // originator connection id is server and local is in packet // target id is the ground // offset is larger { WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *originator = (Entity *) Connection::Server->FindReplicator(repid); if (originator != NULL) { Check_Object(originator); weapon_command.originator.Add(originator); Check_Object(Map::GetInstance()); weapon_command.target.Add(Map::GetInstance()); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); // find the y component Check_Object(MWEntityManager::GetInstance()); weapon_command.targetOffset.y = ((MWEntityManager*)MWEntityManager::GetInstance())->FindGroundHeight(weapon_command.targetOffset.x, weapon_command.targetOffset.z); } else { weapon_command.obsolete = true; } } break; case MWEntityManager::FirstPersonWeaponToServerObjectCommandMessageID: // originator connection id is derived from packet header // target local id is in the packet - connection is server // offset is default { Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection]; if (originator != NULL) { weapon_command.originator.Add(originator); WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *target = (Entity *) Connection::Server->FindReplicator(repid); if (target != NULL) { weapon_command.target.Add(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "First Person To Server Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::ThirdPersonWeaponToServerObjectCommandMessageID: // originator id is in the packet // target local id is in the packet - connection is server // offset is default { BYTE connection_id; memory_stream->ReadBits(&connection_id, 8); Entity *originator = ((MWEntityManager*)MWEntityManager::GetInstance())->playerVehicle[connection_id]; if (originator != NULL) { weapon_command.originator.Add(originator); WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *target = (Entity *) Connection::Server->FindReplicator(repid); if (target != NULL) { weapon_command.target.Add(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person To Server Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::AIWeaponCommandToServerObjectMessageID: // originator connection id is server and local is in packet // target local id is in the packet - connection is server // offset is default { WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *originator = (Entity *) Connection::Server->FindReplicator(repid); if (originator != NULL) { weapon_command.originator.Add(originator); WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *target = (Entity *) Connection::Server->FindReplicator(repid); if (target != NULL) { weapon_command.target.Add(target); Entity* parent_target = target; int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); } else { weapon_command.obsolete = true; } } else { weapon_command.obsolete = true; } } break; case MWEntityManager::FirstPersonWeaponNoTargetCommandMessageID: // originator connection id is derived from packet header // no target no offset just shoot { if (MWEntityManager::GetInstance()->playerVehicle[connection] != NULL) weapon_command.originator.Add(MWEntityManager::GetInstance()->playerVehicle[connection]); weapon_command.target.Remove(); weapon_command.targetOffset = Point3D::Identity; Check_Object(weapon_command.originator.GetCurrent()); Check_Object(Map::GetInstance()); weapon_command.target.Add( Map::GetInstance() ); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); if (weapon_command.originator.GetCurrent() == NULL) { weapon_command.obsolete = true; } } break; case MWEntityManager::ThirdPersonWeaponNoTargetCommandMessageID: // originator id is in the packet // no target no offset just shoot { BYTE connection_id; memory_stream->ReadBits(&connection_id, 8); if (MWEntityManager::GetInstance()->playerVehicle[connection_id] != NULL) weapon_command.originator.Add(MWEntityManager::GetInstance()->playerVehicle[connection_id]); weapon_command.target.Remove(); weapon_command.targetOffset = Point3D::Identity; Check_Object(weapon_command.originator.GetCurrent()); Check_Object(Map::GetInstance()); weapon_command.target.Add( Map::GetInstance() ); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person No Target Receive - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); if (weapon_command.originator.GetCurrent() == NULL) { weapon_command.obsolete = true; } } break; case MWEntityManager::AIWeaponCommandToNoTargetMessageID: // originator connection id is server and local is in packet // no target no offset just shoot { WORD local_id; memory_stream->ReadBits(&local_id, 16); ReplicatorID repid(Connection::Server->GetID(), local_id); Entity *originator = (Entity *) Connection::Server->FindReplicator(repid); if (originator != NULL) weapon_command.originator.Add(originator); weapon_command.target.Remove(); weapon_command.targetOffset = Point3D::Identity; Check_Object(weapon_command.originator.GetCurrent()); Check_Object(Map::GetInstance()); weapon_command.target.Add(Map::GetInstance()); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->ReadBitsToScaledFloat(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); if (weapon_command.originator.GetCurrent() == NULL) { weapon_command.obsolete = true; } } break; } if (!weapon_command.obsolete) { Vehicle *vehicle = Cast_Object(Vehicle *, weapon_command.originator.GetCurrent()); if (weapon_command.target.GetCurrent() != NULL) { Stuff::ChainIteratorOf iterator(&vehicle->weaponChain); Weapon *weapon; while ((weapon = iterator.ReadAndNext()) != NULL) { int id = weapon->GetWeaponID(); if (weapon_command.weaponFired & (0x1 << id)) { if (weapon->IsDerivedFrom(MissileWeapon::DefaultData)) { MissileWeapon *missile_weapon; missile_weapon = Cast_Object(MissileWeapon *, weapon); if (missile_weapon->IsAMSValid(weapon_command.target.GetCurrent())) { //write the target number... weapon_command.AntiWeaponCount[id] = 0; // may not error, but ... jcem: critical error - should clear before ReadBits(...)... memory_stream->ReadBits(&weapon_command.AntiWeaponCount[id], 3); } else { weapon_command.AntiWeaponCount[id] = 0; } } } } } } } //########################################################################## //########################### FirstPersonWeaponCommand //########################################################################## void WeaponCommand::SpecialEncode(int connection, int type, WeaponUpdate &weapon_command, DynamicMemoryStream *memory_stream) { // SPEW(("jerryeds", "SEND-FIRE")); memory_stream->WriteBits(&weapon_command.weaponFired, 32); memory_stream->WriteBits(&weapon_command.lockTime, 32); switch(type) { case MWEntityManager::FirstPersonWeaponToMechCommandMessageID: { // originator connection id is derived from packet header // target id is the full entity id // offset is default Check_Object(weapon_command.target.GetCurrent()); BYTE connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID; WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&connection_id, 8); memory_stream->WriteBits(&local_id, 16); // SPEWALWAYS(("jackyc", "First Person To Mech Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); //SPEW(("jerryeds", "CLIENT HIT: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); // SPEWALWAYS(("jackyc", "First Person To Mech Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::ThirdPersonWeaponToMechCommandMessageID: // originator id is in the packet // target id is the full entity id // offset is default { BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID; memory_stream->WriteBits(&connection_id, 8); Check_Object(weapon_command.target.GetCurrent()); connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID; WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&connection_id, 8); memory_stream->WriteBits(&local_id, 16); // SPEWALWAYS(("jackyc", "Third Person To Mech Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person To Mech Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); //SPEW(("jerryeds","SERVER HIT : %d:%d - %f:%f:%f" , connection_id, local_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); //SPEW(("jerryeds", "SERVER HIT: %s : <%f:%f:%f>", (const char *)weapon_command.target->instanceName, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::AIWeaponCommandToMechtMessageID: // originator connection id is server and local is in packet // target id is the full entity id // offset is default { BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID; WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); Check_Object(weapon_command.target.GetCurrent()); connection_id = weapon_command.target.GetCurrent()->GetReplicatorID().connectionID; local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&connection_id, 8); memory_stream->WriteBits(&local_id, 16); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); } break; case MWEntityManager::FirstPersonWeaponToGroundCommandMessageID: // originator connection id is derived from packet header // target id is the ground // offset is larger { Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); //SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::ThirdPersonWeaponToGroundCommandMessageID: // originator id is in the packet // target id is the ground // offset is larger { BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID; memory_stream->WriteBits(&connection_id, 8); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); //SPEW(("jerryeds","PLAYER %d: Hit ground <%f,%f,%f>", connection_id, weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); // SPEWALWAYS(("jackyc", "Third Person To Ground Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::AIWeaponCommandToGroundtMessageID: // originator connection id is server and local is in packet // target id is the ground // offset is larger { WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,TerrainXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,TerrainZEntryID)); } break; case MWEntityManager::FirstPersonWeaponToServerObjectCommandMessageID: // originator connection id is derived from packet header // target local id is in the packet - connection is server // offset is default { WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); // SPEWALWAYS(("jackyc", "First Person To Server Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "First Person To Server Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::ThirdPersonWeaponToServerObjectCommandMessageID: // originator id is in the packet // target local id is in the packet - connection is server // offset is default { BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID; memory_stream->WriteBits(&connection_id, 8); WORD local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); // SPEWALWAYS(("jackyc", "Third Person To Server Write1 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person To Server Write2 - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::AIWeaponCommandToServerObjectMessageID: // originator connection id is server and local is in packet // target local id is in the packet - connection is server // offset is default { WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); local_id = weapon_command.target.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); Entity* parent_target = weapon_command.target.GetCurrent(); int class_id = parent_target->GetClassID(); if (class_id == MWMoverClassID) { MWMover* mover = Cast_Object(MWMover*, parent_target); parent_target = mover->GetParentVehicle(); } Scalar sphere_radiusMaxX = 0.f; Scalar sphere_radiusMaxY = 0.f; Scalar sphere_radiusMaxZ = 0.f; Scalar sphere_radiusMinX = 0.f; Scalar sphere_radiusMinY = 0.f; Scalar sphere_radiusMinZ = 0.f; class_id = parent_target->GetClassID(); switch (class_id) { case MechClassID: { sphere_radiusMaxX = MECH_RANGE; sphere_radiusMaxY = MECH_RANGE; sphere_radiusMaxZ = MECH_RANGE; sphere_radiusMinX = -MECH_RANGE; sphere_radiusMinY = -MECH_RANGE; sphere_radiusMinZ = -MECH_RANGE; } break; case BuildingClassID: case TurretClassID: case BridgeClassID: case MFBClassID: case FieldBaseClassID: case DropshipClassID: { CollisionVolume *solid = parent_target->GetSolidVolume(); if (solid) { Point3D sphere_center = Point3D(solid->m_localSpaceBounds.localToParent); sphere_radiusMaxX = sphere_center.x + solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMaxY = sphere_center.y + solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMaxZ = sphere_center.z + solid->m_localSpaceBounds.axisExtents.z; sphere_radiusMinX = sphere_center.x - solid->m_localSpaceBounds.axisExtents.x; sphere_radiusMinY = sphere_center.y - solid->m_localSpaceBounds.axisExtents.y; sphere_radiusMinZ = sphere_center.z - solid->m_localSpaceBounds.axisExtents.z; } else { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } } break; case VehicleClassID: { sphere_radiusMaxX = VEHICLE_RANGE; sphere_radiusMaxY = VEHICLE_RANGE; sphere_radiusMaxZ = VEHICLE_RANGE; sphere_radiusMinX = -VEHICLE_RANGE; sphere_radiusMinY = -VEHICLE_RANGE; sphere_radiusMinZ = -VEHICLE_RANGE; } break; default: { sphere_radiusMaxX = DEFAULT_RANGE; sphere_radiusMaxY = DEFAULT_RANGE; sphere_radiusMaxZ = DEFAULT_RANGE; sphere_radiusMinX = -DEFAULT_RANGE; sphere_radiusMinY = -DEFAULT_RANGE; sphere_radiusMinZ = -DEFAULT_RANGE; } break; } Clamp(weapon_command.targetOffset.x, sphere_radiusMinX, sphere_radiusMaxX); Clamp(weapon_command.targetOffset.y, sphere_radiusMinY, sphere_radiusMaxY); Clamp(weapon_command.targetOffset.z, sphere_radiusMinZ, sphere_radiusMaxZ); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x,sphere_radiusMinX,sphere_radiusMaxX,BitDepthManager::BitDepth(UpdateType,TargetOffsetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y,sphere_radiusMinY,sphere_radiusMaxY,BitDepthManager::BitDepth(UpdateType,TargetOffsetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z,sphere_radiusMinZ,sphere_radiusMaxZ,BitDepthManager::BitDepth(UpdateType,TargetOffsetZEntryID)); } break; case MWEntityManager::FirstPersonWeaponNoTargetCommandMessageID: // originator connection id is derived from packet header // no target no offset just shoot { Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); // SPEWALWAYS(("jackyc", "First Person No Target Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::ThirdPersonWeaponNoTargetCommandMessageID: // originator id is in the packet // no target no offset just shoot { BYTE connection_id = weapon_command.originator.GetCurrent()->GetReplicatorID().connectionID; memory_stream->WriteBits(&connection_id, 8); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); // SPEWALWAYS(("jackyc", "Third Person No Target Write - %f - %f - %f", weapon_command.targetOffset.x, weapon_command.targetOffset.y, weapon_command.targetOffset.z)); } break; case MWEntityManager::AIWeaponCommandToNoTargetMessageID: // originator connection id is server and local is in packet // no target no offset just shoot { WORD local_id = weapon_command.originator.GetCurrent()->GetReplicatorID().localID; memory_stream->WriteBits(&local_id, 16); Scalar min_z, max_z, min_x, max_x; Map::GetInstance()->GetMapExtents(&min_z, &max_z, &min_x, &max_x); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.x, min_x, max_x, BitDepthManager::BitDepth(UpdateType,NoTargetXEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.y, -1000.0f, 1000.0f, BitDepthManager::BitDepth(UpdateType,NoTargetYEntryID)); memory_stream->WriteScaledFloatToBits(weapon_command.targetOffset.z, min_z, max_z, BitDepthManager::BitDepth(UpdateType,NoTargetZEntryID)); } break; } //Write the ams data... Vehicle *vehicle = Cast_Object(Vehicle *, weapon_command.originator.GetCurrent()); if (weapon_command.target.GetCurrent() != NULL) { Stuff::ChainIteratorOf iterator(&vehicle->weaponChain); Weapon *weapon; while ((weapon = iterator.ReadAndNext()) != NULL) { int id = weapon->GetWeaponID(); if (weapon_command.weaponFired & (0x1 << id)) { if (weapon->IsDerivedFrom(MissileWeapon::DefaultData)) { MissileWeapon *missile_weapon; missile_weapon = Cast_Object(MissileWeapon *, weapon); if (missile_weapon->IsAMSValid(weapon_command.target.GetCurrent())) { //write the target number... memory_stream->WriteBits(&weapon_command.AntiWeaponCount[id], 3); } } } } } } void MechWarrior4::NetWeaponSecurityCheckStop() { _asm { nop } }