std::vector <NavNode*> NavMesh::Path(glm::vec3 _StartPos, glm::vec3 _EndPos) { StartNode = GiveScore(m_Graph, _StartPos); CurrentNode = GiveScore(m_Graph, _StartPos); EndNode = GiveScore(m_Graph, _EndPos); CurrentNode->Parent = nullptr; Open.emplace_back(CurrentNode); Open.emplace_back(CurrentNode); if((CurrentNode->Position.x != EndNode->Position.x)&&(CurrentNode->Position.z != EndNode->Position.z)) { PathList.emplace_back(CurrentNode); PathList.emplace_back(EndNode); return PathList; } do{ Closed.emplace_back(Open.front()); Open.erase(Open.begin()); std::sort( Open.begin(), Open.end(), Compare()); CurrentNode = Open.front(); for(int i=0;i<3;i++) { if(CurrentNode->edgeTarget[i] != nullptr) { int check =0; for(int a=0;a<Open.size();a++) { if(CurrentNode->edgeTarget[i]->Position == Open[a]->Position) { check ++; } } for(int a=0;a<Closed.size();a++) { if(CurrentNode->edgeTarget[i]->Position == Closed[a]->Position) { check ++; } } if(check == 0) { Open.emplace_back(CurrentNode->edgeTarget[i]); CurrentNode->edgeTarget[i]->Parent = CurrentNode; } } } }while((CurrentNode->Position.x != EndNode->Position.x)&&(CurrentNode->Position.z != EndNode->Position.z)); PathList.emplace_back(CurrentNode); while((CurrentNode->Parent != nullptr)&&(CurrentNode != nullptr)){ PathList.emplace(PathList.begin(), CurrentNode->Parent); CurrentNode = CurrentNode->Parent; } return PathList; }
// the 'cmdsrun' parameter counts how many commands are run. // if a 'Inv Item Was Used' check does not pass, it doesn't count // so cmdsrun remains 0 if no inventory items matched int run_interaction_commandlist (InteractionCommandList *nicl, int *timesrun, int*cmdsrun) { size_t i; if (nicl == NULL) return -1; for (i = 0; i < nicl->Cmds.size(); i++) { cmdsrun[0] ++; int room_was = play.room_changes; switch (nicl->Cmds[i].Type) { case 0: // Do nothing break; case 1: // Run script { TempEip tempip(4001); RuntimeScriptValue rval_null; update_mp3(); if ((strstr(evblockbasename,"character")!=0) || (strstr(evblockbasename,"inventory")!=0)) { // Character or Inventory (global script) const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); // we are already inside the mouseclick event of the script, can't nest calls QueueScriptFunction(kScInstGame, torun); } else { // Other (room script) const char *torun = make_ts_func_name(evblockbasename,evblocknum,nicl->Cmds[i].Data[0].Value); QueueScriptFunction(kScInstRoom, torun); } update_mp3(); break; } case 2: // Add score (first time) if (timesrun[0] > 0) break; timesrun[0] ++; case 3: // Add score GiveScore (IPARAM1); break; case 4: // Display Message /* if (comprdata<0) display_message_aschar=evb->data[ss];*/ DisplayMessage(IPARAM1); break; case 5: // Play Music PlayMusicResetQueue(IPARAM1); break; case 6: // Stop Music stopmusic (); break; case 7: // Play Sound play_sound (IPARAM1); break; case 8: // Play Flic play_flc_file(IPARAM1, IPARAM2); break; case 9: // Run Dialog { int room_was = play.room_changes; RunDialog(IPARAM1); // if they changed room within the dialog script, // the interaction command list is no longer valid if (room_was != play.room_changes) return -1; } break; case 10: // Enable Dialog Option SetDialogOption (IPARAM1, IPARAM2, 1); break; case 11: // Disable Dialog Option SetDialogOption (IPARAM1, IPARAM2, 0); break; case 12: // Go To Screen Character_ChangeRoomAutoPosition(playerchar, IPARAM1, IPARAM2); return -1; case 13: // Add Inventory add_inventory (IPARAM1); break; case 14: // Move Object MoveObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); // if they want to wait until finished, do so if (IPARAM5) GameLoopUntilEvent(UNTIL_MOVEEND,(long)&objs[IPARAM1].moving); break; case 15: // Object Off ObjectOff (IPARAM1); break; case 16: // Object On ObjectOn (IPARAM1); break; case 17: // Set Object View SetObjectView (IPARAM1, IPARAM2); break; case 18: // Animate Object AnimateObject (IPARAM1, IPARAM2, IPARAM3, IPARAM4); break; case 19: // Move Character if (IPARAM4) MoveCharacterBlocking (IPARAM1, IPARAM2, IPARAM3, 0); else MoveCharacter (IPARAM1, IPARAM2, IPARAM3); break; case 20: // If Inventory Item was used if (play.usedinv == IPARAM1) { if (game.options[OPT_NOLOSEINV] == 0) lose_inventory (play.usedinv); if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; } else cmdsrun[0] --; break; case 21: // if player has inventory item if (playerchar->inv[IPARAM1] > 0) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 22: // if a character is moving if (game.chars[IPARAM1].walking) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 23: // if two variables are equal if (IPARAM1 == IPARAM2) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 24: // Stop character walking StopMoving (IPARAM1); break; case 25: // Go to screen at specific co-ordinates NewRoomEx (IPARAM1, IPARAM2, IPARAM3); return -1; case 26: // Move NPC to different room if (!is_valid_character(IPARAM1)) quit("!Move NPC to different room: invalid character specified"); game.chars[IPARAM1].room = IPARAM2; break; case 27: // Set character view SetCharacterView (IPARAM1, IPARAM2); break; case 28: // Release character view ReleaseCharacterView (IPARAM1); break; case 29: // Follow character FollowCharacter (IPARAM1, IPARAM2); break; case 30: // Stop following FollowCharacter (IPARAM1, -1); break; case 31: // Disable hotspot DisableHotspot (IPARAM1); break; case 32: // Enable hotspot EnableHotspot (IPARAM1); break; case 33: // Set variable value get_interaction_variable(nicl->Cmds[i].Data[0].Value)->Value = IPARAM2; break; case 34: // Run animation scAnimateCharacter(IPARAM1, IPARAM2, IPARAM3, 0); GameLoopUntilEvent(UNTIL_SHORTIS0,(long)&game.chars[IPARAM1].animating); break; case 35: // Quick animation SetCharacterView (IPARAM1, IPARAM2); scAnimateCharacter(IPARAM1, IPARAM3, IPARAM4, 0); GameLoopUntilEvent(UNTIL_SHORTIS0,(long)&game.chars[IPARAM1].animating); ReleaseCharacterView (IPARAM1); break; case 36: // Set idle animation SetCharacterIdle (IPARAM1, IPARAM2, IPARAM3); break; case 37: // Disable idle animation SetCharacterIdle (IPARAM1, -1, -1); break; case 38: // Lose inventory item lose_inventory (IPARAM1); break; case 39: // Show GUI InterfaceOn (IPARAM1); break; case 40: // Hide GUI InterfaceOff (IPARAM1); break; case 41: // Stop running more commands return -1; case 42: // Face location FaceLocation (IPARAM1, IPARAM2, IPARAM3); break; case 43: // Pause command processor scrWait (IPARAM1); break; case 44: // Change character view ChangeCharacterView (IPARAM1, IPARAM2); break; case 45: // If player character is if (GetPlayerCharacter() == IPARAM1) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 46: // if cursor mode is if (GetCursorMode() == IPARAM1) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; case 47: // if player has been to room if (HasBeenToRoom(IPARAM1)) if (run_interaction_commandlist (nicl->Cmds[i].Children.get(), timesrun, cmdsrun)) return -1; break; default: quit("unknown new interaction command"); break; } // if the room changed within the action, nicl is no longer valid if (room_was != play.room_changes) return -1; } return 0; }
bool NavMesh::onCreate(int a_argc, char* a_argv[]) { // initialise the Gizmos helper class Gizmos::create(); // create a world-space matrix for a camera m_cameraMatrix = glm::inverse( glm::lookAt(glm::vec3(20,20,0),glm::vec3(0,0,0), glm::vec3(0,1,0)) ); // create a perspective projection matrix with a 90 degree field-of-view and widescreen aspect ratio m_projectionMatrix = glm::perspective(glm::pi<float>() * 0.25f, DEFAULT_SCREENWIDTH/(float)DEFAULT_SCREENHEIGHT, 0.1f, 1000.0f); // set the clear colour and enable depth testing and backface culling glClearColor(0.25f,0.25f,0.25f,1); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); m_sponza = new FBXFile(); m_sponza->load("../../Build/models/SponzaSimple.fbx", FBXFile::UNITS_CENTIMETER); createOpenGLBuffers(m_sponza); m_navMesh = new FBXFile(); m_navMesh->load("../../Build/models/SponzaSimpleNavMesh.fbx", FBXFile::UNITS_CENTIMETER); // createOpenGLBuffers(m_navMesh); BuildNavMesh(m_navMesh->getMeshByIndex(0), m_Graph); unsigned int vs = Utility::loadShader("../../Build/shaders/sponza.vert", GL_VERTEX_SHADER); unsigned int fs = Utility::loadShader("../../Build/shaders/sponza.frag", GL_FRAGMENT_SHADER); m_shader = Utility::createProgram(vs,0,0,0,fs); glDeleteShader(vs); glDeleteShader(fs); count = 0; Screen = new ShaderHandle(); Screen->Load(2, "Screen.vert", "Screen.frag"); bBlueUp = new Button(glm::vec2(25 , 25), glm::vec2(50)); bBlueDown = new Button(glm::vec2(25, 100), glm::vec2(50)); bRedUp = new Button(glm::vec2(100, 25), glm::vec2(50)); bRedDown = new Button(glm::vec2(100 ,100), glm::vec2(50)); Behaviour* Seek = new SeekTarget(10,this); Behaviour* Rand = new RandomiseTarget(10); Behaviour* Within = new WithinRange(0.5f); // IF not within range THEN seek ELSE randomise target // IF not attack THEN Above Sequence* Seq = new Sequence(); Seq->addchild(Within); Seq->addchild(Rand); Selector* Root = new Selector(); Root->addchild(Seq); Root->addchild(Seek); Agenda = Root; RedSize = 3; BlueSize = 3; Red = new Team(); Blue = new Team(); int FlagCount = 3; for (int i=0;i<FlagCount;i++) { Flags.emplace_back(new Flag()); } Flags[0]->Position = glm::vec3(9, 0, 7); Flags[1]->Position = glm::vec3(0, 0, 0); Flags[2]->Position = glm::vec3(-9, 0, -7); for (int i=0;i<RedSize;++i) { Red->AddMember(); glm::vec3 NewPos; NewPos.xz = glm::circularRand(20.0f); Red->Members[i]->Position = NewPos; } for (int i=0;i<BlueSize;++i) { Blue->AddMember(); glm::vec3 NewPos; NewPos.xz = glm::circularRand(20.0f); Blue->Members[i]->Position = NewPos; Blue->Members[i]->SetTarget(Flags[0]->GetPos()); } for(int i=0;i<RedSize;++i) { Red->Members[i]->SetTarget(Flags[0]->GetPos()); Red->Members[i]->CalcEnemy(Blue->Members); Red->Members[i]->SetBehaviour(Agenda); GiveScore(m_Graph, Red->Members[i]->Position); Red->Members[i]->Position = m_Graph[0]->Position; } for (int i=0;i<BlueSize;++i) { Blue->Members[i]->SetBehaviour(Agenda); Blue->Members[i]->CalcEnemy(Red->Members); GiveScore(m_Graph, Blue->Members[i]->Position); Blue->Members[i]->Position = m_Graph[0]->Position; } TestNode = m_Graph[rand()%m_Graph.size()]; Path(glm::vec3(-9,0,-3), glm::vec3(6,0,5)); return true; }