void Turret::update(int64 diff) { // No target : try to find a new one if(!isAttacking) { const std::map<uint32, Object*>& objects = map->getObjects(); Unit* nextTarget = 0; unsigned int nextTargetPriority = 10; for(auto& it : objects) { Unit* u = dynamic_cast<Unit*>(it.second); if(!u || u->isDead() || u->getTeam() == getTeam() || distanceWith(u) > TURRET_RANGE) { continue; } // Note: this method means that if there are two champions within turret range, // The player to have been added to the game first will always be targeted before the others if (!targetUnit) { auto priority = classifyTarget(u); if (priority < nextTargetPriority) { nextTarget = u; nextTargetPriority = priority; } } else { Champion* targetIsChampion = dynamic_cast<Champion*>(targetUnit); // Is the current target a champion? If it is, don't do anything if (!targetIsChampion) { // Find the next champion in range targeting an enemy champion who is also in range Champion* enemyChamp = dynamic_cast<Champion*>(u); if (enemyChamp&& enemyChamp->getTargetUnit() != 0) { Champion* enemyChampTarget = dynamic_cast<Champion*>(enemyChamp->getTargetUnit()); if (enemyChampTarget && // Enemy Champion is targeting an ally enemyChamp->distanceWith(enemyChampTarget) <= enemyChamp->getStats().getRange() && // Enemy within range of ally distanceWith(enemyChampTarget) <= TURRET_RANGE) { // Enemy within range of this turret nextTarget = enemyChamp; // No priority required break; } } } } } if (nextTarget) { targetUnit = nextTarget; map->getGame()->notifySetTarget(this, nextTarget); } } // Lose focus of the unit target if the target is out of range if(targetUnit && distanceWith(targetUnit) > TURRET_RANGE) { setTargetUnit(0); map->getGame()->notifySetTarget(this, 0); } Unit::update(diff); }
void Game::notifySpawn(Unit* u) { Minion* m = dynamic_cast<Minion*>(u); if(m) { notifyMinionSpawned(m, 1-m->getSide()); } Champion* c = dynamic_cast<Champion*>(u); if(c) { notifyChampionSpawned(c, 1-c->getSide()); } notifySetHealth(u); }
void Champion::die(Unit* killer) { respawnTimer = 5000000 + getStats().getLevel()*2500000; map->getGame()->notifyChampionDie(this, killer); Champion* cKiller = dynamic_cast<Champion*>(killer); if (!cKiller) { return; } float gold = map->getGoldFor(this); printf("Before: getGoldFromChamp: %f\n Killdc: %i\n Killnc33q4t3246t4 %i\n", gold, cKiller->killDeathCounter,this->killDeathCounter); if(cKiller->killDeathCounter < 0){ cKiller->killDeathCounter = 0; } if(cKiller->killDeathCounter >= 0){ cKiller->killDeathCounter += 1; } if(this->killDeathCounter > 0){ this->killDeathCounter = 0; } if(this->killDeathCounter <= 0){ this->killDeathCounter -= 1; } if(!gold) { return; } if(map->getFirstBlood()){ gold += 100; map->setFirstBlood(false); } cKiller->getStats().setGold(cKiller->getStats().getGold() + gold); map->getGame()->notifyAddGold(cKiller, this, gold); printf("After: getGoldFromChamp: %f\n Killdc: %i\n Killnc33q4t3246t4 %i\n", gold, cKiller->killDeathCounter,this->killDeathCounter); map->stopTargeting(this); }
bool Game::initialize(ENetAddress *address, const char *baseKey){ if (enet_initialize () != 0) return false; atexit(enet_deinitialize); _server = enet_host_create(address, 32, 0, 0); if(_server == NULL) return false; std::string key = base64_decode(baseKey); if(key.length() <= 0) return false; _blowfish = new BlowFish((uint8*)key.c_str(), 16); initHandlers(); map = new SummonersRift(this); //TODO: better lua implementation LuaScript script(false); script.loadScript("../../lua/config.lua"); // sol::state lua; // lua.open_libraries(sol::lib::base, sol::lib::table); // lua.open_file("../../lua/config.lua"); sol::table playerList = script.getTable("players"); for (int i=1;i<12;i++) { try { std::string playerIndex = "player"+toString(i); sol::table playerData = playerList.get<sol::table>(playerIndex); std::string rank = playerData.get<std::string>("rank"); std::string name = playerData.get<std::string>("name"); std::string champion = playerData.get<std::string>("champion"); std::string team = playerData.get<std::string>("team"); int skin = playerData.get<int>("skin"); int ribbon = playerData.get<int>("ribbon"); int icon = playerData.get<int>("icon"); std::string summoner1 = playerData.get<std::string>("summoner1"); std::string summoner2 = playerData.get<std::string>("summoner2"); ClientInfo* player = new ClientInfo(rank, ((team == "BLUE") ? TEAM_BLUE : TEAM_PURPLE), ribbon, icon); player->setName(name); player->setSkinNo(skin); static int id = 1; player->userId = id; // same as StartClient.bat id++; player->setSummoners(strToId(summoner1), strToId(summoner2)); Champion* c = ChampionFactory::getChampionFromType(champion, map, GetNewNetID(), player->userId); float respawnX, respawnY; std::tie(respawnX, respawnY) = c->getRespawnPosition(); c->setPosition(respawnX, respawnY); c->setSide((team == "BLUE") ? 0 : 1); c->levelUp(); map->addObject(c); player->setChampion(c); players.push_back(player); } catch(sol::error e) { //printf("Error loading champion: \n%s", e.what()); break; } } // Uncomment the following to get 2-players /*ClientInfo* player2 = new ClientInfo("GOLD", TEAM_PURPLE); player2->setName("tseT"); Champion* c2 = ChampionFactory::getChampionFromType("Ezreal", map, GetNewNetID()); c2->setPosition(100.f, 273.55f); c2->setSide(1); map->addObject(c2); player2->setChampion(c2); player2->setSkinNo(4); player2->userId = 2; // same as StartClient.bat player2->setSummoners(SPL_Ignite, SPL_Flash); players.push_back(player2);*/ return _isAlive = true; }
int main() { // Polymorphism refers to the ability of a BASE CLASS pointer to point to // any object of a class that is DERIVED from the base class. Minion melee(250, 250, 50, 0, 23, 100); Champion garen(600, 600, 60, 30, 1, "Garen", "The Might of Demacia"); // Now that Actor has an Attack class, we can make our actors do battle! garen.Attack(&melee); melee.Attack(&garen); cout << "After one attack:" << endl; cout << "Melee: " << melee.GetCurrentHitPoints() << " / " << melee.GetMaxHitPoints() << " HP" << endl; cout << "Garen: " << garen.GetCurrentHitPoints() << " / " << garen.GetMaxHitPoints() << " HP" << endl; Actor *a; // Actor is the base class // Polymorphism says I can point a at either melee or garen a = &melee; a = &garen; // This is allowed because every Minion "is-a" Actor, so an Actor* can point // to a Minion, or a Champion, or any other class that derives from Actor. // If we do this, then we are limited to using methods defined by the Actor // class. cout << a->GetCurrentHitPoints() << endl; // Regardless of what a actually points to, we can ONLY use Actor methods. // Even though YOU AND I KNOW that a points to a Champion, this line will // not compile. Why do you suppose that is? // cout << a->GetName(); // Does the thing that a points to have a GetName // method in reality? If yes, why can't we use it? // Suppose I'm willing to bet my life that a points to a Champion. I can use // "down casting" to convert it to a Champion pointer. Champion *c = (Champion*)a; // there is a better way to do this; more later. // I can now call my Champion methods on c, which points to the same object // that a does. cout << c->GetName() << endl; // Down-casting can be dangerous if you get the types wrong. a = &melee; c = (Champion*)a; cout << c->GetName() << endl; // ?????? // Vectors of pointers. // Like all types, I can make a vector of Actor pointers. vector<Actor*> actors; actors.push_back(&melee); // I can push a Minion into an Actor... why? actors.push_back(&garen); // I can push a Champion into an Actor... why? // Iterating through a vector of pointers. for (vector<Actor*>::iterator itr = actors.begin(); itr != actors.end(); itr++) { // *itr always gives me one element from the vector.. which would be of // type Actor*. cout << (*itr)->GetMaxHitPoints() << endl; } actors.clear(); // clear the vector for later. // One final example. Can I put heap-based objects into this vector? for (int i = 0; i < 5; i++) actors.push_back(RandomActor()); // You bet! // Just remember... by putting heap objects in a vector, you must be careful // to not remove them without deleting them first. // DO NOT DO THIS: // actors.clear(); // What would have happened??? // Before clearing, you must walk the vector and delete each element. for (Actor *i : actors) { // remember this style loop? delete i; // this deletes the object, but the vector still have a pointer // to the now-deleted object. } actors.clear(); // now the vector has lost its pointers to the deleted stuff. return 0; }
bool Game::handleChatBoxMessage(HANDLE_ARGS) { ChatMessage *message = reinterpret_cast<ChatMessage *>(packet->data); //Lets do commands if(message->msg == '.') { const char *cmd[] = { ".set", ".gold", ".speed", ".health", ".xp", ".ap", ".ad", ".mana", ".model", ".help", ".spawn", ".size", ".junglespawn", ".skillpoints", ".level", ".tp", ".coords", ".ch"}; std::ostringstream debugMsg; // help command if (strncmp(message->getMessage(), cmd[9], strlen(cmd[9])) == 0) { return true; } // set if(strncmp(message->getMessage(), cmd[0], strlen(cmd[0])) == 0) { uint32 blockNo, fieldNo; float value; sscanf(&message->getMessage()[strlen(cmd[0])+1], "%u %u %f", &blockNo, &fieldNo, &value); blockNo = 1 << (blockNo - 1); uint32 mask = 1 << (fieldNo - 1); peerInfo(peer)->getChampion()->getStats().setStat(blockNo, mask, value); return true; } // gold if(strncmp(message->getMessage(), cmd[1], strlen(cmd[1])) == 0) { float gold = (float)atoi(&message->getMessage()[strlen(cmd[1]) + 1]); peerInfo(peer)->getChampion()->getStats().setGold(gold); return true; } // speed if(strncmp(message->getMessage(), cmd[2], strlen(cmd[2])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[2])+1]); printf("Setting speed to %f\n", data); peerInfo(peer)->getChampion()->getStats().setMovementSpeed(data); return true; } //health if(strncmp(message->getMessage(), cmd[3], strlen(cmd[3])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[3])+1]); peerInfo(peer)->getChampion()->getStats().setCurrentHealth(data); peerInfo(peer)->getChampion()->getStats().setMaxHealth(data); notifySetHealth(peerInfo(peer)->getChampion()); return true; } // xp if(strncmp(message->getMessage(), cmd[4], strlen(cmd[4])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[5])+1]); printf("Setting experience to %f\n", data); peerInfo(peer)->getChampion()->getStats().setExp(data); return true; } // ap if(strncmp(message->getMessage(), cmd[5], strlen(cmd[5])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[5])+1]); printf("Setting AP to %f\n", data); peerInfo(peer)->getChampion()->getStats().setBonusApFlat(data); return true; } // ad if(strncmp(message->getMessage(), cmd[6], strlen(cmd[6])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[5])+1]); printf("Setting AD to %f\n", data); peerInfo(peer)->getChampion()->getStats().setBonusAdFlat(data); return true; } // Mana if(strncmp(message->getMessage(), cmd[7], strlen(cmd[7])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[7])+1]); printf("Setting Mana to %f\n", data); peerInfo(peer)->getChampion()->getStats().setCurrentMana(data); peerInfo(peer)->getChampion()->getStats().setMaxMana(data); return true; } // Model if(strncmp(message->getMessage(), cmd[8], strlen(cmd[8])) == 0) { std::string sModel = (char *)&message->getMessage()[strlen(cmd[8]) + 1]; peerInfo(peer)->getChampion()->setModel(sModel); return true; } // Size if(strncmp(message->getMessage(), cmd[11], strlen(cmd[11])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[11])+1]); printf("Setting size to %f\n", data); peerInfo(peer)->getChampion()->getStats().setSize(data); return true; } // Mob Spawning-Creating, updated if(strncmp(message->getMessage(), cmd[12], strlen(cmd[12])) == 0) { const char *cmd[] = { "c baron" , "c wolves", "c red", "c blue", "c dragon", "c wraiths", "c golems"}; return true; } // Skillpoints if(strncmp(message->getMessage(), cmd[13], strlen(cmd[13])) == 0) { peerInfo(peer)->getChampion()->setSkillPoints(17); SkillUpResponse skillUpResponse(peerInfo(peer)->getChampion()->getNetId(), 0, 0, 17); sendPacket(peer, skillUpResponse, CHL_GAMEPLAY); return true; } // Level if(strncmp(message->getMessage(), cmd[14], strlen(cmd[14])) == 0) { float data = (float)atoi(&message->getMessage()[strlen(cmd[14])+1]); peerInfo(peer)->getChampion()->getStats().setLevel(data); return true; } // tp if(strncmp(message->getMessage(), cmd[15], strlen(cmd[15])) == 0) { float x, y; sscanf(&message->getMessage()[strlen(cmd[15])+1], "%f %f", &x, &y); notifyTeleport(peerInfo(peer)->getChampion(), x, y); return true; } // coords if(strncmp(message->getMessage(), cmd[16], strlen(cmd[16])) == 0) { printf("At %f;%f\n", peerInfo(peer)->getChampion()->getX(), peerInfo(peer)->getChampion()->getY()); debugMsg << "At Coords - X:" << peerInfo(peer)->getChampion()->getX() << " Y:" << peerInfo(peer)->getChampion()->getY() << " Z:" << peerInfo(peer)->getChampion()->getZ(); notifyDebugMessage(debugMsg.str()); return true; } // Ch(ampion) if(strncmp(message->getMessage(), cmd[17], strlen(cmd[17])) == 0) { std::string champ = (char *)&message->getMessage()[strlen(cmd[17]) + 1]; Champion* c = new Champion(champ, map, peerInfo(peer)->getChampion()->getNetId(), peerInfo(peer)->userId); c->setPosition(peerInfo(peer)->getChampion()->getX(), peerInfo(peer)->getChampion()->getY()); c->setModel(champ); // trigger the "modelUpdate" proc map->removeObject(peerInfo(peer)->getChampion()); delete peerInfo(peer)->getChampion(); map->addObject(c); peerInfo(peer)->setChampion(c); return true; } } switch(message->type) { case CMT_ALL: return broadcastPacket(packet->data, packet->dataLength, CHL_COMMUNICATION); case CMT_TEAM: return broadcastPacketTeam(peerInfo(peer)->getTeam(), packet->data, packet->dataLength, CHL_COMMUNICATION); default: //Logging->errorLine("Unknown ChatMessageType\n"); return sendPacket(peer, packet->data, packet->dataLength, CHL_COMMUNICATION); } return false; }
void Champion::combine(Champion &other){ for(unsigned int i = 0; i < other.size(); i++){ this->testContestant(other.pos[i], other.value[i]); } }