// Demand tribute, and get the planet's response. string Planet::DemandTribute(PlayerInfo &player) const { if(player.GetCondition("tribute: " + name)) return "We are already paying you as much as we can afford."; if(!tribute || defenseFleets.empty()) return "Please don't joke about that sort of thing."; if(player.GetCondition("combat rating") < defenseThreshold) return "You're not worthy of our time."; // The player is scary enough for this planet to take notice. Check whether // this is the first demand for tribute, or not. if(!isDefending) { isDefending = true; set<const Government *> toProvoke; for(const auto &fleet : defenseFleets) toProvoke.insert(fleet->GetGovernment()); for(const auto &gov : toProvoke) gov->Offend(ShipEvent::PROVOKE); // Terrorizing a planet is not taken lightly by it or its allies. GetGovernment()->Offend(ShipEvent::ATROCITY); return "Our defense fleet will make short work of you."; } // The player has already demanded tribute. Have they defeated the entire defense fleet? bool isDefeated = (defenseDeployed == defenseFleets.size()); for(const shared_ptr<Ship> &ship : defenders) if(!ship->IsDisabled() && !ship->IsYours()) { isDefeated = false; break; } if(!isDefeated) return "We're not ready to surrender yet."; player.Conditions()["tribute: " + name] = tribute; GameData::GetPolitics().DominatePlanet(this); return "We surrender. We will pay you " + Format::Credits(tribute) + " credits per day to leave us alone."; }
MissionPanel::MissionPanel(PlayerInfo &player) : MapPanel(player), available(player.AvailableJobs()), accepted(player.Missions()), availableIt(player.AvailableJobs().begin()), acceptedIt(player.AvailableJobs().empty() ? accepted.begin() : accepted.end()) { while(acceptedIt != accepted.end() && !acceptedIt->IsVisible()) ++acceptedIt; wrap.SetWrapWidth(380); wrap.SetFont(FontSet::Get(14)); wrap.SetAlignment(WrappedText::JUSTIFIED); // Select the first available or accepted mission in the currently selected // system, or along the travel plan. if(!FindMissionForSystem(selectedSystem) && player.HasTravelPlan()) { const auto &tp = player.TravelPlan(); for(auto it = tp.crbegin(); it != tp.crend(); ++it) if(FindMissionForSystem(*it)) break; } // Auto select the destination system for the current mission. if(availableIt != available.end()) selectedSystem = availableIt->Destination()->GetSystem(); else if(acceptedIt != accepted.end()) selectedSystem = acceptedIt->Destination()->GetSystem(); // Center the system slightly above the center of the screen because the // lower panel is taking up more space than the upper one. center = Point(0., -80.) - selectedSystem->Position(); }
void GameEvent::Apply(PlayerInfo &player) { for(const auto &it : GameData::Governments()) { int rep = it.second.Reputation(); player.Conditions()["reputation: " + it.first] = rep; } conditionsToApply.Apply(player.Conditions()); player.AddChanges(changes); for(const auto &it : GameData::Governments()) { int rep = it.second.Reputation(); int newRep = player.Conditions()["reputation: " + it.first]; if(rep != newRep) it.second.AddReputation(newRep - rep); } for(const System *system : systemsToUnvisit) player.Unvisit(system); }
BoardingPanel::BoardingPanel(PlayerInfo &player, const shared_ptr<Ship> &victim) : player(player), you(player.FlagshipPtr()), victim(victim), attackOdds(&*you, &*victim), defenseOdds(&*victim, &*you), initialCrew(you->Crew()) { SetInterruptible(false); const System &system = *player.GetSystem(); for(const auto &it : victim->Cargo().Commodities()) plunder.emplace_back(it.first, it.second, system.Trade(it.first)); // You cannot plunder hand to hand weapons, because they are kept in the // crew's quarters, not mounted on the exterior of the ship. for(const auto &it : victim->Outfits()) if(!it.first->Get("unplunderable")) plunder.emplace_back(it.first, it.second); if(!victim->IsCapturable()) messages.emplace_back("This is not a ship that you can capture."); sort(plunder.begin(), plunder.end()); }
bool Mission::HasSpace(const PlayerInfo &player) const { int extraCrew = 0; if(player.Flagship()) extraCrew = player.Flagship()->Crew() - player.Flagship()->RequiredCrew(); return (cargoSize <= player.Cargo().Free() + player.Cargo().CommoditiesSize() && passengers <= player.Cargo().Bunks() + extraCrew); }
static int MannedTurrets(IshipIGC* pshipParent) { // loop through all of the ships on that side and count the ones // that are turrets of this. int cMannedTurrets = 0; const ShipListIGC* shipList = pshipParent->GetSide()->GetShips(); for (const ShipLinkIGC* lShip = shipList->first(); lShip; lShip = lShip->next()) { IshipIGC* pship = lShip->data(); PlayerInfo* pplayer = (PlayerInfo*)pship->GetPrivateData(); if (pplayer->LastSeenState() == c_ssTurret) { PlayerInfo* pplayerParent = trekClient.FindPlayer(pplayer->LastSeenParent()); if (pplayerParent && pplayerParent->GetShip() == pshipParent) cMannedTurrets++; } } return cMannedTurrets; }
static bool CanBoard(IshipIGC* pship) { PlayerInfo* pPlayer = (PlayerInfo*)pship->GetPrivateData(); if (pship != trekClient.GetShip() && pship->GetSide() == trekClient.GetSide() && pPlayer->LastSeenState() == c_ssDocked && pship->GetPilotType() >= c_ptPlayer) { HullID hid = pPlayer->LastSeenShipType(); assert (hid != NA); IhullTypeIGC* pht = trekClient.m_pCoreIGC->GetHullType(hid); assert (pht); if ((trekClient.GetShip()->GetPilotType() == c_ptCheatPlayer) || (pht->GetMaxFixedWeapons() != pht->GetMaxWeapons())) { return true; } } return false; }
// Check if this action can be completed right now. It cannot be completed // if it takes away money or outfits that the player does not have. bool MissionAction::CanBeDone(const PlayerInfo &player) const { if(player.Accounts().Credits() < -payment) return false; const Ship *flagship = player.Flagship(); for(const auto &it : gifts) { if(it.second >= 0) continue; // The outfit can be taken from the player's cargo or from the flagship. int available = player.Cargo().Get(it.first); for(const auto &ship : player.Ships()) available += ship->Cargo().Get(it.first); if(flagship) available += flagship->OutfitCount(it.first); if(available < -it.second) return false; } return true; }
bool AllianceApplylistCommand::handleRecieve(cocos2d::CCDictionary *dict) { if (dict->valueForKey("cmd")->compare(AL_APPLY_LIST) != 0) return false; CCDictionary *params=_dict(dict->objectForKey("params")); if (!params) { return false; } const CCString *pStr = params->valueForKey("errorCode"); if (pStr->compare("")!=0) { CCCommonUtils::flyText(_lang(pStr->getCString())); callFail(NetResult::create()); }else{ map<std::string, PlayerInfo*>::iterator it; AllianceManager::getInstance()->applyUserList.clear(); CCArray* arr = (CCArray*)params->objectForKey("list"); int num = arr->count(); for (int i=0; i<num; i++) { CCDictionary* dicPlayer = (CCDictionary*)arr->objectAtIndex(i); PlayerInfo* player = new PlayerInfo(); player->updateInfo(dicPlayer); AllianceManager::getInstance()->applyUserList[player->uid] = player; if(player->uid==GlobalData::shared()->playerInfo.uid){ if(dicPlayer->objectForKey("relinquishEndTime")){ GlobalData::shared()->playerInfo.relinquishEndTime = dicPlayer->valueForKey("relinquishEndTime")->doubleValue(); } if(dicPlayer->objectForKey("officer")){ GlobalData::shared()->playerInfo.officer = dicPlayer->valueForKey("officer")->getCString(); } } } callSuccess(NetResult::create(Error_OK, params)); } return true; }
Engine::Engine(PlayerInfo &player) : player(player) { // Start the thread for doing calculations. calcThread = thread(&Engine::ThreadEntryPoint, this); if(!player.IsLoaded() || !player.GetSystem()) return; // Preload any landscapes for this system. for(const StellarObject &object : player.GetSystem()->Objects()) if(object.GetPlanet()) GameData::Preload(object.GetPlanet()->Landscape()); // Figure out what planet the player is landed on, if any. const StellarObject *object = player.GetStellarObject(); if(object) center = object->Position(); // Now we know the player's current position. Draw the planets. draw[calcTickTock].SetCenter(center); radar[calcTickTock].SetCenter(center); for(const StellarObject &object : player.GetSystem()->Objects()) if(object.HasSprite()) { draw[calcTickTock].Add(object); double r = max(2., object.Radius() * .03 + .5); radar[calcTickTock].Add(RadarType(object), object.Position(), r, r - 1.); } // Add all neighboring systems to the radar. const Ship *flagship = player.Flagship(); const System *targetSystem = flagship ? flagship->GetTargetSystem() : nullptr; const vector<const System *> &links = (flagship && flagship->Attributes().Get("jump drive")) ? player.GetSystem()->Neighbors() : player.GetSystem()->Links(); for(const System *system : links) radar[calcTickTock].AddPointer( (system == targetSystem) ? Radar::SPECIAL : Radar::INACTIVE, system->Position() - player.GetSystem()->Position()); }
// Check if it's possible to offer or complete this mission right now. bool Mission::CanOffer(const PlayerInfo &player) const { if(location == BOARDING || location == ASSISTING) { if(!player.BoardingShip()) return false; if(!sourceFilter.Matches(*player.BoardingShip())) return false; } else { if(source && source != player.GetPlanet()) return false; if(!sourceFilter.Matches(player.GetPlanet())) return false; } if(!toOffer.Test(player.Conditions())) return false; if(!toFail.IsEmpty() && toFail.Test(player.Conditions())) return false; if(repeat) { auto cit = player.Conditions().find(name + ": offered"); if(cit != player.Conditions().end() && cit->second >= repeat) return false; } auto it = actions.find(OFFER); if(it != actions.end() && !it->second.CanBeDone(player)) return false; it = actions.find(ACCEPT); if(it != actions.end() && !it->second.CanBeDone(player)) return false; it = actions.find(DECLINE); if(it != actions.end() && !it->second.CanBeDone(player)) return false; return true; }
bool Mission::CanComplete(const PlayerInfo &player) const { if(player.GetPlanet() != destination || !waypoints.empty()) return false; if(!toComplete.Test(player.Conditions())) return false; auto it = actions.find(COMPLETE); if(it != actions.end() && !it->second.CanBeDone(player)) return false; for(const NPC &npc : npcs) if(!npc.HasSucceeded(player.GetSystem())) return false; // If any of the cargo for this mission is being carried by a ship that is // not in this system, the mission cannot be completed right now. for(const auto &ship : player.Ships()) if(ship->GetSystem() != player.GetSystem() && ship->Cargo().Get(this)) return false; return true; }
void* handle(void* par) { signal(SIGPIPE, SIG_IGN); HandleThreadParameter* parameter = (HandleThreadParameter*) par; int clientSocket = parameter->clientID; Server* server = parameter->server; std::vector<std::string> withBase = server->listFilesInDirectoryWithBase( "sendFiles"); std::vector<std::string> withoutBase = server->listFilesInDirectory( "sendFiles"); // Manda las imagenes y sonidos necesarios que se utilizaran. server->sendFiles(withBase, withoutBase, clientSocket); PlayerInfo* info = server->recieveNewPlayer(clientSocket); if (!info){ Logs::logErrorMessage("No se ha recibido la informacion del jugador"); return NULL; } string playerName = info->getPlayer()->getName(); int result = server->isNameAbilivable(playerName); server->sendAproval(clientSocket, result); if (result != OK) { playerName = server->getAbilivableName(playerName); server->sendNewName(clientSocket, playerName); info->setName(playerName); info->getPlayer()->setName(playerName); } cont++; info->getPlayer()->setTeam(cont%2 +1); bool playing = true; cout << playerName << " has conected and joined team: " << info->getPlayer()->getTeam() <<endl; // Antes de agregarlo al juego creo el thread para chequear el estado en el que se encuentra. TimerThreadParameter param = {server,clientSocket,playerName, &playing}; pthread_t timerThread; server->addPlayerToGame(clientSocket, info); pthread_create(&timerThread,NULL,timerChecker,(void*)¶m); server->runMainLoop(clientSocket,playerName); pthread_cancel(timerThread); server->disconectPlayer(clientSocket,playerName); close(clientSocket); return NULL; }
ShipInfoPanel::ShipInfoPanel(PlayerInfo &player, int index) : player(player), shipIt(player.Ships().begin()), canEdit(player.GetPlanet()) { SetInterruptible(false); // If a valid ship index was given, show that ship. if(static_cast<unsigned>(index) < player.Ships().size()) shipIt += index; else if(player.Flagship()) { // Find the player's flagship. It may not be first in the list, if the // first item in the list cannot be a flagship. while(shipIt != player.Ships().end() && shipIt->get() != player.Flagship()) ++shipIt; } UpdateInfo(); }
// Check to see if the player has done anything they should be fined for. string Politics::Fine(PlayerInfo &player, const Government *gov, int scan, const Ship *target, double security) { // Do nothing if you have already been fined today, or if you evade // detection. auto it = fined.find(gov); if(it != fined.end() || Random::Real() > security || !gov->GetFineFraction()) return ""; string reason; int64_t maxFine = 0; for(const shared_ptr<Ship> &ship : player.Ships()) { // Check if the ship evades being scanned due to interference plating. if(Random::Real() > 1. / (1. + ship->Attributes().Get("scan interference"))) continue; if(target && target != &*ship) continue; if(ship->GetSystem() != player.GetSystem()) continue; if(!scan || (scan & ShipEvent::SCAN_CARGO)) { int64_t fine = ship->Cargo().IllegalCargoFine(); if((fine > maxFine && maxFine >= 0) || fine < 0) { maxFine = fine; reason = "carrying illegal cargo."; } } if(!scan || (scan & ShipEvent::SCAN_OUTFITS)) { for(const auto &it : ship->Outfits()) if(it.second) { int64_t fine = it.first->Get("illegal"); if((fine > maxFine && maxFine >= 0) || fine < 0) { maxFine = fine; reason = "having illegal outfits installed on your ship."; } } } } if(maxFine < 0) { gov->Offend(ShipEvent::ATROCITY); if(!scan) reason = "atrocity"; else reason = "After scanning your ship, the " + gov->GetName() + " captain hails you with a grim expression on his face. He says, \"You are guilty of " + reason + " The penalty for your actions is death. Goodbye.\""; } else if(maxFine > 0) { // Scale the fine based on how lenient this government is. maxFine = maxFine * gov->GetFineFraction() + .5; reason = "The " + gov->GetName() + " fines you " + Format::Number(maxFine) + " credits for " + reason; player.Accounts().AddFine(maxFine); fined.insert(gov); } return reason; }
void AI::UpdateKeys(PlayerInfo &player, bool isActive) { shift = (SDL_GetModState() & KMOD_SHIFT); Command oldHeld = keyHeld; keyHeld.ReadKeyboard(); keyDown = keyHeld.AndNot(oldHeld); if(keyHeld.Has(AutopilotCancelKeys())) keyStuck.Clear(); if(keyStuck.Has(Command::JUMP) && !player.HasTravelPlan()) keyStuck.Clear(Command::JUMP); const Ship *flagship = player.Flagship(); if(!isActive || !flagship || flagship->IsDestroyed()) return; // Only toggle the "cloak" command if one of your ships has a cloaking device. if(keyDown.Has(Command::CLOAK)) for(const auto &it : player.Ships()) if(it->Attributes().Get("cloak")) { isCloaking = !isCloaking; Messages::Add(isCloaking ? "Engaging cloaking device." : "Disengaging cloaking device."); break; } // Toggle your secondary weapon. if(keyDown.Has(Command::SELECT)) player.SelectNext(); // The commands below here only apply if you have escorts or fighters. if(player.Ships().size() < 2) return; // Only toggle the "deploy" command if one of your ships has fighter bays. if(keyDown.Has(Command::DEPLOY)) for(const auto &it : player.Ships()) if(it->HasBays()) { isLaunching = !isLaunching; Messages::Add(isLaunching ? "Deploying fighters" : "Recalling fighters."); break; } shared_ptr<Ship> target = flagship->GetTargetShip(); if(keyDown.Has(Command::FIGHT) && target) { sharedTarget = target; holdPosition = false; moveToMe = false; Messages::Add("All your ships are focusing their fire on \"" + target->Name() + "\"."); } if(keyDown.Has(Command::HOLD)) { sharedTarget.reset(); holdPosition = !holdPosition; moveToMe = false; Messages::Add(holdPosition ? "Your fleet is holding position." : "Your fleet is no longer holding position."); } if(keyDown.Has(Command::GATHER)) { sharedTarget.reset(); holdPosition = false; moveToMe = !moveToMe; Messages::Add(moveToMe ? "Your fleet is gathering around your flagship." : "Your fleet is no longer gathering around your flagship."); } if(sharedTarget.lock() && sharedTarget.lock()->IsDisabled()) sharedTarget.reset(); }
// "Instantiate" a mission by replacing randomly selected values and places // with a single choice, and then replacing any wildcard text as well. Mission Mission::Instantiate(const PlayerInfo &player) const { Mission result; // If anything goes wrong below, this mission should not be offered. result.hasFailed = true; result.isVisible = isVisible; result.hasPriority = hasPriority; result.isMinor = isMinor; result.autosave = autosave; result.location = location; result.repeat = repeat; result.name = name; result.waypoints = waypoints; // If one of the waypoints is the current system, it is already visited. auto it = result.waypoints.find(player.GetSystem()); if(it != result.waypoints.end()) result.waypoints.erase(it); // First, pick values for all the variables. // If a specific destination is not specified in the mission, pick a random // one out of all the destinations that satisfy the mission requirements. result.destination = destination; if(!result.destination && !destinationFilter.IsEmpty()) { // Find a destination that satisfies the filter. vector<const Planet *> options; for(const auto &it : GameData::Planets()) { // Skip entries with incomplete data. if(it.second.Name().empty() || (clearance.empty() && !it.second.CanLand())) continue; if(it.second.IsWormhole() || !it.second.HasSpaceport()) continue; if(destinationFilter.Matches(&it.second, player.GetSystem())) options.push_back(&it.second); } if(!options.empty()) result.destination = options[Random::Int(options.size())]; else return result; } // If no destination is specified, it is the same as the source planet. Also // use the source planet if the given destination is not a valid planet name. if(!result.destination || !result.destination->GetSystem()) { if(player.GetPlanet()) result.destination = player.GetPlanet(); else return result; } // If cargo is being carried, see if we are supposed to replace a generic // cargo name with something more specific. if(!cargo.empty()) { const Trade::Commodity *commodity = nullptr; if(cargo == "random") commodity = PickCommodity(*player.GetSystem(), *result.destination->GetSystem()); else { for(const Trade::Commodity &option : GameData::Commodities()) if(option.name == cargo) { commodity = &option; break; } } if(commodity) result.cargo = commodity->items[Random::Int(commodity->items.size())]; else result.cargo = cargo; } // Pick a random cargo amount, if requested. if(cargoSize || cargoLimit) { if(cargoProb) result.cargoSize = Random::Polya(cargoLimit, cargoProb) + cargoSize; else if(cargoLimit > cargoSize) result.cargoSize = cargoSize + Random::Int(cargoLimit - cargoSize + 1); else result.cargoSize = cargoSize; } // Pick a random passenger count, if requested. if(passengers | passengerLimit) { if(passengerProb) result.passengers = Random::Polya(passengerLimit, passengerProb) + passengers; else if(passengerLimit > passengers) result.passengers = passengers + Random::Int(passengerLimit - passengers + 1); else result.passengers = passengers; } result.illegalCargoFine = illegalCargoFine; // How far is it to the destination? DistanceMap distance(player.GetSystem()); int jumps = distance.Distance(result.destination->GetSystem()); int defaultPayment = (jumps + 1) * (150 * result.cargoSize + 1500 * result.passengers); int defaultDeadline = doDefaultDeadline ? (2 * jumps) : 0; // Set the deadline, if requested. if(daysToDeadline || defaultDeadline) { result.hasDeadline = true; result.deadline = player.GetDate() + (defaultDeadline + daysToDeadline); } // Copy the completion conditions. No need to copy the offer conditions, // because they have already been checked. result.toComplete = toComplete; result.toFail = toFail; // Generate the substitutions map. map<string, string> subs; subs["<commodity>"] = result.cargo; subs["<tons>"] = to_string(result.cargoSize) + (result.cargoSize == 1 ? " ton" : " tons"); subs["<cargo>"] = subs["<tons>"] + " of " + subs["<commodity>"]; subs["<bunks>"] = to_string(result.passengers); subs["<passengers>"] = (result.passengers == 1) ? "passenger" : "passengers"; subs["<fare>"] = (result.passengers == 1) ? "a passenger" : (subs["<bunks>"] + " passengers"); if(player.GetPlanet()) subs["<origin>"] = player.GetPlanet()->Name(); else if(player.BoardingShip()) subs["<origin>"] = player.BoardingShip()->Name(); subs["<planet>"] = result.destination ? result.destination->Name() : ""; subs["<system>"] = result.destination ? result.destination->GetSystem()->Name() : ""; subs["<destination>"] = subs["<planet>"] + " in the " + subs["<system>"] + " system"; subs["<date>"] = result.deadline.ToString(); subs["<day>"] = result.deadline.LongString(); // Instantiate the NPCs. This also fills in the "<npc>" substitution. for(const NPC &npc : npcs) result.npcs.push_back(npc.Instantiate(subs, player.GetSystem())); // Instantiate the actions. The "complete" action is always first so that // the "<payment>" substitution can be filled in. for(const auto &it : actions) result.actions[it.first] = it.second.Instantiate(subs, defaultPayment); for(const auto &it : onEnter) result.onEnter[it.first] = it.second.Instantiate(subs, defaultPayment); // Perform substitution in the name and description. result.displayName = Format::Replace(displayName, subs); result.description = Format::Replace(description, subs); result.clearance = Format::Replace(clearance, subs); result.blocked = Format::Replace(blocked, subs); result.clearanceFilter = clearanceFilter; result.hasFullClearance = hasFullClearance; result.hasFailed = false; return result; }
MapDetailPanel::MapDetailPanel(PlayerInfo &player, const System *system) : MapPanel(player, system ? MapPanel::SHOW_REPUTATION : player.MapColoring(), system), governmentY(0), tradeY(0), selectedPlanet(nullptr) { }
void ServerPacketHandlerSystem::handleLobby() { while( m_server->hasNewPackets() ) { Packet packet = m_server->popNewPacket(); char packetType; packetType = packet.getPacketType(); if(packetType == (char)PacketType::ChangeStatePacket){ ChangeStatePacket statePacket; statePacket.unpack(packet); if(statePacket.m_gameState == GameStates::INITGAME){ ChangeStatePacket newState; newState.m_serverState = ServerStates::LOADING; m_stateSystem->setQueuedState(ServerStates::LOADING); m_server->broadcastPacket(newState.pack()); } } else if(packetType == (char)PacketType::PlayerInfo){ PlayerInfo playerInfo; playerInfo.unpack(packet); PlayerSystem* playerSystem = static_cast<PlayerSystem*> (m_world->getSystem(SystemType::PlayerSystem)); vector<Entity*> connectedPlayers = playerSystem->getActiveEntities(); //Add the entity here to be used by other systems Entity* newPlayer = m_world->createEntity(); PlayerComponent* newComp = new PlayerComponent(); if( playerInfo.playerName == "brightestmind" && playerInfo.playerID == 0){ newComp->setAbsoluteScore(9001); } else if(playerInfo.playerName=="judas"){ newComp->setAbsoluteScore(-9001); } newComp->m_playerName = playerInfo.playerName; newComp->m_playerID = playerInfo.playerID; //connectedPlayers.size(); newComp->m_networkID = packet.getSenderId(); newPlayer->addComponent(newComp); m_world->addEntity(newPlayer); NewlyConnectedPlayerPacket connectedPlayer; connectedPlayer.playerName = newComp->m_playerName; connectedPlayer.playerID = newComp->m_playerID; connectedPlayer.score = newComp->getScore(); connectedPlayer.networkID = newComp->m_networkID; // Broadcast the player to all clients. m_server->broadcastPacket(connectedPlayer.pack()); for (unsigned int i = 0; i < connectedPlayers.size(); i++){ NewlyConnectedPlayerPacket alreadyConnectedPlayers; PlayerComponent* playerComp; playerComp = static_cast<PlayerComponent*> (connectedPlayers[i]->getComponent(ComponentType::PlayerComponent)); alreadyConnectedPlayers.playerID = playerComp->m_playerID; alreadyConnectedPlayers.playerName = playerComp->m_playerName; alreadyConnectedPlayers.networkID = playerComp->m_networkID; // Send all the existing players to the new client. m_server->unicastPacket(alreadyConnectedPlayers.pack(), newComp->m_networkID); //m_server->broadcastPacket(alreadyConnectedPlayers.pack()); } // Force all players to be set unready. memset(&m_lobbyPlayerReadyStates, 0, sizeof(m_lobbyPlayerReadyStates)); } else if(packetType == (char)PacketType::ClientDisconnect){ DisconnectPacket dcPacket; dcPacket.unpack(packet); // Remove client! PlayerSystem* playerSystem = static_cast<PlayerSystem*> (m_world->getSystem(SystemType::PlayerSystem)); playerSystem->deletePlayerEntity(dcPacket.playerID); // Broadcast the dc packet back to all clients, including the one who sent it. m_server->broadcastPacket(packet); // Force all players to be set unready. memset(&m_lobbyPlayerReadyStates, 0, sizeof(m_lobbyPlayerReadyStates)); m_world->getOutputLogger()->write(("Server detected a disconnect packet for player: " + toString(dcPacket.playerID) + "\n").c_str()); } else if(packetType == (char)PacketType::PlayerReadyPacket){ // Broadcast the ready packet back to all clients, including the one who sent it. m_server->broadcastPacket(packet); PlayerReadyPacket readyPacket; readyPacket.unpack(packet); m_lobbyPlayerReadyStates[readyPacket.playerId] = readyPacket.ready; // Check so that all players are ready! m_readyLobbyPlayers = 0; for (int i = 0; i < MAXPLAYERS; i++) { if (m_lobbyPlayerReadyStates[i]) m_readyLobbyPlayers++; } m_world->getOutputLogger()->write( ("Players ready: " + toString(m_readyLobbyPlayers) + "\n").c_str() ); PlayerSystem* playerSystem = static_cast<PlayerSystem*> (m_world->getSystem(SystemType::PlayerSystem)); if (m_readyLobbyPlayers >= playerSystem->getActiveEntities().size()) { ChangeStatePacket newState; newState.m_serverState = ServerStates::LOADING; m_stateSystem->setQueuedState(ServerStates::LOADING); m_server->broadcastPacket(newState.pack()); } } else if( packetType == (char)PacketType::Ping ) { // ========================================= // PINGPACKET // ========================================= PingPacket pingPacket; pingPacket.unpack( packet ); Packet response((char)PacketType::Pong); response << pingPacket.timeStamp; m_server->unicastPacket( response, packet.getSenderId() ); } else if( packetType == (char)PacketType::Pong) { // ========================================= // PONGPACKET // ========================================= //auto clientInfo = static_cast<ClientInfo*>(m_world->getEntityManager()->get) float totalElapsedTime = m_world->getElapsedTime(); float timeWhenSent; PongPacket pongPacket; pongPacket.unpack( packet ); timeWhenSent = pongPacket.timeStamp; /************************************************************************/ /* Convert from seconds to milliseconds. */ /************************************************************************/ float ping = (totalElapsedTime - timeWhenSent)*1000.0f; //m_clients[packet.getSenderId()] = info; auto playerSys = static_cast<PlayerSystem*>( m_world->getSystem(SystemType::PlayerSystem)); PlayerComponent* playerComp = playerSys->findPlayerComponentFromNetworkID(packet.getSenderId()); if (playerComp) playerComp->m_ping = ping; } else { printPacketTypeNotHandled("Lobby", (int)packetType); } } }
// When the state of this mission changes, it may make changes to the player // information or show new UI panels. PlayerInfo::MissionCallback() will be // used as the callback for any UI panel that returns a value. bool Mission::Do(Trigger trigger, PlayerInfo &player, UI *ui) { if(trigger == STOPOVER) { // If this is not one of this mission's stopover planets, or if it is // not the very last one that must be visited, do nothing. auto it = stopovers.find(player.GetPlanet()); if(it == stopovers.end()) return false; for(const NPC &npc : npcs) if(npc.IsLeftBehind(player.GetSystem())) { ui->Push(new Dialog("This is a stop for one of your missions, but you have left a ship behind.")); return false; } stopovers.erase(it); if(!stopovers.empty()) return false; } if(trigger == ACCEPT) { ++player.Conditions()[name + ": offered"]; ++player.Conditions()[name + ": active"]; } else if(trigger == DECLINE) ++player.Conditions()[name + ": offered"]; else if(trigger == FAIL) --player.Conditions()[name + ": active"]; else if(trigger == COMPLETE) { --player.Conditions()[name + ": active"]; ++player.Conditions()[name + ": done"]; } // "Jobs" should never show dialogs when offered, nor should they call the // player's mission callback. if(trigger == OFFER && location == JOB) ui = nullptr; auto it = actions.find(trigger); if(it == actions.end()) { // If a mission has no "on offer" field, it is automatically accepted. if(trigger == OFFER && location != JOB) player.MissionCallback(Conversation::ACCEPT); return true; } if(!it->second.CanBeDone(player)) return false; // Set the "reputation" conditions so we can check if this action changed // any of them. for(const auto &it : GameData::Governments()) { int rep = it.second.Reputation(); player.Conditions()["reputation: " + it.first] = rep; } it->second.Do(player, ui, destination ? destination->GetSystem() : nullptr); // Check if any reputation conditions were updated. for(const auto &it : GameData::Governments()) { int rep = it.second.Reputation(); int newRep = player.Conditions()["reputation: " + it.first]; if(newRep != rep) it.second.AddReputation(newRep - rep); } return true; }
// "Instantiate" a mission by replacing randomly selected values and places // with a single choice, and then replacing any wildcard text as well. Mission Mission::Instantiate(const PlayerInfo &player) const { Mission result; // If anything goes wrong below, this mission should not be offered. result.hasFailed = true; result.isVisible = isVisible; result.hasPriority = hasPriority; result.isMinor = isMinor; result.autosave = autosave; result.location = location; result.repeat = repeat; result.name = name; result.waypoints = waypoints; // If one of the waypoints is the current system, it is already visited. auto it = result.waypoints.find(player.GetSystem()); if(it != result.waypoints.end()) result.waypoints.erase(it); // Copy the stopover planet list, and populate the list based on the filters // that were given. result.stopovers = stopovers; // Make sure they all exist in a valid system. for(auto it = result.stopovers.begin(); it != result.stopovers.end(); ) { if((*it)->GetSystem()) ++it; else it = result.stopovers.erase(it); } for(const LocationFilter &filter : stopoverFilters) { const Planet *planet = PickPlanet(filter, player); if(!planet) return result; result.stopovers.insert(planet); } // First, pick values for all the variables. // If a specific destination is not specified in the mission, pick a random // one out of all the destinations that satisfy the mission requirements. result.destination = destination; if(!result.destination && !destinationFilter.IsEmpty()) { result.destination = PickPlanet(destinationFilter, player); if(!result.destination) return result; } // If no destination is specified, it is the same as the source planet. Also // use the source planet if the given destination is not a valid planet name. if(!result.destination || !result.destination->GetSystem()) { if(player.GetPlanet()) result.destination = player.GetPlanet(); else return result; } // If cargo is being carried, see if we are supposed to replace a generic // cargo name with something more specific. if(!cargo.empty()) { const Trade::Commodity *commodity = nullptr; if(cargo == "random") commodity = PickCommodity(*player.GetSystem(), *result.destination->GetSystem()); else { for(const Trade::Commodity &option : GameData::Commodities()) if(option.name == cargo) { commodity = &option; break; } for(const Trade::Commodity &option : GameData::SpecialCommodities()) if(option.name == cargo) { commodity = &option; break; } } if(commodity) result.cargo = commodity->items[Random::Int(commodity->items.size())]; else result.cargo = cargo; } // Pick a random cargo amount, if requested. if(cargoSize || cargoLimit) { if(cargoProb) result.cargoSize = Random::Polya(cargoLimit, cargoProb) + cargoSize; else if(cargoLimit > cargoSize) result.cargoSize = cargoSize + Random::Int(cargoLimit - cargoSize + 1); else result.cargoSize = cargoSize; } // Pick a random passenger count, if requested. if(passengers | passengerLimit) { if(passengerProb) result.passengers = Random::Polya(passengerLimit, passengerProb) + passengers; else if(passengerLimit > passengers) result.passengers = passengers + Random::Int(passengerLimit - passengers + 1); else result.passengers = passengers; } result.illegalCargoFine = illegalCargoFine; // How far is it to the destination? DistanceMap distance(player.GetSystem()); int jumps = distance.Distance(result.destination->GetSystem()); int payload = result.cargoSize + 10 * result.passengers; // Set the deadline, if requested. if(deadlineBase || deadlineMultiplier) result.deadline = player.GetDate() + deadlineBase + deadlineMultiplier * jumps; // Copy the conditions. The offer conditions must be copied too, because they // may depend on a condition that other mission offers might change. result.toOffer = toOffer; result.toComplete = toComplete; result.toFail = toFail; // Generate the substitutions map. map<string, string> subs; subs["<commodity>"] = result.cargo; subs["<tons>"] = to_string(result.cargoSize) + (result.cargoSize == 1 ? " ton" : " tons"); subs["<cargo>"] = subs["<tons>"] + " of " + subs["<commodity>"]; subs["<bunks>"] = to_string(result.passengers); subs["<passengers>"] = (result.passengers == 1) ? "passenger" : "passengers"; subs["<fare>"] = (result.passengers == 1) ? "a passenger" : (subs["<bunks>"] + " passengers"); if(player.GetPlanet()) subs["<origin>"] = player.GetPlanet()->Name(); else if(player.BoardingShip()) subs["<origin>"] = player.BoardingShip()->Name(); subs["<planet>"] = result.destination ? result.destination->Name() : ""; subs["<system>"] = result.destination ? result.destination->GetSystem()->Name() : ""; subs["<destination>"] = subs["<planet>"] + " in the " + subs["<system>"] + " system"; subs["<date>"] = result.deadline.ToString(); subs["<day>"] = result.deadline.LongString(); if(!result.stopovers.empty()) { string planets; const Planet * const *last = &*--result.stopovers.end(); int count = 0; // Iterate by reference to the pointers so we can check when we're at // the very last one in the set. for(const Planet * const &planet : result.stopovers) { if(count++) planets += (&planet != last) ? ", " : (count > 2 ? ", and " : " and "); planets += planet->Name() + " in the " + planet->GetSystem()->Name() + " system"; } subs["<stopovers>"] = planets; } // Instantiate the NPCs. This also fills in the "<npc>" substitution. for(const NPC &npc : npcs) result.npcs.push_back(npc.Instantiate(subs, player.GetSystem())); // Instantiate the actions. The "complete" action is always first so that // the "<payment>" substitution can be filled in. for(const auto &it : actions) result.actions[it.first] = it.second.Instantiate(subs, jumps, payload); for(const auto &it : onEnter) result.onEnter[it.first] = it.second.Instantiate(subs, jumps, payload); // Perform substitution in the name and description. result.displayName = Format::Replace(displayName, subs); result.description = Format::Replace(description, subs); result.clearance = Format::Replace(clearance, subs); result.blocked = Format::Replace(blocked, subs); result.clearanceFilter = clearanceFilter; result.hasFullClearance = hasFullClearance; result.hasFailed = false; return result; }
void GSTitle::OnActive() { static bool first = true; if (first) { first = false; TheAvatarManager::Instance()->Load(); // Set default keyboard layout KbSetLayout(KB_LAYOUT_REGULAR); TheGSOptions::Instance()->LoadFromConfig(); } // Kill off any dummy player object TheGame::Instance()->ClearGameObjects(); #ifdef SHOW_FRAME_TIME Font* font = (Font*)TheResourceManager::Instance()->GetRes("font2d/arial-font.font"); TheGame::Instance()->SetFrameTimeFont(font); #endif GSGui::OnActive(); if (!m_titleImage.OpenAndLoad("title-bgimage.txt")) { std::cout << "Failed to load GUI title bg image!\n"; Assert(0); } m_gui = LoadGui("gui-title.txt"); Assert(m_gui); GuiButton* start = (GuiButton*)GetElementByName(m_gui, "start-button"); start->SetCommand(Amju::OnStartButton); start->SetHasFocus(true); GuiButton* options = (GuiButton*)GetElementByName(m_gui, "options-button"); options->SetCommand(Amju::OnOptionsButton); GuiButton* quick = (GuiButton*)GetElementByName(m_gui, "quick-start-button"); static PlayerInfoManager* pim = ThePlayerInfoManager::Instance(); if (pim->GetNumPlayerNames() > 0) { quick->SetVisible(true); quick->SetCommand(Amju::OnQuickStartButton); quick->SetHasFocus(true); // Change button text to player name Strings names = pim->GetPlayerNames(); Assert(!names.empty()); pim->SetCurrentPlayer(names[0]); PlayerInfo* pi = pim->GetPI(); Assert(pi); std::string playername = pi->PIGetString(PI_KEY("playername")); quick->SetText(playername); } else { quick->SetVisible(false); } GuiButton* quit = (GuiButton*)GetElementByName(m_gui, "quit-button"); quit->SetCommand(Amju::OnQuitButton); quit->SetIsCancelButton(true); #ifdef SHOW_VERSION GuiText* ver = (GuiText*)GetElementByName(m_gui, "version"); std::string s = "v." + ToString(VersionMajor) + "." + ToString(VersionMinor); #ifdef _DEBUG s += " DEBUG"; #endif ver->SetText(s); #endif //CreateText("my game"); #ifdef PLAY_MUSIC TheSoundManager::Instance()->PlaySong(ROConfig()->GetValue("music-title", "Sound/hammers.it")); #endif }
// ticks the game forward in time void GameInfo::Ticker() { tic++; // TODO read/write demo ticcmd's here // do main actions switch (state) { case GS_INTRO: if (--pagetic <= 0) AdvanceIntro(); break; case GS_LEVEL: if (!paused && currentcluster) currentcluster->Ticker(); if (!dedicated) { hud.Ticker(); automap.Ticker(); } break; case GS_INTERMISSION: wi.Ticker(); break; case GS_FINALE: F_Ticker(); break; case GS_NULL: default: // do nothing break; } MapInfo *m; PlayerInfo *p; if (state != GS_LEVEL) return; // manage players for (player_iter_t t = Players.begin(); t != Players.end(); ) { p = t->second; t++; // because "old t" may be invalidated if (p->playerstate == PST_REMOVE) { // the player is removed from the game (invalidates "old t") if (!p->mp) RemovePlayer(p->number); // first the maps throw out the removed player, then the game proper. // TODO purge the removed players from the frag maps of other players? } else p->Ticker(); } if (!server) return; // for (player_iter_t t = Players.begin(); t != Players.end(); t++) { p = t->second; if (p->playerstate == PST_NEEDMAP) { LConnection *conn = p->connection; if (conn && !conn->isGhostAvailable(p)) { // remote player, is it already being ghosted? if not, wait. CONS_Printf(" server waiting for client ghost\n"); continue; } // assign the player to a map CONS_Printf("Map request.."); if (p->requestmap == 0) { m = initial_map; // first map in game p->entrypoint = initial_ep; } else m = FindMapInfo(p->requestmap); if (!m) { // game ends currentcluster->Finish(p->requestmap, p->entrypoint); StartFinale(NULL); break; } else if (!m->found) m = currentcluster->maps[0]; // TODO or give an error? // cluster change? if (currentcluster->number != m->cluster) { // TODO minor thing: if several players exit maps on the same tick, // and someone besides the first one causes a cluster change, some // maps could be loaded in vain... // cluster change! currentcluster->Finish(p->requestmap, p->entrypoint); MapCluster *next = FindCluster(m->cluster); StartFinale(next); currentcluster = next; break; // this is important! no need to check the other players. } p->Reset(!currentcluster->keepstuff, true); // normal individual mapchange if (!m->Activate(p)) I_Error("Darn!\n"); if (conn) { CONS_Printf(" server sending rpc\n"); // nonlocal player enters a new map, notify client // send the EnterMap rpc only to the owning connection NetEvent *e = TNL_RPC_CONSTRUCT_NETEVENT(p, s2cEnterMap, (m->mapnumber)); conn->postNetEvent(e); } } } }
void MissionAction::Do(PlayerInfo &player, UI *ui, const System *destination) const { bool isOffer = (trigger == "offer"); if(!conversation.IsEmpty()) { ConversationPanel *panel = new ConversationPanel(player, conversation, destination); if(isOffer) panel->SetCallback(&player, &PlayerInfo::MissionCallback); ui->Push(panel); } else if(!dialogText.empty()) { map<string, string> subs; subs["<first>"] = player.FirstName(); subs["<last>"] = player.LastName(); if(player.Flagship()) subs["<ship>"] = player.Flagship()->Name(); string text = Format::Replace(dialogText, subs); if(isOffer) ui->Push(new Dialog(text, player, destination)); else ui->Push(new Dialog(text)); } else if(isOffer && ui) player.MissionCallback(Conversation::ACCEPT); Ship *flagship = player.Flagship(); for(const auto &it : gifts) { int count = it.second; string name = it.first->Name(); if(!count || name.empty()) continue; string message; if(abs(count) == 1) { char c = tolower(name.front()); bool isVowel = (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'); message = (isVowel ? "An " : "A ") + name + " was "; } else message = to_string(abs(count)) + " " + name + "s were "; if(count > 0) message += "added to your "; else message += "removed from your "; bool didCargo = false; bool didShip = false; int cargoCount = player.Cargo().Get(it.first); if(count < 0 && cargoCount) { int moved = min(cargoCount, -count); count += moved; player.Cargo().Transfer(it.first, moved); didCargo = true; } while(flagship && count) { int moved = (count > 0) ? 1 : -1; if(flagship->Attributes().CanAdd(*it.first, moved)) { flagship->AddOutfit(it.first, moved); didShip = true; } else break; count -= moved; } if(count > 0) { player.Cargo().Transfer(it.first, -count); didCargo = true; if(count > 0) { string special = "The " + name + (count == 1 ? " was" : "s were"); special += " put in your cargo hold because there is not enough space to install "; special += (count == 1) ? "it" : "them"; special += " in your ship."; ui->Push(new Dialog(special)); } } if(didCargo && didShip) message += "cargo hold and your flagship."; else if(didCargo) message += "cargo hold."; else message += "flagship."; Messages::Add(message); } if(payment) player.Accounts().AddCredits(payment); for(const auto &it : events) player.AddEvent(*GameData::Events().Get(it.first), player.GetDate() + it.second); conditions.Apply(player.Conditions()); }
BankPanel::BankPanel(PlayerInfo &player) : player(player), qualify(player.Accounts().Prequalify()), selectedRow(0) { SetTrapAllEvents(false); }
Engine::Engine(PlayerInfo &player) : player(player), calcTickTock(false), drawTickTock(false), terminate(false), step(0), flash(0.), doFlash(false), wasLeavingHyperspace(false), load(0.), loadCount(0), loadSum(0.) { // Start the thread for doing calculations. calcThread = thread(&Engine::ThreadEntryPoint, this); if(!player.IsLoaded() || !player.GetSystem()) return; // Preload any landscapes for this system. for(const StellarObject &object : player.GetSystem()->Objects()) if(object.GetPlanet()) GameData::Preload(object.GetPlanet()->Landscape()); // Now we know the player's current position. Draw the planets. Point center; if(player.GetPlanet()) { for(const StellarObject &object : player.GetSystem()->Objects()) if(object.GetPlanet() == player.GetPlanet()) center = object.Position(); } for(const StellarObject &object : player.GetSystem()->Objects()) if(!object.GetSprite().IsEmpty()) { Point position = object.Position(); Point unit = object.Unit(); position -= center; int type = object.IsStar() ? Radar::SPECIAL : !object.GetPlanet() ? Radar::INACTIVE : object.GetPlanet()->IsWormhole() ? Radar::ANOMALOUS : GameData::GetPolitics().HasDominated(object.GetPlanet()) ? Radar::PLAYER : object.GetPlanet()->CanLand() ? Radar::FRIENDLY : Radar::HOSTILE; double r = max(2., object.Radius() * .03 + .5); draw[calcTickTock].Add(object.GetSprite(), position, unit); radar[calcTickTock].Add(type, position, r, r - 1.); } // Add all neighboring systems to the radar. const Ship *flagship = player.Flagship(); const System *targetSystem = flagship ? flagship->GetTargetSystem() : nullptr; const vector<const System *> &links = (flagship && flagship->Attributes().Get("jump drive")) ? player.GetSystem()->Neighbors() : player.GetSystem()->Links(); for(const System *system : links) radar[calcTickTock].AddPointer( (system == targetSystem) ? Radar::SPECIAL : Radar::INACTIVE, system->Position() - player.GetSystem()->Position()); }
int main() { network::InitializeNetwork(); initMemoryCheck(); //Init Timer GlobalTimer *gt = GlobalTimer::getInstance(); //Init EventManager EventManager *test; test = myNew EventManager("test", true); //Init ActorHandler Actor::init(); ActorHandler *actorHandler = ActorHandler::getInstance(); network::Peer mPeer("hej2", 5002); network::MessageHandler *msgServer, *msgClient; msgClient = myNew network::MsgH_GameClient(&mPeer); mPeer.getServerManager()->addMessageHandler(msgClient); msgServer = myNew network::MsgH_GameServer("tja", mPeer.getPeerManager()); mPeer.getPeerManager()->addMessageHandler(msgServer); mPeer.joinNetwork("localhost", 5001); network::EventMsgHandler netEventHandler(mPeer.getIdManager()); mPeer.getPeerManager()->addMessageHandler(&netEventHandler); //Init Listeners EventListenerPtr snoop; snoop = boost::shared_ptr<EventSnooper>(myNew EventSnooper()); safeAddListener(snoop, EventType(gWildcardEventType)); EventListenerPtr stats; stats = boost::shared_ptr<Statistics>(myNew Statistics()); safeAddListener(stats, EvtData_From_ActorDestroyed::mEventType); safeAddListener(stats, EvtData_System_EndGame::mEventType); EventListenerPtr epActorHandler; epActorHandler = boost::shared_ptr<ActorHandler>(actorHandler); safeAddListener(epActorHandler,EvtData_To_EnemyUpdateHp::mEventType); safeAddListener(epActorHandler, EvtData_From_ActorCollision::mEventType); safeAddListener(epActorHandler, EvtData_To_TankStartFire::mEventType); safeAddListener(epActorHandler, EvtData_To_TankStopFire::mEventType); safeAddListener(epActorHandler, EvtData_From_ActorDestroyed::mEventType); safeAddListener(epActorHandler, EvtData_To_ActorStartMove::mEventType); safeAddListener(epActorHandler, EvtData_To_ActorStopMove::mEventType); safeAddListener(epActorHandler, EvtData_To_ActorStartRotate::mEventType); safeAddListener(epActorHandler, EvtData_To_ActorStopRotate::mEventType); EventListenerPtr logiclol; logiclol = boost::shared_ptr<LogicListener>(myNew LogicListener()); safeAddListener(logiclol,EvtData_From_EnemyHit::mEventType); safeAddListener(logiclol, EvtData_System_EndGame::mEventType); EventListenerPtr networkForwarder; networkForwarder = boost::shared_ptr<network::EventForwarder>(myNew network::EventForwarder(&mPeer)); //safeAddListener(networkForwarder, EvtData_To_ActorStartMove::mEventType); safeAddListener(networkForwarder, EvtData_To_ActorStopMove::mEventType); EventListenerPtr sound; sound = boost::shared_ptr<sound::SoundListener>(myNew sound::SoundListener()); logic::safeAddListener(sound, logic::EvtData_To_ActorStartMove::mEventType); logic::safeAddListener(sound, logic::EvtData_To_ActorStopMove::mEventType); logic::safeAddListener(sound, logic::EvtData_From_ActorCreated::mEventType); logic::safeAddListener(sound, logic::EvtData_From_ActorDestroyed::mEventType); logic::safeAddListener(sound, logic::EvtData_From_WeaponFired::mEventType); //Init PLayerInfo PlayerInfo *pi = PlayerInfo::getInstance(); //Init Dx gfx::DX10Module *module = gfx::DX10Module::getInstance(); pthread_t th = module->create(); while(!module->getRunFlag()) { Sleep(10); } //Init Input logic::InputStates *input = myNew logic::InputStates(module->getHInstancePointer(), module->getHWNDPointer()); input->setState(logic::InputStates::GameState_Game_Inside_Tank); //testing dxmodule module->lock(0); gfx::Camera *camera = module->getCamera(); camera->setTarget(D3DXVECTOR3(0.0f, 0.0f, 0.0f)); camera->setPosition(D3DXVECTOR3(-100.0f, 50.0f, -100.0f)); module->loadObjectShapeInstance(gfx::ShapeTypes::CUBE, 1, "Cube", 5000); srand(time(0)); int colorCounter; gfx::TransformObject *tempObj; for(int i = 0; i < 10; i++) { colorCounter = i; for(int j = 0; j < 10; j++) { int rnd = rand()%10; tempObj = module->createObjectInstanced(1); if(rnd == 0) { tempObj->setPosition(D3DXVECTOR3(-30.0f * j,0.0f,-30.0f * i)); tempObj->setScale(D3DXVECTOR3(15.0f, 15.0f, 15.0f)); tempObj->setID(-1); } else { tempObj->setPosition(D3DXVECTOR3(-30.0f * j, -10.0f,-30.0f * i)); tempObj->setScale(D3DXVECTOR3(15.0f, 0.1f, 15.0f)); tempObj->setID(-2); } int color = colorCounter % 4; if(color == 0) tempObj->setColor(D3DXCOLOR(0.0f,0.0f,0.0f,1.0f)); else if(color == 1) tempObj->setColor(D3DXCOLOR(1.0f,0.0f,0.0f,1.0f)); else if(color == 2) tempObj->setColor(D3DXCOLOR(1.0f,1.0f,0.0f,1.0f)); else if(color == 3) tempObj->setColor(D3DXCOLOR(0.0f,1.0f,1.0f,1.0f)); colorCounter++; } } //module->loadObjectShapeInstance(gfx::ShapeTypes::CUBE, 1, "Cube", 5000); module->loadMeshInstance("../../ModelFiles/TankGround/TankGeometry.txt", 2, "LongRangeTank", 5000); //module->loadMeshInstance("../../ModelFiles/TankGround/TankGeometry.txt", 1, "Tank3", 5000); module->loadMeshInstance("../../ModelFiles/TankAir/TankAirGeometry.txt", 3, "CloseRangeTank", 5000); /*gfx::InstanceMesh *mesh1 = module->createMeshInstanced("Tank"); mesh1->setTextureID(0); mesh1->setFlagUpdateAbsolute(false); mesh1->setID(lolAnt->getKey()); mesh1->setName("enemy"); mesh1->setPosition(D3DXVECTOR3(lolAnt->getPosition().x, lolAnt->getPosition().y, lolAnt->getPosition().z)); mesh1->setScale(D3DXVECTOR3(2.5f, 1.5f, 2.5f)); mesh1->setColor(D3DXCOLOR(0.0f, 0.25f, 1.0f, 1.0f)); mesh1 = module->createMeshInstanced("Tank3"); mesh1->setTextureID(0); mesh1->setFlagUpdateAbsolute(false); mesh1->setID(spindelFan->getKey()); mesh1->setName("enemy2"); mesh1->setPosition(D3DXVECTOR3(spindelFan->getPosition().x, spindelFan->getPosition().y, spindelFan->getPosition().z)); mesh1->setScale(D3DXVECTOR3(2.5f, 1.5f, 2.5f)); mesh1->setColor(D3DXCOLOR(0.0f, 0.25f, 1.0f, 1.0f)); mesh1 = module->createMeshInstanced("Tank2"); mesh1->setTextureID(1); mesh1->setFlagUpdateAbsolute(false); mesh1->setID(pt->getKey()); mesh1->setName("player"); mesh1->setPosition(D3DXVECTOR3(pt->getPosition().x, pt->getPosition().y, pt->getPosition().z)); mesh1->setScale(D3DXVECTOR3(2.5f, 1.5f, 2.5f)); mesh1->setColor(D3DXCOLOR(1.0f, 0.0f, 1.0f, 1.0f));*/ //Create actors Tank *pt = myNew Tank(200, 15, Tank::TankType_CloseCombat); pi->setTankActorId(pt->getKey()); //safeQueueEvent(EventDataPtr(myNew EvtData_From_ActorCreated(pt->getKey()))); FireAnt *lolAnt = myNew FireAnt(100,20,Enemy::Size_Small,1,150.0f); //safeQueueEvent(EventDataPtr(myNew EvtData_From_ActorCreated(lolAnt->getKey()))); actorHandler->insertActor(lolAnt); lolAnt->setPosition(-120.0f,0.0f,0.0f); lolAnt->setDirection(1.0f,0.0f,0.0f); BlackWidow *spindelFan = myNew BlackWidow(100,20,Enemy::Size_Medium,1,150.0f); actorHandler->insertActor(spindelFan); spindelFan->setPosition(-50.0f,0.0f,0.0f); spindelFan->setDirection(1.0f,0.0f,0.0f); actorHandler->insertActor(pt); pt->setPosition(-10.0f, 3.0f, 0.0f); pt->setDirection(1.0f, 0.0f, 0.0f); pt->setSubsetDirection(1.0f,0.0f,0.0f); actorHandler->setDXModule(); module->unlock(0); sound::SoundSystem *ss = sound::SoundSystem::getInstance(); ss->setActor(); LogicQuadTree *pQuadTree = LogicQuadTree::getInstance(); float dt; while(!module->getQuit()) { test->tick(EventManager::KINFINITE); pQuadTree->updateQuadTree(); //camera->setTarget(mesh1->getPositionX(), mesh1->getPositionY(), mesh1->getPositionZ()); //camera->setPosition(D3DXVECTOR3(mesh1->getPositionX()-100.0f, 50.0f, mesh1->getPositionZ()-100.0f)); dt = gt->tick(); actorHandler->update(dt); ss->Update(); input->update(); Sleep(10); } logic::safeTriggerEvent(logic::EvtData_System_EndGame()); KeyHandler *tmp = KeyHandler::getInstance(); network::ShutdownNetwork(); SAFE_DELETE(ss); SAFE_DELETE(pQuadTree); SAFE_DELETE(tmp); SAFE_DELETE(input); SAFE_DELETE(gt); SAFE_DELETE(test); SAFE_DELETE(pi); SAFE_DELETE(module); return 0; }
int main(int argc, char *argv[]) { Conversation conversation; bool debugMode = false; for(const char *const *it = argv + 1; *it; ++it) { string arg = *it; if(arg == "-h" || arg == "--help") { PrintHelp(); return 0; } else if(arg == "-v" || arg == "--version") { PrintVersion(); return 0; } else if(arg == "-t" || arg == "--talk") conversation = LoadConversation(); else if(arg == "-d" || arg == "--debug") debugMode = true; } PlayerInfo player; try { SDL_Init(SDL_INIT_VIDEO); // Begin loading the game data. GameData::BeginLoad(argv); Audio::Init(GameData::Sources()); // On Windows, make sure that the sleep timer has at least 1 ms resolution // to avoid irregular frame rates. #ifdef _WIN32 timeBeginPeriod(1); #endif player.LoadRecent(); player.ApplyChanges(); // Check how big the window can be. SDL_DisplayMode mode; if(SDL_GetCurrentDisplayMode(0, &mode)) return DoError("Unable to query monitor resolution!"); Preferences::Load(); Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI; if(Preferences::Has("fullscreen")) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; // Make the window just slightly smaller than the monitor resolution. int maxWidth = mode.w; int maxHeight = mode.h; // Restore this after toggling fullscreen. int restoreWidth = 0; int restoreHeight = 0; if(maxWidth < 640 || maxHeight < 480) return DoError("Monitor resolution is too small!"); if(Screen::RawWidth() && Screen::RawHeight()) { // Never allow the saved screen width to be leaving less than 100 // pixels free around the window. This avoids the problem where you // maximize without going full-screen, and next time the window pops // up you can't access the resize control because it is offscreen. Screen::SetRaw( min(Screen::RawWidth(), (maxWidth - 100)), min(Screen::RawHeight(), (maxHeight - 100))); if(flags & SDL_WINDOW_FULLSCREEN_DESKTOP) { restoreWidth = Screen::RawWidth(); restoreHeight = Screen::RawHeight(); Screen::SetRaw(maxWidth, maxHeight); } } else Screen::SetRaw(maxWidth - 100, maxHeight - 100); // Make sure the zoom factor is not set too high for the full UI to fit. if(Screen::Height() < 700) Screen::SetZoom(100); // Create the window. SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); #ifdef _WIN32 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); #endif SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); SDL_Window *window = SDL_CreateWindow("Endless Sky", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, Screen::RawWidth(), Screen::RawHeight(), flags); if(!window) return DoError("Unable to create window!"); SDL_GLContext context = SDL_GL_CreateContext(window); if(!context) return DoError("Unable to create OpenGL context! Check if your system supports OpenGL 3.0.", window); if(SDL_GL_MakeCurrent(window, context)) return DoError("Unable to set the current OpenGL context!", window, context); SDL_GL_SetSwapInterval(1); // Initialize GLEW. #ifndef __APPLE__ glewExperimental = GL_TRUE; if(glewInit() != GLEW_OK) return DoError("Unable to initialize GLEW!", window, context); #endif // Check that the OpenGL version is high enough. const char *glVersion = reinterpret_cast<const char *>(glGetString(GL_VERSION)); if(!glVersion || !*glVersion) return DoError("Unable to query the OpenGL version!", window, context); const char *glslVersion = reinterpret_cast<const char *>(glGetString(GL_SHADING_LANGUAGE_VERSION)); if(!glslVersion || !*glslVersion) { ostringstream out; out << "Unable to query the GLSL version. OpenGL version is " << glVersion << "."; return DoError(out.str(), window, context); } if(*glVersion < '3') { ostringstream out; out << "Endless Sky requires OpenGL version 3.0 or higher." << endl; out << "Your OpenGL version is " << glVersion << ", GLSL version " << glslVersion << "." << endl; out << "Please update your graphics drivers."; return DoError(out.str(), window, context); } glClearColor(0.f, 0.f, 0.0f, 1.f); glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); GameData::LoadShaders(); { // Check whether this is a high-DPI window. int width = 0; int height = 0; SDL_GL_GetDrawableSize(window, &width, &height); Screen::SetHighDPI(width > Screen::RawWidth() && height > Screen::RawHeight()); // Fix a possible race condition leading to the wrong window dimensions. glViewport(0, 0, width, height); } UI gamePanels; UI menuPanels; menuPanels.Push(new MenuPanel(player, gamePanels)); if(!conversation.IsEmpty()) menuPanels.Push(new ConversationPanel(player, conversation)); string swizzleName = "_texture_swizzle"; #ifndef __APPLE__ const char *extensions = reinterpret_cast<const char *>(glGetString(GL_EXTENSIONS)); if(!strstr(extensions, swizzleName.c_str())) #else bool hasSwizzle = false; GLint extensionCount; glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); for(GLint i = 0; i < extensionCount && !hasSwizzle; ++i) { const char *extension = reinterpret_cast<const char *>(glGetStringi(GL_EXTENSIONS, i)); hasSwizzle = (extension && strstr(extension, swizzleName.c_str())); } if(!hasSwizzle) #endif menuPanels.Push(new Dialog( "Note: your computer does not support the \"texture swizzling\" OpenGL feature, " "which Endless Sky uses to draw ships in different colors depending on which " "government they belong to. So, all human ships will be the same color, which " "may be confusing. Consider upgrading your graphics driver (or your OS).")); FrameTimer timer(60); bool isPaused = false; while(!menuPanels.IsDone()) { // Handle any events that occurred in this frame. SDL_Event event; while(SDL_PollEvent(&event)) { UI &activeUI = (menuPanels.IsEmpty() ? gamePanels : menuPanels); // The caps lock key slows the game down (to make it easier to // see and debug things that are happening quickly). if(debugMode && (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) && event.key.keysym.sym == SDLK_CAPSLOCK) { timer.SetFrameRate((event.key.keysym.mod & KMOD_CAPS) ? 10 : 60); } else if(debugMode && event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_BACKQUOTE) { isPaused = !isPaused; } else if(event.type == SDL_KEYDOWN && menuPanels.IsEmpty() && Command(event.key.keysym.sym).Has(Command::MENU) && !gamePanels.IsEmpty() && gamePanels.Top()->IsInterruptible()) { menuPanels.Push(shared_ptr<Panel>( new MenuPanel(player, gamePanels))); } else if(event.type == SDL_QUIT) { menuPanels.Quit(); } else if(event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { int width = event.window.data1 & ~1; int height = event.window.data2 & ~1; if(width != Screen::RawWidth() || height != Screen::RawHeight()) { Screen::SetRaw(width, height); if((event.window.data1 | event.window.data2) & 1) SDL_SetWindowSize(window, Screen::RawWidth(), Screen::RawHeight()); SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); } } else if(event.type == SDL_KEYDOWN && (Command(event.key.keysym.sym).Has(Command::FULLSCREEN) || (event.key.keysym.sym == SDLK_RETURN && event.key.keysym.mod & KMOD_ALT))) { if(restoreWidth) { SDL_SetWindowFullscreen(window, 0); Screen::SetRaw(restoreWidth, restoreHeight); SDL_SetWindowSize(window, Screen::RawWidth(), Screen::RawHeight()); restoreWidth = 0; restoreHeight = 0; } else { restoreWidth = Screen::RawWidth(); restoreHeight = Screen::RawHeight(); Screen::SetRaw(maxWidth, maxHeight); SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); } int width, height; SDL_GL_GetDrawableSize(window, &width, &height); glViewport(0, 0, width, height); } else if(activeUI.Handle(event)) { // No need to do anything more! } } Font::ShowUnderlines(SDL_GetModState() & KMOD_ALT); // Tell all the panels to step forward, then draw them. ((!isPaused && menuPanels.IsEmpty()) ? gamePanels : menuPanels).StepAll(); Audio::Step(); // That may have cleared out the menu, in which case we should draw // the game panels instead: (menuPanels.IsEmpty() ? gamePanels : menuPanels).DrawAll(); SDL_GL_SwapWindow(window); timer.Wait(); } // If you quit while landed on a planet, save the game. if(player.GetPlanet()) player.Save(); // The Preferences class reads the screen dimensions, so update them if // the window is full screen: bool isFullscreen = (restoreWidth != 0); Preferences::Set("fullscreen", isFullscreen); if(isFullscreen) Screen::SetRaw(restoreWidth, restoreHeight); Preferences::Save(); Cleanup(window, context); } catch(const runtime_error &error) { DoError(error.what()); } return 0; }
OutfitterPanel::OutfitterPanel(PlayerInfo &player) : ShopPanel(player, CATEGORIES), available(player.SoldOutfits()) { for(const pair<string, Outfit> &it : GameData::Outfits()) catalog[it.second.Category()].insert(it.first); }
HailPanel::HailPanel(PlayerInfo &player, const shared_ptr<Ship> &ship) : player(player), ship(ship), sprite(ship->GetSprite().GetSprite()), unit(2. * ship->Unit()) { SetInterruptible(false); const Government *gov = ship->GetGovernment(); header = gov->GetName() + " ship \"" + ship->Name() + "\":"; if(gov->GetName() == "Derelict") { message = "There is no response to your hail."; } else if(gov->IsEnemy()) { if(ship->IsDisabled()) message = GameData::Phrases().Get("hostile disabled")->Get(); else { SetBribe(gov->GetBribeFraction()); if(bribe) message = "If you want us to leave you alone, it'll cost you " + Format::Number(bribe) + " credits."; } } else if(ship->IsDisabled()) { const Ship *flagship = player.Flagship(); if(!flagship->JumpsRemaining() || flagship->IsDisabled()) message = "Sorry, we can't help you, because our ship is disabled."; else message = "Our ship has been disabled! Please come board our ship and patch us up!"; } else { // Is the player in any need of assistance? const Ship *flagship = player.Flagship(); // Check if the player is out of fuel. if(!flagship->JumpsRemaining()) { playerNeedsHelp = true; canGiveFuel = ship->CanRefuel(*flagship); } // Check if the player is disabled. if(flagship->IsDisabled()) { playerNeedsHelp = true; canRepair = true; } if(canGiveFuel || canRepair) message = "Looks like you've gotten yourself into a bit of trouble. " "Would you like us to "; if(canGiveFuel && canRepair) message += "patch you up and give you some fuel?"; else if(canGiveFuel) message += "give you some fuel?"; else if(canRepair) message += "patch you up?"; } if(message.empty()) message = ship->GetHail(); }