void ActorSet::addAll(ActorSet &s) { for(ActorSet::iterator iter = s.begin(); iter != s.end(); ++iter) { insert(*iter); } }
Actor* Actor::Create(String archetype) { //TODO: this is kind of a fragile way to get the Actor the script created. // Let's figure out a smarter way to get the object directly from Python, // hopefully without introducing a bunch of Python API code into Angel proper. String markerTag = "last-spawned-actor-from-code"; String toExec = "Actor._lastSpawnedActor = Actor.Create('" + archetype + "')\n"; toExec += "Actor._lastSpawnedActor.Tag('" + markerTag + "')\n"; theWorld.ScriptExec(toExec); ActorSet tagged = theTagList.GetObjectsTagged(markerTag); if (tagged.size() > 1) { sysLog.Log("WARNING: more than one Actor tagged with '" + markerTag + "'. (" + archetype + ")"); } if (tagged.size() < 1) { sysLog.Log("ERROR: Script failed to create Actor with archetype " + archetype + ". "); return NULL; } ActorSet::iterator it = tagged.begin(); Actor* forReturn = *it; toExec = "Actor._lastSpawnedActor.__disown__()\n"; toExec += "Actor._lastSpawnedActor = None\n"; theWorld.ScriptExec(toExec); if (forReturn != NULL) { forReturn->Untag(markerTag); } return forReturn; }
ActorSet MonsterFSM::getApplicableTargets(void) const { ASSERT(m_Owner!=0, "Owner was NULL"); ActorSet s = m_Owner->getZone().getObjects().exclude(m_Owner->m_ID).typeFilter<Player>(); // remove actors that are dead or ghosts ActorSet::iterator i = s.begin(); while(i != s.end()) { ActorSet::iterator nextIterator = i; ++nextIterator; const Player &player = dynamic_cast<const Player&>(*i->second); if(!player.isAlive()) { s.erase(i); } i = nextIterator; } return s; }
ActorSet TagCollection::GetObjectsTagged(String findTag) { StringList tags = SplitString(findTag, ", "); if (tags.size() == 0) { return ActorSet(); } else if (tags.size() == 1) { findTag = ToLower(findTag); std::map<String, ActorSet>::iterator it = _tagMappings.find(findTag); if (it != _tagMappings.end()) { return it->second; } else { return ActorSet(); } } else { ActorSet t1; ActorSet t2; String searchTag = ToLower(tags[0]); bool t1_active = true; t1 = GetObjectsTagged(searchTag); for(unsigned int i=1; i < tags.size(); i++) { searchTag = ToLower(tags[i]); ActorSet compare = GetObjectsTagged(searchTag); if (t1_active) { std::set_intersection(t1.begin(), t1.end(), compare.begin(), compare.end(), std::inserter(t2, t2.begin())); t1.clear(); t1_active = false; } else { std::set_intersection(t2.begin(), t2.end(), compare.begin(), compare.end(), std::inserter(t1, t1.begin())); t2.clear(); t1_active = true; } } if (t1_active) { return t1; } else { return t2; } } }
void ActorSet::moveObject(ActorSet &dest, OBJECT_ID id) { ASSERT(isMember(id), "The object is not a member of this set"); ASSERT(!dest.isMember(id), "The object is already a member of the other set"); // Add it to the other set dest.insert( make_pair(id, toActor(*find(id))) ); // Remove it from this set erase(find(id)); }
void DemoScreenPathfinding::Start() { //Set up our obstacle course theWorld.LoadLevel("maze"); //Create the bounding box that will limit the pathfinding search area BoundingBox bounds(Vector2(-20, -20), Vector2(20, 20)); //Create our pathfinding graph. In our 2D worlds, this is a relatively fast // operation -- you shouldn't be doing it every frame, but recalculating every // so often if your world has changed is not inappropriate. theSpatialGraph.CreateGraph( 0.75f, //The size of the entity you want to pathfind (so the generator // can know how small a space can be and still have it fit.) bounds //The search area ); //Create a MazeFinder (class definition below), and put him in the bottom // left corner of the maze MazeFinder *mf = new MazeFinder(); mf->SetPosition(-11.5, -8); theWorld.Add(mf); //Send him to the upper right, watch him scurry mf->GoTo(Vector2(11.5, 8)); //Demo housekeeping below this point. #pragma region Demo housekeeping String description = "This little dude is pathfinding through the area."; description += "\n\nClick the mouse to give him a new target."; description += "\n\nPress [B] to see the pathfinding graph."; TextActor *t = new TextActor("Console", description); t->SetAlignment(TXT_Center); t->SetPosition(0.0f, -5.0f); theWorld.Add(t); TextActor *fileLoc = new TextActor("ConsoleSmall", "DemoScreenPathfinding.cpp"); fileLoc->SetPosition(MathUtil::ScreenToWorld(5, 763)); fileLoc->SetColor(.3f, .3f, .3f); theWorld.Add(fileLoc); _objects.push_back(fileLoc); _objects.push_back(t); _objects.push_back(mf); ActorSet walls = theTagList.GetObjectsTagged("maze_wall"); ActorSet::iterator it = walls.begin(); while (it != walls.end()) { _objects.push_back(*it); it++; } #pragma endregion }
void DemoScreenCollisionLevelFile::Start() { //Loads the file from Config\ActorDef\collisionlevel_demo.lvl LoadLevel("collisionlevel_demo"); //All the magic happens in the level file! //Demo housekeeping below this point. #pragma region Demo housekeeping t = new TextActor("Console", "These Actors were also placed using a level file."); t->SetPosition(0, 4.5); t->SetAlignment(TXT_Center); theWorld.Add(t, 10); t2 = new TextActor("Console", "Their physics-related properties came from actor definitions."); t2->SetPosition(0, -3.5); t2->SetAlignment(TXT_Center); theWorld.Add(t2, 10); t3 = new TextActor("Console", "They respond to sound in a data driven way."); t3->SetPosition(0, -4.5); t3->SetAlignment(TXT_Center); theWorld.Add(t3, 10); t4 = new TextActor("Console", "If the only collision response you need is sound, this is easier."); t4->SetPosition(0, -5.5); t4->SetAlignment(TXT_Center); theWorld.Add(t4, 10); TextActor *fileLoc = new TextActor("ConsoleSmall", "DemoScreenCollisionLevelFile.cpp, collisionlevel_demo.lvl,"); TextActor *fileLoc2 = new TextActor("ConsoleSmall", " ground_actor.adf, physics_event_actor.adf"); fileLoc->SetPosition(MathUtil::ScreenToWorld(5, 745)); fileLoc->SetColor(.3f, .3f, .3f); fileLoc2->SetPosition(MathUtil::ScreenToWorld(5, 763)); fileLoc2->SetColor(.3f, .3f, .3f); theWorld.Add(fileLoc, 10); theWorld.Add(fileLoc2, 10); _objects.push_back(fileLoc); _objects.push_back(fileLoc2); _objects.push_back(t); _objects.push_back(t2); _objects.push_back(t3); _objects.push_back(t4); ActorSet spawnedActors = tagList.GetObjectsTagged("spawned"); ActorSet::iterator it = spawnedActors.begin(); while (it != spawnedActors.end()) { _objects.push_back(*it); it++; } #pragma endregion }
ActorSet ActorSet::exclude(OBJECT_ID id) const { ActorSet s = *this; ActorSet::iterator iter = s.find(id); if(iter != s.end()) // if present { s.erase(iter); } return s; }
bool MagicTower::attack() { int opt = thePrefs.GetInt("PlayerSettings", "Tactics"); bool (*tactics[6])(Enemy*, Enemy*) = { (bool(*)(Enemy*, Enemy*))&Tower::nearest_tower, (bool(*)(Enemy*, Enemy*))&Tower::nearest_castle, (bool(*)(Enemy*, Enemy*))&Tower::weakest, (bool(*)(Enemy*, Enemy*))&Tower::strongest, (bool(*)(Enemy*, Enemy*))&Tower::fastest, (bool(*)(Enemy*, Enemy*))&Tower::slowest }; Vector2 pos = this->GetPosition(); ActorSet enemies = theTagList.GetObjectsTagged("enemy"); ActorSet::iterator it = enemies.begin(); float min_dist = 1000.0; Enemy* for_dmg = NULL; while(it != enemies.end()) { Vector2 en_pos = (*it)->GetPosition(); float dist = Vector2::DistanceSquared(en_pos, pos); if ((dist <= MathUtil::PixelsToWorldUnits(Level::Radius(level))) && ((for_dmg == NULL) || (tactics[opt]((Enemy*)(*it), for_dmg)))) { for_dmg = (Enemy*)(*it); } it++; } if(for_dmg) { Actor *circle = new Actor(); circle->SetPosition(this->GetPosition()); circle->SetColor(0.7f, 0.3f, 0.5f); circle->SetDrawShape(ADS_Circle); circle->SetSize(0.1); theWorld.Add(circle, 3); circle->MoveTo(for_dmg->GetPosition(), 0.1); std::thread for_del(&MagicTower::delete_circle, this, circle); for_del.detach(); for_dmg->get_damage(thePrefs.GetFloat("TowerSettings", "MagicDmg")); int random_effect = MathUtil::RandomIntInRange(1, 3); switch(random_effect) { case 1: { std::shared_ptr<Effect> ef(new Poisoning()); for_dmg->effect(ef); break; } case 2: { std::shared_ptr<Effect> ef(new Deceleration()); for_dmg->effect(ef); break; } case 3: { std::shared_ptr<Effect> ef(new Weakness()); for_dmg->effect(ef); break; } } } }
ActorSet ActorSet::haveMoved(void) const { ActorSet s; for(const_iterator i=begin(); i!=end(); ++i) { const Actor *p = i->second; if(!p->zombie && (p->hasAnimated || p->hasMoved)) { s.insert(*i); } } return s; }
ActorSet ActorSet::isNotWithin(const Frustum &frustum) const { ActorSet s; for(const_iterator i=begin(); i!=end(); ++i) { const Actor *p = i->second; if(!p->zombie && !frustum.SphereInFrustum2(p->getPos(), p->getSphereRadius()*2)) { s.insert(*i); } } return s; }
void DemoScreenLayeredCollisionLevelFile::Start() { //Give names to some layers so we can reference them more easily theWorld.NameLayer("background", 0); theWorld.NameLayer("foreground", 1); theWorld.NameLayer("hud", 2); //Loads the file from Config\ActorDef\layeredcollisionlevel_demo.lua theWorld.LoadLevel("layeredcollisionlevel_demo"); //All the magic happens in the level file! //Demo housekeeping below this point. #pragma region Demo housekeeping t2 = new TextActor("Console", "These new Actors were assigned layers in their level file."); t2->SetPosition(0, 5.5); t2->SetAlignment(TXT_Center); theWorld.Add(t2, 10); t3 = new TextActor("Console", "Layers can be given string names as well as numbers"); t3->SetPosition(0, 4.5); t3->SetAlignment(TXT_Center); theWorld.Add(t3, 10); t4 = new TextActor("Console", "and assigned to Actors in their definition file or at runtime."); t4->SetPosition(0, 3.5); t4->SetAlignment(TXT_Center); theWorld.Add(t4, 10); TextActor *fileLoc = new TextActor("ConsoleSmall", "DemoScreenLayeredCollisionLevelFile.cpp, layeredcollisionlevel_demo.lua"); fileLoc->SetPosition(MathUtil::ScreenToWorld(5, 763)); fileLoc->SetColor(.3f, .3f, .3f); theWorld.Add(fileLoc, 10); _objects.push_back(fileLoc); _objects.push_back(t2); _objects.push_back(t3); _objects.push_back(t4); ActorSet spawnedActors = theTagList.GetObjectsTagged("spawned"); ActorSet::iterator it = spawnedActors.begin(); while (it != spawnedActors.end()) { _objects.push_back(*it); it++; } #pragma endregion }
int main(int argc, char *argv[]) { QApplication app(argc, argv); glutInit(&argc, argv); MainWindow mainWin; mainWin.show(); ActorSet* aset = new ActorSet();; for(int i = 1; i < argc; i++){ aset->addActorFromPath(argv[i]); } mainWin.setActorSet(aset); return app.exec(); }
ActorSet Shadow::calculateReceivers(const ActorSet &zoneActors, const mat4& lightProjectionMatrix, const mat4& lightViewMatrix) { Frustum f; f.CalculateFrustum(lightViewMatrix, lightProjectionMatrix); const ActorSet s = zoneActors.isWithin(f); return s; }
void GotoTargetAIEvent::Update(float dt) { ActorSet taggedActors = theTagList.GetObjectsTagged(_targetTag); for( ActorSet::iterator itr = taggedActors.begin(); itr != taggedActors.end(); itr++ ) { Actor* pTargetActor = (*itr); if( theSpatialGraph.IsInPathableSpace( pTargetActor->GetPosition() ) ) { _destination = pTargetActor->GetPosition(); GotoAIEvent::Update( dt ); return; } } //otherwise, we failed _moveFailed = true; IssueCallback(); }
void Bullet::onTrigger(void) { OBJECT_ID id = INVALID_ID; // Only consider Creature from our World that are not the Bullet owner ActorSet s = getZone().getObjects().typeFilter<Creature>().exclude(owner); if(isAnythingInProximity(s, id)) { Creature& creature = dynamic_cast<Creature&>(s.get(id)); creature.damage(damageValue, owner); creature.applyKnockBack(creature.getPos()-getPos()); if(causesFreeze) creature.freeze(); kill(); } }
void Shadow::update(const ActorSet &zoneActors, float deltaTime) { if(light!=0 && zoneActors.isMember(actorID)) { const Actor &actor = zoneActors.get(actorID); // Update the shadow when something has changed needsUpdate |= (actor.hasAnimated || actor.hasMoved); // Update when necessary or requested if(needsUpdate) { float lx=0, ly=0; calculateAngularSpread(actor, lightViewMatrix, lx, ly); calculateMatrices(*light, actor, shadowMapSize, lightProjectionMatrix, lightViewMatrix, textureMatrix, lx, ly); frustum = calculateFrustum(lightProjectionMatrix, lightViewMatrix); if(g_Application.displayDebugData) { calculateFrustumVertices(*light, actor, lx, ly, ntl, ntr, nbl, nbr, ftl, ftr, fbl, fbr); } renderToShadow(shadowMapTexture, shadowMapSize, actor, lightProjectionMatrix, lightViewMatrix); needsUpdate=false; } // Periodically take some time to determine the actors that be receiving this shadow periodicTimer-=deltaTime; if(periodicTimer<0) { periodicTimer = 250.0f + FRAND_RANGE(100.0f, 250.0f); // stagger receivers = calculateReceivers(zoneActors, lightProjectionMatrix, lightViewMatrix); } } }
void Shadow::bind(const ActorSet &zoneActors, unsigned int textureUnit) const { if(light!=0 && zoneActors.isMember(actorID)) { CHECK_GL_ERROR(); // Bind shadow texture glActiveTextureARB(textureStages[textureUnit]); glClientActiveTextureARB(textureStages[textureUnit]); glBindTexture(GL_TEXTURE_2D, shadowMapTexture); glEnable(GL_TEXTURE_2D); // Define the matrix const float row1[4] = {textureMatrix.m[0], textureMatrix.m[4], textureMatrix.m[8], textureMatrix.m[12]}; const float row2[4] = {textureMatrix.m[1], textureMatrix.m[5], textureMatrix.m[9], textureMatrix.m[13]}; const float row3[4] = {textureMatrix.m[2], textureMatrix.m[6], textureMatrix.m[10], textureMatrix.m[14]}; const float row4[4] = {textureMatrix.m[3], textureMatrix.m[7], textureMatrix.m[11], textureMatrix.m[15]}; // Enable tex coord generation glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glEnable(GL_TEXTURE_GEN_Q); // Define the parameters of the generation glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); // Pass the texture matrix we defined above glTexGenfv(GL_S, GL_EYE_PLANE, row1); glTexGenfv(GL_T, GL_EYE_PLANE, row2); glTexGenfv(GL_R, GL_EYE_PLANE, row3); glTexGenfv(GL_Q, GL_EYE_PLANE, row4); // Enable shadow comparison glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY); CHECK_GL_ERROR(); } }
void DemoScreenLevelFile::Start() { //Loads the file from Config\ActorDef\level_demo.lua // Level files automatically add their actors to the world. theWorld.LoadLevel("level_demo"); //Since the Actors were just added directly to the world, // we don't have handles to them. The level definition // gave them the tag "spawned," so we can get them that way. ActorSet spawnedActors = theTagList.GetObjectsTagged("spawned"); ActorSet::iterator it = spawnedActors.begin(); while (it != spawnedActors.end()) { //Can check Individual actors for tags as well. if ((*it)->IsTagged("left-tilted")) { (*it)->SetRotation(25.0f); } else if ((*it)->IsTagged("right-tilted")) { (*it)->SetRotation(-25.0f); } //Applying tags (*it)->Tag("rotated"); //Removing tags (*it)->Untag("spawned"); it++; } //Demo housekeeping below this point. #pragma region Demo housekeeping t = new TextActor("Console", "These Actors were placed and tagged (\"left-tilted\""); t->SetPosition(0, 5.5); t->SetAlignment(TXT_Center); theWorld.Add(t); t2 = new TextActor("Console", "and \"right-tilted\") using a level definition file."); t2->SetPosition(0, 4.5); t2->SetAlignment(TXT_Center); theWorld.Add(t2); t3 = new TextActor("Console", "Then their rotations were set based on those tags."); t3->SetPosition(0, -4.5); t3->SetAlignment(TXT_Center); theWorld.Add(t3); TextActor *fileLoc = new TextActor("ConsoleSmall", "DemoScreenLevelFile.cpp, level_demo.lua"); fileLoc->SetPosition(MathUtil::ScreenToWorld(5, 763)); fileLoc->SetColor(.3f, .3f, .3f); theWorld.Add(fileLoc); _objects.push_back(fileLoc); _objects.push_back(t); _objects.push_back(t2); _objects.push_back(t3); it = spawnedActors.begin(); while (it != spawnedActors.end()) { _objects.push_back(*it); it++; } #pragma endregion }
int approxActorSet(const ActorSet& r) { int size = sizeof(r); LOGF(Priority::DEBUG, "ActorSet\t%s\t%d b", r.name().c_str(), size); return size; }
void GameApp::ReceiveMessage(Message* message) { if (message->GetMessageName() == "MouseDown") { Castle* castle = (Castle*)Actor::GetNamed("Castle"); TypedMessage<Vec2i> *m = (TypedMessage<Vec2i>*)message; Vec2i screenCoordinates = m->GetValue(); Vector2 click = MathUtil::ScreenToWorld(screenCoordinates); if(tower != 3){ ActorSet background = theTagList.GetObjectsTagged("grass"); ActorSet::iterator it = background.begin(); while(it != background.end()){ Vector2 position = (*it)->GetPosition(); Vector2 size = (*it)->GetSize(); if ((click.X < position.X + size.X/2.0) && (click.X > position.X - size.X/2.0) && (click.Y < position.Y + size.Y/2.0) && (click.Y > position.Y - size.Y/2.0)){ if(!(castle->buy_tower(tower))) return; if(tower == 1){ StandartTower* new_tower = (StandartTower*)Actor::Create("standart_tower"); new_tower->SetPosition(click); theWorld.Add(new_tower, 2); } if(tower == 2){ MagicTower* new_tower = (MagicTower*)Actor::Create("magic_tower"); new_tower->SetPosition(click); theWorld.Add(new_tower, 2); } break; } it++; } } else{ ActorSet background = theTagList.GetObjectsTagged("road"); ActorSet::iterator it = background.begin(); while(it != background.end()){ Vector2 position = (*it)->GetPosition(); Vector2 size = (*it)->GetSize(); if ((click.X < position.X + size.X/2.0) && (click.X > position.X - size.X/2.0) && (click.Y < position.Y + size.Y/2.0) && (click.Y > position.Y - size.Y/2.0)){ if(!(castle->buy_tower(tower))) return; Trap* new_trap = (Trap*)Actor::Create("trap"); new_trap->SetPosition(click); theWorld.Add(new_trap, 1); break; } it++; } } theSwitchboard.UnsubscribeFrom(this, "MouseDown"); } }