📄 scourge.cpp
字号:
} } return false;}void Scourge::toggleInventoryWindow() { if(inventory->isVisible()) inventory->hide(); else inventory->show();}void Scourge::toggleOptionsWindow() { if(optionsMenu->isVisible()) optionsMenu->hide(); else { party->toggleRound(true); optionsMenu->show(); }}void Scourge::showExitConfirmationDialog() { party->toggleRound(true); exitConfirmationDialog->setVisible(true);}bool Scourge::handleEvent(Widget *widget, SDL_Event *event) { if(widget == Window::message_button && info_dialog_showing) { party->toggleRound(false); info_dialog_showing = false; party->startEffect(Constants::EFFECT_TELEPORT, (Constants::DAMAGE_DURATION * 4)); } if(containerGuiCount > 0) { for(int i = 0; i < containerGuiCount; i++) { if(containerGui[i]->handleEvent(widget, event)) { closeContainerGui(containerGui[i]); } } // return false; } if(inventory->isVisible()) { inventory->handleEvent(widget, event); // return false; } if(optionsMenu->isVisible()) { optionsMenu->handleEvent(widget, event); return false; } // FIXME: this is hacky... if(party->handleEvent(widget, event)) return true; int n = board->handleEvent(widget, event); if(n == Board::EVENT_HANDLED) return false; else if(n == Board::EVENT_PLAY_MISSION) { int selected = board->getSelectedLine(); if(selected != -1 && selected < board->getMissionCount()) { nextMission = selected; oldStory = currentStory = 0; endMission(); return true; } } if(widget == yesExitConfirm) { exitLabel->setText(Constants::getMessage(Constants::EXIT_MISSION_LABEL)); exitConfirmationDialog->setVisible(false); endMission(); return true; } else if(widget == noExitConfirm) { teleporting = false; changingStory = false; currentStory = oldStory; exitLabel->setText(Constants::getMessage(Constants::EXIT_MISSION_LABEL)); exitConfirmationDialog->setVisible(false); return false; } return false;}// create the uivoid Scourge::createUI() { messageWin = new Window( getSDLHandler(), 0, 0, 400, 120, strdup("Messages"), getShapePalette()->getGuiTexture(), false ); messageWin->setBackground(0, 0, 0); messageList = new ScrollingList(0, 0, 400, 95); messageList->setSelectionColor( 0.15f, 0.15f, 0.3f ); messageWin->addWidget(messageList); // this has to be after addWidget messageList->setBackground( 1, 0.75f, 0.45f ); messageList->setSelectionColor( 0.25f, 0.25f, 0.25f ); // FIXME: try to encapsulate this in a class... // exitConfirmationDialog = NULL; int w = 250; int h = 120; exitConfirmationDialog = new Window(getSDLHandler(), (getSDLHandler()->getScreen()->w/2) - (w/2), (getSDLHandler()->getScreen()->h/2) - (h/2), w, h, strdup("Leave level?"), getShapePalette()->getGuiTexture(), false); yesExitConfirm = new Button( 40, 50, 110, 80, strdup("Yes") ); exitConfirmationDialog->addWidget((Widget*)yesExitConfirm); noExitConfirm = new Button( 140, 50, 210, 80, strdup("No") ); exitConfirmationDialog->addWidget((Widget*)noExitConfirm); exitLabel = new Label(20, 20, Constants::getMessage(Constants::EXIT_MISSION_LABEL)); exitConfirmationDialog->addWidget((Widget*)exitLabel);}void Scourge::playRound() { // change animation if needed for(int i = 0; i < 4; i++) { if(((MD2Shape*)(party->getParty(i)->getShape()))->getAttackEffect()) { party->getParty(i)->getShape()->setCurrentAnimation((int)MD2_ATTACK); ((MD2Shape*)(party->getParty(i)->getShape()))->setAngle(party->getParty(i)->getTargetAngle()); } else if(party->getParty(i)->anyMovesLeft()) party->getParty(i)->getShape()->setCurrentAnimation((int)MD2_RUN); else party->getParty(i)->getShape()->setCurrentAnimation((int)MD2_STAND); } // move the map if(move) map->move(move); if(targetSelectionFor) return; // hound your targets party->followTargets(); // round starts if: // -in group mode // -(or) the round was manually started GLint t = SDL_GetTicks(); if(party->isRealTimeMode()) { if(lastProjectileTick == 0 || t - lastProjectileTick > userConfiguration->getGameSpeedTicks() / 10) { lastProjectileTick = t; // move projectiles Projectile::moveProjectiles(this); } if(lastTick == 0 || t - lastTick > userConfiguration->getGameSpeedTicks()) { lastTick = t; // move the party members party->movePlayers(); // move visible monsters for(int i = 0; i < creatureCount; i++) { if(!creatures[i]->getStateMod(Constants::dead) && map->isLocationVisible(creatures[i]->getX(), creatures[i]->getY())) { moveMonster(creatures[i]); } } // setup the current battle round if(battleRound.size() == 0) { // set up for battle battleCount = 0; // attack targeted monster if close enough for(int i = 0; i < 4; i++) { if(!party->getParty(i)->getStateMod(Constants::dead) && (party->getParty(i)->hasTarget() || party->getParty(i)->getAction() > -1)) { battle[battleCount++] = new Battle(this, party->getParty(i)); } } for(int i = 0; i < creatureCount; i++) { if(!creatures[i]->getStateMod(Constants::dead) && map->isLocationVisible(creatures[i]->getX(), creatures[i]->getY()) && (creatures[i]->hasTarget() || creatures[i]->getAction() > -1)) { battle[battleCount++] = new Battle(this, creatures[i]); } } // fight one round of the epic battle if(battleCount > 0) { Battle::setupBattles(this, battle, battleCount, &battleRound); battleTurn = 0; } } // fight a turn of the battle if(battleRound.size() > 0) { if(battleTurn < (int)battleRound.size()) { Battle *battle = battleRound[battleTurn]; battle->fightTurn(); delete battle; battleTurn++; } else { battleRound.clear(); } } } }} void Scourge::creatureDeath(Creature *creature) { if(creature == party->getPlayer()) { party->switchToNextLivePartyMember(); } // remove from the map; the object will be cleaned up at the end of the mission map->removeCreature(creature->getX(), creature->getY(), creature->getZ()); // add a container object instead //creature->getShape()->setCurrentAnimation(MD2_DEATH1); Item *item = newItem(RpgItem::getItemByName("Corpse")); // add creature's inventory to container map->setItem(creature->getX(), creature->getY(), creature->getZ(), item); int n = creature->getInventoryCount(); for(int i = 0; i < n; i++) { item->addContainedItem(creature->removeInventory(0)); } creature->setStateMod(Constants::dead, true);}void Scourge::addGameSpeed(int speedFactor){ char msg[80]; userConfiguration->setGameSpeedLevel(userConfiguration->getGameSpeedLevel() + speedFactor); sprintf(msg, "Speed set to %d\n", userConfiguration->getGameSpeedTicks()); map->addDescription(msg);}void Scourge::moveMonster(Creature *monster) { // set running animation (currently move or attack) if(((MD2Shape*)(monster->getShape()))->getAttackEffect()) { monster->getShape()->setCurrentAnimation((int)MD2_ATTACK); ((MD2Shape*)(monster->getShape()))->setAngle(monster->getTargetAngle()); // don't move when attacking return; } else { monster->getShape()->setCurrentAnimation((int)MD2_RUN); } if(monster->getMotion() == Constants::MOTION_LOITER) { // attack the closest player if((int)(20.0f * rand()/RAND_MAX) == 0) { monster->decideMonsterAction(); } else { // random (non-attack) monster movement monster->setDistanceRange(0, Constants::MIN_DISTANCE); for(int i = 0; i < 4; i++) { int n = (int)(10.0f * rand()/RAND_MAX); if(n == 0 || !monster->move(monster->getDir(), map)) { int dir = (int)(4.0f * rand()/RAND_MAX); switch(dir) { case 0: monster->setDir(Constants::MOVE_UP); break; case 1: monster->setDir(Constants::MOVE_DOWN); break; case 2: monster->setDir(Constants::MOVE_LEFT); break; case 3: monster->setDir(Constants::MOVE_RIGHT); break; } } else { break; } } } } else if(monster->hasTarget()) { // monster gives up when low on hp or bored // FIXME: when low on hp, it should run away not loiter if(monster->getAction() == Constants::ACTION_NO_ACTION && (monster->getHp() < (int)((float)monster->getStartingHp() * 0.2f) || (int)(20.0f * rand()/RAND_MAX) == 0)) { monster->setMotion(Constants::MOTION_LOITER); monster->cancelTarget(); } else { monster->moveToLocator(map); } }}void Scourge::openContainerGui(Item *container) { // is it already open? for(int i = 0; i < containerGuiCount; i++) { if(containerGui[i]->getContainer() == container) { containerGui[i]->getWindow()->toTop(); return; } } // open new window if(containerGuiCount < MAX_CONTAINER_GUI) { containerGui[containerGuiCount++] = new ContainerGui(this, container, 10 + containerGuiCount * 15, 10 + containerGuiCount * 15); }}void Scourge::closeContainerGui(ContainerGui *gui) { if(containerGuiCount <= 0) return; for(int i = 0; i < containerGuiCount; i++) { if(containerGui[i] == gui) { for(int t = i; t < containerGuiCount - 1; t++) { containerGui[t] = containerGui[t + 1]; } containerGuiCount--; delete gui; return; } }}void Scourge::closeAllContainerGuis() { for(int i = 0; i < containerGuiCount; i++) { delete containerGui[i]; } containerGuiCount = 0;}void Scourge::refreshContainerGui(Item *container) { for(int i = 0; i < containerGuiCount; i++) { if(containerGui[i]->getContainer() == container) { containerGui[i]->refresh(); } }}void Scourge::showMessageDialog(char *message) { party->toggleRound(true); Window::showMessageDialog(getSDLHandler(), getSDLHandler()->getScreen()->w / 2 - 150, getSDLHandler()->getScreen()->h / 2 - 55, 300, 110, Constants::messages[Constants::SCOURGE_DIALOG][0], getShapePalette()->getGuiTexture(), message);}Window *Scourge::createWoodWindow(int x, int y, int w, int h, char *title) { Window *win = new Window( getSDLHandler(), x, y, w, h, title, getShapePalette()->getGuiWoodTexture(), true, Window::SIMPLE_WINDOW ); win->setBackgroundTileHeight(96); win->setBorderColor( 0.5f, 0.2f, 0.1f ); win->setColor( 0.8f, 0.8f, 0.7f, 1 ); win->setBackground( 0.65, 0.30f, 0.20f, 0.15f ); win->setSelectionColor( 0.25f, 0.35f, 0.6f ); return win;}void Scourge::missionCompleted() { showMessageDialog("Congratulations, mission accomplished!"); // Award exp. points for completing the mission if(currentMission && missionWillAwardExpPoints && currentMission->isCompleted()) { // only do this once missionWillAwardExpPoints = false; // how many points? int exp = (currentMission->getLevel() + 1) * 100; map->addDescription("For completing the mission", 0, 1, 1); char message[200]; sprintf(message, "The party receives %d points.", exp); map->addDescription(message, 0, 1, 1); for(int i = 0; i < getParty()->getPartySize(); i++) { bool b = getParty()->getParty(i)->getStateMod(Constants::leveled); if(!getParty()->getParty(i)->getStateMod(Constants::dead)) { int n = getParty()->getParty(i)->addExperience(exp); if(n > 0) { // sprintf(message, "%s gains %d experience points.", getParty()->getParty(i)->getName(), n); // getMap()->addDescription(message); if(!b && getParty()->getParty(i)->getStateMod(Constants::leveled)) { sprintf(message, "%s gains a level!", getParty()->getParty(i)->getName()); getMap()->addDescription(message, 1.0f, 0.5f, 0.5f); } } } } }}/** Return the closest live player within the given radius or null if none can be found.*/Creature *Scourge::getClosestVisibleMonster(int x, int y, int w, int h, int radius) { float minDist = 0; Creature *p = NULL; for(int i = 0; i < creatureCount; i++) { if(!creatures[i]->getStateMod(Constants::dead) && map->isLocationVisible(creatures[i]->getX(), creatures[i]->getY()) && creatures[i]->isMonster()) { float dist = Constants::distance(x, y, w, h, creatures[i]->getX(), creatures[i]->getY(), creatures[i]->getShape()->getWidth(), creatures[i]->getShape()->getDepth()); if(dist <= (float)radius && (!p || dist < minDist)) { p = creatures[i]; minDist = dist; } } } return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -