#include "MW4Headers.hpp" #include "Flag.hpp" #include "ai.hpp" #include "Mech.hpp" #include "MWApplication.hpp" #include "bucket.hpp" #include "MWMission.hpp" #include "aiutils.hpp" #include "rail_move.hpp" #include "torso.hpp" #include #include #include #include #include #include "team.hpp" #include #include #include #include "nglog_mw4.hpp" // jcem - start #include "windows.h" #include "ctcls.h" #include "ctcl.h" #include "recscore.h" // jcem // jcem - end //############################################################################# //############################### Flag ############################## //############################################################################# Flag::ClassData* Flag::DefaultData = NULL; const Stuff::Scalar FLAG_DISTANCE = 25.0f; const Stuff::Scalar FLAG_DROP_DISTANCE = 80.0f; const Stuff::Scalar FLAG_MAX_IDLE_TIME = 30.0f; const Stuff::Scalar flag_hold_increment_time = 1.0f; const Stuff::Scalar flag_drop_behind_distance = 10.0f; //________________________________________________________________________________________________________________ void Flag::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( FlagClassID, "MechWarrior4::Flag", BaseClass::DefaultData, 0, NULL, (BaseClass::Factory)Make, (BaseClass::CreateMessage::Factory)CreateMessage::ConstructCreateMessage, ExecutionStateEngine::DefaultData, (BaseClass::GameModel::Factory)GameModel::ConstructGameModel, (BaseClass::GameModel::Factory)GameModel::ConstructOBBStream, (BaseClass::GameModel::ReadAndVerifier)GameModel::ReadAndVerify, (BaseClass::GameModel::ModelWrite)GameModel::WriteToText, (BaseClass::GameModel::ModelSave)GameModel::SaveGameModel, AnimationStateEngine::Make ); Register_Object(DefaultData); } //________________________________________________________________________________________________________________ void Flag::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //________________________________________________________________________________________________________________ Flag* Flag::Make(CreateMessage *message,ReplicatorID *base_id) { Check_Object(message); Flag *new_entity = new Flag(DefaultData, message, base_id, NULL); Check_Object(new_entity); return new_entity; } //________________________________________________________________________________________________________________ Flag::Flag(ClassData *class_data,CreateMessage *message,ReplicatorID *base_id,ElementRenderer::Element *element) : NavPoint(class_data, message, base_id, element) , m_AttachedTo (NULL) , m_Team(MWApplication::No_Team) , m_Origin(LinearMatrix4D::Identity) , m_DeactiveTime(0) , m_WaitAfterCaptureTime(0) , m_AttachRadius(FLAG_DISTANCE) , m_FirstFrame(true) , m_HoldTimeLastUpdate(0) , m_Visible(true) , m_LastFlagEvent(FLAG_NONE) { Check_Pointer(this); Check_Object(message); executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState); int team(MWApplication::NameToTeamNumber(instanceName)); if (team != MWApplication::No_Team) { SetTeam(team); } m_UseDropNames = UseDropNames(); m_LastAnimateTime = -10.0f; m_DisplayIncValue = -1; // starts at -1 forcing a -1 value to become 0 for visualrepresentation SetToDisplay(); } //________________________________________________________________________________________________________________ Flag::~Flag() { } //________________________________________________________________________________________________________________ void Flag::RevealFlag() { Check_Object(this); if (m_Visible == false) { SetVisibleFlag(); SetNewLocalToParent(m_Origin); SyncMatrices(true); Map::GetInstance()->UpdateZone(this); m_Visible = true; // executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState); MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance()); if (mwmission->GetFlagsAsNavPoints() == true) { AddToNavList(); } else { RemoveFromNavList(); } } } void Flag::HideFlag() { m_HoldTimeLastUpdate = 0; if (m_Visible == true) { ClearVisibleFlag(); Stuff::LinearMatrix4D m(GetLocalToWorld()); m.BuildTranslation(Stuff::Point3D::HellPoint); SetNewLocalToParent(m); SyncMatrices(true); Map::GetInstance()->UpdateZone(this); m_Visible = false; // executionState->RequestState(ExecutionStateEngine::NeverExecuteState); RemoveFromNavList(); IgnorePostCollision(); } } //________________________________________________________________________________________________________________ void Flag::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } void Flag::Attach (Adept::Entity *who) { if (Attached() == who) return; if (who == 0) { m_HoldTimeLastUpdate = 0; } m_AttachedTo.Remove (); if ((who) && (m_Visible == true)) { Check_Object (who); m_StartAttachTime = gos_GetElapsedTime (); m_AttachedTo.Add (who); MWObject *obj; obj = Cast_Object (MWObject *, who); m_AttachSite = obj->FindSite("site_flag"); if (!m_AttachSite) m_AttachSite = obj->FindSite ("site_eject"); if (!m_AttachSite) { Attach (NULL); } } } //________________________________________________________________________________________________________________ Stuff::Time Flag::TimeAttached() { if (Attached()) { return gos_GetElapsedTime () - m_StartAttachTime; } return 0; } //________________________________________________________________________________________________________________ Adept::Entity* Flag::Attached() { return m_AttachedTo.GetCurrent(); } //________________________________________________________________________________________________________________ void Flag::PreCollisionExecute(Stuff::Time till) { PRECOLLISION_LOGIC("Flag"); if (m_FirstFrame == true) { BaseClass::PreCollisionExecute (till); m_Origin = GetLocalToWorld(); m_FirstFrame = false; return; } if (Enabled() == false) { Attach(NULL); HideFlag(); return; } if (m_WaitAfterCaptureTime != 0) { UpdateWaitAfterCapture(); } else { RevealFlag(); UsePostCollision (); if (Network::GetInstance()->AmIServer()) { if (Attached() == 0) { UpdateUnattached(); } else { UpdateAttached(); } } } if (m_Visible == true) { if (gos_GetElapsedTime () - m_LastAnimateTime > (1.0f/10.0f)) // six animations per second { m_LastAnimateTime = (float)gos_GetElapsedTime (); visualRepresentation += m_DisplayIncValue; if (visualRepresentation <= FirstFlagAnimationState) { visualRepresentation = FirstFlagAnimationState; m_DisplayIncValue = 1; } else if (visualRepresentation >= SixthFlagAnimationState) { visualRepresentation = SixthFlagAnimationState; m_DisplayIncValue = -1; } ExecuteComponentWebs(); } BaseClass::PreCollisionExecute (till); } } //________________________________________________________________________________________________________________ void Flag::UpdateUnattached() { if ((m_DeactiveTime != 0) && (GetFlagDropReturnTime() != -1) && (gos_GetElapsedTime() > m_DeactiveTime)) { // ngLog addition #if !defined(NO_LOG) if(m_Team != MWApplication::No_Team) { MW4log_generic(MW4P_DSTATS, va("Flag_Return\t-1\t%d", m_Team)); } #endif // !defined(NO_LOG) Execute_ReturnToOrigin(); return; } LookForSomeoneToAttachTo(); } //________________________________________________________________________________________________________________ void Flag::LookForSomeoneToAttachTo() { NameTable *table = NameTable::GetInstance(); // For Bots? // MSL 5.05 Team Return Flag int size(table->nameTableArray[NameTable::VehicleArray].GetLength()); { for (int i = 0; i < size; ++i) { NameTableEntry *data; data = &table->nameTableArray [NameTable::VehicleArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent (); if ((ent != 0) || (EntityCanCarryMe(*ent) == true)) { if (IsWithin(ent,m_AttachRadius,true) == true) { if (EntityCanCarryMe(*ent) == true) { Execute_AttachTo(ent); return; } } } } } size = table->nameTableArray[NameTable::VehicleArray].GetLength(); { for (int i = 0; i < size; ++i) { NameTableEntry *data; data = &table->nameTableArray [NameTable::VehicleArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent (); if ((ent != 0) || (EntityCanReturnMe(*ent) == true)) { if (IsWithin(ent,m_AttachRadius,true) == true) { if (EntityCanReturnMe(*ent) == true) { SetNewLocalToParent(m_Origin); m_DeactiveTime = 0; return; } } } } } } /* // Original Flag Code //________________________________________________________________________________________________________________ void Flag::LookForSomeoneToAttachTo() { NameTable *table = NameTable::GetInstance(); int size(table->nameTableArray[NameTable::VehicleArray].GetLength()); {for (int i = 0; i < size; ++i) { NameTableEntry *data; data = &table->nameTableArray [NameTable::VehicleArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent (); if ((ent == 0) || (EntityCanCarryMe(*ent) == false)) { continue; } if (IsWithin(ent,m_AttachRadius,true) == true) { Execute_AttachTo(ent); return; } }} size = table->nameTableArray[NameTable::PlayerArray].GetLength(); {for (int i = 0; i < size; ++i) { NameTableEntry *data; data = &table->nameTableArray [NameTable::PlayerArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent (); if ((ent != 0) && (ent->IsDerivedFrom(Adept::Player::DefaultData) == true)) { Adept::Player* player = Cast_Object(Adept::Player*,ent); if (player->vehicle != 0) { if (EntityCanCarryMe(*(player->vehicle)) == false) { continue; } if (IsWithin(player->vehicle,m_AttachRadius,true) == true) { Execute_AttachTo(player->vehicle); return; } } } }} } */ //________________________________________________________________________________________________________________ void Flag::UpdateAttached() { Verify(Attached() != 0); if (CarrierCanStillCarryMe() == false) { Execute_Drop(); } else { if (CarrierCanCaptureMe() == true) { Execute_Capture(); } else { if (m_HoldTimeLastUpdate == 0) { m_HoldTimeLastUpdate = (Stuff::Scalar)gos_GetElapsedTime(); } if (m_HoldTimeLastUpdate + flag_hold_increment_time < (Stuff::Scalar)gos_GetElapsedTime()) { m_HoldTimeLastUpdate += flag_hold_increment_time; IncrementScore(CBucketManager::FLAG_HOLD_TIME,Attached()->GetReplicatorID()); } } } } //________________________________________________________________________________________________________________ void Flag::UpdateWaitAfterCapture() { Verify(m_WaitAfterCaptureTime != 0); if (m_WaitAfterCaptureTime < 0) { HideFlag(); return; } if (gos_GetElapsedTime() > m_WaitAfterCaptureTime) { m_WaitAfterCaptureTime = 0; RevealFlag(); } } //________________________________________________________________________________________________________________ void Flag::PostCollisionExecute(Stuff::Time till) { POSTCOLLISION_LOGIC("Flag"); if (Attached() == 0) { UpdateFlagObjectOnGround(); } else { if (Attached()->IsDestroyed ()) { Execute_Drop(); } else { UpdateFlagObjectAttached(); } } SyncMatrices(true); BaseClass::PostCollisionExecute (till); } //________________________________________________________________________________________________________________ void Flag::UpdateFlagObjectOnGround() { Verify(Attached() == 0); LinearMatrix4D mat(GetLocalToWorld ()); Stuff::Line3D line; line.m_length = 2000.0f; line.m_direction = Vector3D::Down; line.m_origin = mat; line.m_origin.y += 1000.0f; Stuff::Normal3D normal; CollisionQuery query(&line, &normal, CanBeWalkedOnFlag, this); Check_Object(CollisionGrid::Instance); CollisionGrid::Instance->ProjectLine(&query); // there had to be a unit here so it must hit something Point3D tr; line.FindEnd(&tr); Point3D loc (GetLocalToWorld ()); loc.y = tr.y; YawPitchRoll new_rotation(YawPitchRoll::Identity); new_rotation = (YawPitchRoll) GetLocalToWorld (); mat.BuildTranslation(loc); mat.AlignLocalAxisToWorldVector (Vector3D::Up,Y_Axis,X_Axis,Z_Axis); SetNewLocalToParent(mat); } //________________________________________________________________________________________________________________ void Flag::UpdateFlagObjectAttached() { Verify(Attached() != 0); Check_Object(m_AttachSite); LinearMatrix4D mat; if (Attached()->IsDerivedFrom(MWObject::DefaultData) == true) { MWObject* mwobject = Cast_Object(MWObject*,Attached()); if (mwobject->GetTorso() != 0) { mat = mwobject->GetTorso()->GetTwistJointMatrix(); } } else { mat = Attached()->GetLocalToWorld(); } UnitVector3D dir; mat.GetLocalForwardInWorld(&dir); EulerAngles ea(mat); mat.BuildRotation(ea); if (m_AttachSite != 0) { mat.BuildTranslation((Stuff::Point3D)m_AttachSite->GetLocalToWorld()); } else { // put the flag in front and to the right of us Point3D forward(dir); forward *= 6.0f; UnitVector3D unit_right; Attached()->GetLocalToWorld().GetLocalRightInWorld(&unit_right); Point3D right(unit_right); right *= (4.0f + (Stuff::Scalar)GetMyIndex()); forward += right; forward += (Point3D)mat; mat.BuildTranslation(forward); } SetNewLocalToParent(mat); } //________________________________________________________________________________________________________________ int Flag::GetTeam() const { return (m_Team); } //________________________________________________________________________________________________________________ void Flag::SetTeam(int team) { Verify(team >= 0); Verify(team <= 7); m_Team = team; } //________________________________________________________________________________________________________________ inline std::string TeamNumToStr(int team_num) { char buf[100]; // MSL 5.02 Flag Team Name if (team_num == 0) sprintf(buf,"Blue"); if (team_num == 1) sprintf(buf,"Red"); if (team_num == 2) sprintf(buf,"Yellow"); if (team_num == 3) sprintf(buf,"Green"); // sprintf(buf,"%d",team_num + 1); return (buf); } //________________________________________________________________________________________________________________ void Flag::Notify(const std::string& s) { MWApplication::GetInstance()->SendChat( Connection::Local->GetID(), MWApplication::SystemBroadcast, 0, (char*)s.c_str()); } void AddNameAndOrTeam(std::string& s, int team_number, const char* string_name) { if (string_name != 0) { s += string_name; if (team_number != MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM1);//" (Team " s += TeamNumToStr(team_number); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM2);//")" } } else { if (team_number != MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM3);//"Team " s += TeamNumToStr(team_number); } } } //________________________________________________________________________________________________________________ void Flag::NotifyFlagTaken(int flag_team, int taker_team, const char* taker_name) { // TODO: notify the team that their flag was picked up std::string s; if (flag_team == MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_FLAG_TAKEN_BY);//"Flag Taken By "; } else { // MSL 5.02 Flag Notification Change // s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM3);//"Team "; s += TeamNumToStr(flag_team); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_S_FLAG_TAKEN_BY);//" Flag Taken By "; } AddNameAndOrTeam(s,taker_team,taker_name); Notify(s); } //________________________________________________________________________________________________________________ void Flag::NotifyFlagDropped(int flag_team, int dropper_team, const char* dropper_name) { // TODO: notify the team that their flag was dropped by its carrier std::string s; if (flag_team == MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_FLAG_DROPPED_BY);//"Flag Dropped By "; } else { // MSL 5.02 Flag Notification Change // s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM3);//"Team "; s += TeamNumToStr(flag_team); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_S_FLAG_DROPPED_BY);//" Flag Dropped By "; } AddNameAndOrTeam(s,dropper_team,dropper_name); Notify(s); } //________________________________________________________________________________________________________________ void Flag::NotifyFlagCaptured(int flag_team, int capturer_team, const char* capturer_name) { // TODO: notify the team that their flag was taken to another team's drop zone std::string s; if (flag_team == MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_FLAG_CAPTURED_BY);//"Flag Captured By "; } else { // MSL 5.02 Flag Notification Change // s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM3);//"Team "); s += TeamNumToStr(flag_team); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_S_FLAG_CAPTURED_BY);//" Flag Captured By "; } AddNameAndOrTeam(s,capturer_team,capturer_name); Notify(s); } //________________________________________________________________________________________________________________ void Flag::NotifyFlagReturned(int flag_team) { // TODO: notify the team that their flag was returned to their base due to time-out std::string s; // MSL 5.02 Flag Notification Change // std::string s(Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM3));//"Team "); s += TeamNumToStr(flag_team); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_S_FLAG_RETURNED_TO_BASE);//" Flag Returned To Base"; Notify(s); } //________________________________________________________________________________________________________________ bool Flag::UseDropNames() { {for (int i = 0; i < NameTable::GetInstance()->GetLength(NameTable::DropZoneArray); ++i) { NameTableEntry* table_entry = NameTable::GetInstance()->FindEntry(NameTable::DropZoneArray,i); if (table_entry != 0) { int team_number(FlagDropNameToTeamNumber(table_entry->objectName)); if (team_number != MWApplication::No_Team) { return (true); } } }} return (false); } //________________________________________________________________________________________________________________ bool Flag::CanDropTeamFlagHere(int team) { { for (int i = 0; i < NameTable::GetInstance()->GetLength(NameTable::DropZoneArray); ++i) { NameTableEntry* table_entry = NameTable::GetInstance()->FindEntry(NameTable::DropZoneArray,i); if ((table_entry != 0) && (table_entry->dataPointer != 0) && (table_entry->dataPointer->GetCurrent() != 0)&& (table_entry->dataPointer->GetCurrent()->IsDerivedFrom(DropZone::DefaultData) == true)) { DropZone* drop_zone = Cast_Object(DropZone*,table_entry->dataPointer->GetCurrent()); int team_number; if (m_UseDropNames == true) { team_number = FlagDropNameToTeamNumber(drop_zone->instanceName); } else { team_number = MWApplication::NameToTeamNumber(drop_zone->instanceName); } // MSL 5.06 Edit for other flag being carried here!! if (team_number == team) { return (drop_zone->IsWithin(this,FLAG_DROP_DISTANCE,true)); } } } } return (false); } //________________________________________________________________________________________________________________ void Flag::GetFlagsCarriedBy(Adept::Entity& entity, std::vector& flags) { int num_flags = NameTable::GetInstance()->GetLength(NameTable::FlagArray); {for (int i = 0; i < num_flags; ++i) { NameTableEntry* entry = NameTable::GetInstance()->FindEntry(NameTable::FlagArray,i); if ((entry != 0) && (entry->dataPointer != 0) && (entry->dataPointer->GetCurrent() != 0) && (entry->dataPointer->GetCurrent()->IsDerivedFrom(Flag::DefaultData) == true)) { Flag* flag = Cast_Object(Flag*,entry->dataPointer->GetCurrent()); if (flag->Attached() == &entity) { flags.push_back(flag); } } }} } //________________________________________________________________________________________________________________ int Flag::NumFlagsCarriedBy(Adept::Entity& entity) { std::vector flags; GetFlagsCarriedBy(entity, flags); return (flags.size()); } //________________________________________________________________________________________________________________ bool Flag::EntityCanCarryMe(Adept::Entity& entity) { if (Attached() != 0) { return (false); } if ((entity.IsDestroyed() == true) || (entity.IsDerivedFrom(Mech::DefaultData) == false)) { return (false); } Mech* mech = Cast_Object(Mech*,&entity); if (GetTeam() != MWApplication::No_Team) { if (mech->GetTeam() == GetTeam()) { return (false); } } if (mech->IsShutdown() == true) { return (false); } int max_flags = mech->GetMaxFlagsCarried(); if (max_flags < 1) { return (false); } if (NumFlagsCarriedBy(entity) >= max_flags) { return (false); } const Stuff::Point3D my_pos(GetLocalToWorld()); if (GetSquaredDistToMatrixForward(my_pos,mech->GetLocalToWorld()) > GetSquaredDistToMatrixBackward(my_pos,mech->GetLocalToWorld())) { return (false); } return (true); } //________________________________________________________________________________________________________________ bool Flag::EntityCanReturnMe(Adept::Entity& entity) { if (Attached() != 0) { return (false); } if ((entity.IsDestroyed() == true) || (entity.IsDerivedFrom(Mech::DefaultData) == false)) { return (false); } Mech* mech = Cast_Object(Mech*,&entity); if (GetTeam() != MWApplication::No_Team) { if (mech->GetTeam() == GetTeam()) { return (true); } } if (mech->IsShutdown() == true) { return (false); } int max_flags = mech->GetMaxFlagsCarried(); if (max_flags < 1) { return (false); } if (NumFlagsCarriedBy(entity) >= max_flags) { return (false); } const Stuff::Point3D my_pos(GetLocalToWorld()); if (GetSquaredDistToMatrixForward(my_pos,mech->GetLocalToWorld()) > GetSquaredDistToMatrixBackward(my_pos,mech->GetLocalToWorld())) { return (false); } return (false); } //________________________________________________________________________________________________________________ void Flag::Execute_ReturnToOrigin() { SetNewLocalToParent(m_Origin); Broadcast_FlagReturned(); if (m_Team != MWApplication::No_Team) { NotifyFlagReturned(m_Team); } m_DeactiveTime = 0; } //________________________________________________________________________________________________________________ void Flag::Execute_AttachTo(Adept::Entity* entity) { Verify(Attached() == 0); Verify(entity != 0); IncrementScore(CBucketManager::FLAGS_TAKEN,entity->GetReplicatorID()); #if !defined(NO_LOG) MW4log_generic(MW4P_DSTATS, va("Flag_Taken\t%d", entity->GetReplicatorID().connectionID)); #endif // !defined(NO_LOG) m_HoldTimeLastUpdate = (Stuff::Scalar)gos_GetElapsedTime(); Attach(entity); if (Attached() != 0) { Vehicle* vehicle = Cast_Object(Vehicle*,entity); NotifyFlagTaken(m_Team,vehicle->GetTeam(),vehicle->instanceName); Broadcast_FlagTaken(*vehicle); } } //________________________________________________________________________________________________________________ void Flag::Execute_Drop() { Verify(Attached() != 0); m_HoldTimeLastUpdate = 0; Stuff::LinearMatrix4D matrix(Attached()->GetLocalToWorld()); Stuff::Scalar desired_height = ((Stuff::Point3D)matrix).y; Stuff::UnitVector3D unit_backwards; matrix.GetLocalBackwardInWorld(&unit_backwards); Stuff::Point3D backwards(unit_backwards); backwards *= flag_drop_behind_distance; backwards += (Stuff::Point3D)matrix; FindGoodDropSpot(backwards,desired_height); matrix.BuildTranslation(backwards); SetNewLocalToParent(matrix); SyncMatrices(true); Map::GetInstance()->UpdateZone(this); IncrementScore(CBucketManager::FLAGS_DROPPED,Attached()->GetReplicatorID()); #if !defined(NO_LOG) MW4log_generic(MW4P_DSTATS, va("Flag_Drop\t%d", Attached()->GetReplicatorID().connectionID)); #endif // !defined(NO_LOG) Vehicle* vehicle = Cast_Object(Vehicle*,Attached()); Check_Object(vehicle); NotifyFlagDropped(m_Team,vehicle->GetTeam(),vehicle->instanceName); Attach (NULL); switch (GetFlagDropReturnTime()) { case 0: { // ngLog addition #if !defined(NO_LOG) if(m_Team != MWApplication::No_Team) { MW4log_generic(MW4P_DSTATS, va("Flag_Return\t-1\t%d", m_Team)); } #endif // !defined(NO_LOG) Execute_ReturnToOrigin(); break; } case -1: { return; } default: { m_DeactiveTime = gos_GetElapsedTime() + GetFlagDropReturnTime(); } } } //________________________________________________________________________________________________________________ bool Flag::CarrierCanStillCarryMe() { Verify(Attached() != 0); if ((Attached()->IsDestroyed() == true) || (Attached()->IsDerivedFrom(Mech::DefaultData) == false)) { return (false); } if (GetTeam() != MWApplication::No_Team) { Mech* mech = Cast_Object(Mech*,Attached()); if (mech->GetTeam() == GetTeam()) { return (false); } } Mech* mech = Cast_Object(Mech*,Attached()); if (mech->IsShutdown() == true) { return (false); } return (true); } //________________________________________________________________________________________________________________ bool Flag::CarrierCanCaptureMe() { Verify(Attached() != 0); Verify(Attached()->IsDerivedFrom(Mech::DefaultData) == true); MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance()); if (mwmission->GetFlagCaptureEnabled() == false) { return (false); } Mech* mech = Cast_Object(Mech*,Attached()); if (GetTeam() == MWApplication::No_Team) { return (CanDropTeamFlagHere(mech->GetTeam())); } else { if (mech->GetTeam() != GetTeam()) { return (CanDropTeamFlagHere(mech->GetTeam())); } } return (false); } //________________________________________________________________________________________________________________ void Flag::Execute_Capture() { Verify(Attached() != 0); IncrementScore(CBucketManager::FLAGS_CAPTURED,Attached()->GetReplicatorID()); g_RSF.RecScore(CBucketManager::FLAGS_CAPTURED,Attached()->GetReplicatorID()); // jcem #if !defined(NO_LOG) MW4log_generic(MW4P_DSTATS, va("Flag_Capture\t%d", Attached()->GetReplicatorID().connectionID)); #endif // !defined(NO_LOG) if (Attached()->IsDerivedFrom(Mech::DefaultData) == true) { Mech* mech = Cast_Object(Mech*,Attached()); NotifyFlagCaptured(m_Team,mech->GetTeam(),mech->instanceName); } m_HoldTimeLastUpdate = 0; Broadcast_FlagCaptured(); Attach(NULL); switch (GetFlagCaptureReturnTime()) { case 0: { SetNewLocalToParent(m_Origin); break; } case -1: { HideFlag(); m_WaitAfterCaptureTime = -1; break; } default: { HideFlag(); m_WaitAfterCaptureTime = gos_GetElapsedTime() + GetFlagCaptureReturnTime(); break; } } } //________________________________________________________________________________________________________________ int Flag::FlagDropNameToTeamNumber(char* name) const { if (name == 0) { return (MWApplication::No_Team); } char buf[200]; strcpy(buf,name); std::string s(_strlwr(buf)); std::string::size_type pos(s.find("teamcapture")); if (pos != std::string::npos) { pos += 11; if (pos < s.size()) { s.erase(0,pos); if (s.size() > 1) { s.erase(1,s.size() - 1); } char* stopstring; long team_number(strtol(s.c_str(),&stopstring,10)); if (team_number == 0) { team_number = MWApplication::No_Team; } else { --team_number; } if ((team_number >= 0) && (team_number <= 7)) { return (team_number); } } } return (MWApplication::No_Team); } //________________________________________________________________________________________________________________ int Flag::GetFlagDropReturnTime() { MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance()); return (mwmission->GetFlagDropReturnTime()); } //________________________________________________________________________________________________________________ int Flag::GetFlagCaptureReturnTime() { MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance()); return (mwmission->GetFlagCaptureReturnTime()); } //________________________________________________________________________________________________________________ int Flag::GetMyIndex() { Verify(Attached() != 0); std::vector flags; GetFlagsCarriedBy(*(Attached()),flags); {for (int i = 0; i < flags.size(); ++i) { if (flags[i] == this) { return (i); } }} Verify(!"Should never get here."); return (0); } //________________________________________________________________________________________________________________ void Flag::IncrementScore(int bucket_type, const Adept::ReplicatorID& id) { MWMission *mission = Cast_Object(MWMission*,MWMission::GetInstance()); mission->m_BucketManager->NotifyAction((CBucketManager::Bucket_Type)bucket_type,id,1); } //________________________________________________________________________________________________________________ bool Flag::Enabled() { if (m_Team != MWApplication::No_Team) { if ((MWApplication::GetInstance() == 0) || (MWApplication::GetInstance()->TeamHasAnyPlayers(m_Team) == false)) { return (false); } } MWMission* mwmission = Cast_Object(MWMission*,MWMission::GetInstance()); switch (mwmission->GetFlagsEnabled()) { case MWMission::FLAGS_HIDE: { return (false); } case MWMission::FLAGS_TEAM_ONLY: { return ((m_Team >= 0) && (m_Team <= 7)); } case MWMission::FLAGS_UNIVERSAL_ONLY: { return (m_Team == MWApplication::No_Team); } case MWMission::FLAGS_SHOW_ALL: { return (true); } } Verify(!"Enable state not found"); return (false); } //________________________________________________________________________________________________________________ void Flag::Respawn(Adept::Entity::CreateMessage *message) { Attach(NULL); HideFlag(); SetNewLocalToParent(m_Origin); m_DeactiveTime = 0; m_WaitAfterCaptureTime = 0; m_HoldTimeLastUpdate = 0; if (message != 0) { Entity::Respawn(message); } } //________________________________________________________________________________________________________________ void Flag::RemoveAllFlagsFrom(Adept::Entity& entity) { NameTable *table = NameTable::GetInstance(); if (table == 0) { return; } int size(table->nameTableArray[NameTable::FlagArray].GetLength()); {for (int i = 0; i < size; ++i) { NameTableEntry *data = &table->nameTableArray [NameTable::FlagArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent(); if ((ent != 0) && (ent->IsDerivedFrom(Flag::DefaultData) == true)) { Flag* flag = Cast_Object(Flag*,ent); if (flag->Attached() == &entity) { flag->Execute_Drop(); } } }} } //________________________________________________________________________________________________________________ void Flag::ResetAllFlags() { NameTable *table = NameTable::GetInstance(); if (table == 0) { return; } int size(table->nameTableArray[NameTable::FlagArray].GetLength()); {for (int i = 0; i < size; ++i) { NameTableEntry *data = &table->nameTableArray [NameTable::FlagArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent(); if ((ent != 0) && (ent->IsDerivedFrom(Flag::DefaultData) == true)) { Flag* flag = Cast_Object(Flag*,ent); if (flag->Attached() != 0) { flag->Attach(0); } } }} } //________________________________________________________________________________________________________________ bool Flag::AnyFlagsAttachedTo(Adept::Entity& entity) { NameTable *table = NameTable::GetInstance(); if (table == 0) { return (false); } int size(table->nameTableArray[NameTable::FlagArray].GetLength()); {for (int i = 0; i < size; ++i) { NameTableEntry *data = &table->nameTableArray [NameTable::FlagArray][i]; Adept::Entity* ent = data->dataPointer->GetCurrent(); if ((ent != 0) && (ent->IsDerivedFrom(Flag::DefaultData) == true)) { Flag* flag = Cast_Object(Flag*,ent); if (flag->Attached() == &entity) { return (true); } } }} return (false); } //________________________________________________________________________________________________________________ bool CouldDropAtPoint(const Stuff::Point3D& point, Stuff::Scalar desired_height, Adept::Entity* who) { Stuff::Scalar minZ, maxZ, minX, maxX; Map::GetInstance()->GetMapExtents(&minZ,&maxZ,&minX,&maxX); if ((point.x <= minX) || (point.x >= maxX) || (point.z <= minZ) || (point.z >= maxZ)) { return (false); } if (MWMission::GetInstance()->GetMissionArea(point) != MWMission::InMissionArea) { return (false); } #pragma warning (disable : 4800) if (MW4AI::CheckCanPass(MW4AI::g_MissionGraph->Passable(point.x,point.z),MW4AI::LEGPASS_FLAG) == true) { return (false); } #pragma warning (default : 4800) Verify(Adept::Map::GetInstance() != 0); Stuff::Line3D line; line.m_length = 200.0f; line.m_direction = Vector3D::Down; line.m_origin = point; line.m_origin.y += 50.0f; Stuff::Normal3D normal; Entity::CollisionQuery query(&line,&normal,Entity::CanBeWalkedOnFlag,who); Check_Object(CollisionGrid::Instance); if (CollisionGrid::Instance->ProjectLine(&query) != Adept::Map::GetInstance()) { return (false); } Stuff::Point3D hit_spot; line.FindEnd(&hit_spot); if ((hit_spot.y < desired_height - 10) || (hit_spot.y > desired_height + 10)) { return (false); } return (true); } void Flag::FindGoodDropSpot(Stuff::Point3D& point, Stuff::Scalar desired_height) { if (CouldDropAtPoint(point,desired_height,Attached()) == true) { return; } Stuff::Scalar move_distance = 8.0f; {for (int i_x = 0; i_x < 10; ++i_x) { Stuff::Scalar x_delta = move_distance * (Stuff::Scalar)i_x; if (i_x & 0x01) { x_delta *= -1; } {for (int i_z = 0; i_z < 10; ++i_z) { Stuff::Scalar z_delta = move_distance * (Stuff::Scalar)i_z; if (i_z & 0x01) { z_delta *= -1; } Stuff::Point3D p(point.x + x_delta,point.y,point.z + z_delta); if (CouldDropAtPoint(p,desired_height,Attached()) == true) { point = p; return; } }} }} } int Flag::GetExecutionSlot() { return (Entity::GetExecutionSlot()); } void Flag::AddStatsToString(std::string& s) { s += instanceName; if (GetTeam() != MWApplication::No_Team) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_TEAM4);//"Team: "; s += IntToString(m_Team); s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_SPACE_NEWLINE);//" \n"; } if (Attached() != 0) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_ATTACHED);//"Attached: \n"; // s += IntToString(Attached()->objectID); // s += "\n"; } else { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_NOT_ATTACHED);//"Not attached\n"; } if (m_Visible == true) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_VISIBLE);//"Visible\n"; } else { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_NOT_VISIBLE);//"Not Visible\n"; } if (Enabled() == true) { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_ENABLED);//"Enabled\n"; } else { s += Application::GetInstance()->GetLocString(IDS_FLAGS_CPP_NOT_ENABLED);//"Not Enabled\n"; } } void Flag::BecomeInteresting(bool render_me) { Check_Object(this); LOAD_LOGIC("Become Interesting::Flag"); // //------------------ // Validate children //------------------ // ChainIteratorOf children(&childEntityChain); Entity *entity; while ((entity = children.ReadAndNext()) != NULL) { Check_Object(entity); entity->BecomeInteresting(render_me); } // //----------------------------- // Now make ourself interesting //----------------------------- // /* extern int g_TeamDecal; if (GetTeam() != MWApplication::No_Team) { Team * team = MWApplication::GetInstance()->teams[GetTeam()]->GetCurrent(); if (team) g_TeamDecal = team->GetTeamDecal(); } */ BaseClass::BecomeInteresting(render_me); } // MSL 5.03 Fixed Flag_Taken (disabled) void Flag::Broadcast_FlagTaken(Adept::Entity& entity) { VehicleInterface* vi = VehicleInterface::GetInstance(); if (vi != 0) { if (&entity == vi->vehicle) { // m_LastFlagEvent = FLAG_TAKEN_BY_ME; // MSL Currently only the server is playing the Taken_by_me sound. Disabling. m_LastFlagEvent = FLAG_TAKEN; } else { m_LastFlagEvent = FLAG_TAKEN; } } else { m_LastFlagEvent = FLAG_TAKEN; } ReactToFlagEvent(m_LastFlagEvent); } void Flag::PlaySound_FlagTaken() { if (VehicleInterface::GetInstance() != 0) { VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::FLAGTAKEN); } } // MSL 5.03 Fixed Flag_Taken void Flag::PlaySound_FlagTakenByMe() { if (VehicleInterface::GetInstance() != 0) { VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::YOUHAVEFLAG); } } void Flag::Broadcast_FlagReturned() { m_LastFlagEvent = FLAG_RETURNED; ReactToFlagEvent(m_LastFlagEvent); } void Flag::PlaySound_FlagReturned() { if (VehicleInterface::GetInstance() != 0) { VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::FLAGRETURNED); } } void Flag::Broadcast_FlagCaptured() { m_LastFlagEvent = FLAG_CAPTURED; ReactToFlagEvent(m_LastFlagEvent); } void Flag::PlaySound_FlagCaptured() { if (VehicleInterface::GetInstance() != 0) { MWMission *mission = Cast_Object (MWMission *,MWMission::GetInstance()); Check_Object (mission); int theType = mission->GetMissionType(); if (theType == MWMission::MISSIONTYPE_COLISEUM) { VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::FLAGCAPTUREDHORN); } else { VehicleInterface::GetInstance()->ReactToEvent(VehicleInterface::FLAGCAPTUREDBUZZER); } } } void Flag::ReactToFlagEvent(FlagEvent event) { switch (event) { case FLAG_TAKEN: { Flag::PlaySound_FlagTaken(); break; } // MSL 5.03 Fixed Flag_Taken case FLAG_TAKEN_BY_ME: { Flag::PlaySound_FlagTakenByMe(); break; } case FLAG_CAPTURED: { Flag::PlaySound_FlagCaptured(); break; } case FLAG_RETURNED: { Flag::PlaySound_FlagReturned(); break; } } } Flag::FlagEvent Flag::GetLastFlagEvent() const { return (m_LastFlagEvent); } void Flag::SetLastFlagEvent(FlagEvent event) { if ((event == m_LastFlagEvent) || (Network::GetInstance()->AmIServer())) { return; } ReactToFlagEvent(event); m_LastFlagEvent = event; }