WorldMapControl::WorldMapControl(const char *font, int direction) { ScrollX = 0; ScrollY = 0; MouseIsDown = false; Changed = true; Area = NULL; Value = direction; Game* game = core->GetGame(); WorldMap* worldmap = core->GetWorldMap(); CopyResRef(currentArea, game->CurrentArea); int entry = core->GetAreaAlias(currentArea); if (entry >= 0) { WMPAreaEntry *m = worldmap->GetEntry(entry); CopyResRef(currentArea, m->AreaResRef); } //if there is no trivial area, look harder if (!worldmap->GetArea(currentArea, (unsigned int &) entry) && core->HasFeature(GF_FLEXIBLE_WMAP) ) { WMPAreaEntry *m = worldmap->FindNearestEntry(currentArea, (unsigned int &) entry); if (m) { CopyResRef(currentArea, m->AreaResRef); } } //this also updates visible locations worldmap->CalculateDistances(currentArea, Value); // alpha bit is unfortunately ignored if (font[0]) { ftext = core->GetFont(font); } else { ftext = NULL; } // initialize label colors // NOTE: it would be better to initialize these colors from // some 2da file Color normal = { 0xf0, 0xf0, 0xf0, 0xff }; Color selected = { 0xf0, 0x80, 0x80, 0xff }; Color notvisited = { 0x80, 0x80, 0xf0, 0xff }; Color black = { 0x00, 0x00, 0x00, 0x00 }; pal_normal = core->CreatePalette ( normal, black ); pal_selected = core->CreatePalette ( selected, black ); pal_notvisited = core->CreatePalette ( notvisited, black ); ResetEventHandler( WorldMapControlOnPress ); ResetEventHandler( WorldMapControlOnEnter ); }
// check if the actor is in npclevel.2da and replace accordingly bool Game::CheckForReplacementActor(int i) { if (core->InCutSceneMode() || npclevels.empty()) { return false; } Actor* act = NPCs[i]; ieDword level = GetPartyLevel(false) / GetPartySize(false); if (!(act->Modified[IE_MC_FLAGS]&MC_BEENINPARTY) && !(act->Modified[IE_STATE_ID]&STATE_DEAD) && act->GetXPLevel(false) < level) { ieResRef newcre = "****"; // default table value std::vector<std::vector<char *> >::iterator it; for (it = npclevels.begin(); it != npclevels.end(); it++) { if (!stricmp((*it)[0], act->GetScriptName()) && (level > 2)) { // the tables have entries only up to level 24 ieDword safeLevel = npclevels[0].size() - 1; if (level < safeLevel) { safeLevel = level; } CopyResRef(newcre, (*it)[safeLevel-2]); break; } } if (stricmp(newcre, "****")) { int pos = gamedata->LoadCreature(newcre, 0, false, act->version); if (pos < 0) { error("Game::CheckForReplacementActor", "LoadCreature failed: pos is negative!\n"); } else { Actor *newact = GetNPC(pos); if (!newact) { error("Game::CheckForReplacementActor", "GetNPC failed: cannot find act!\n"); } else { newact->Pos = act->Pos; // the map is not loaded yet, so no SetPosition newact->TalkCount = act->TalkCount; newact->InteractCount = act->InteractCount; CopyResRef(newact->Area, act->Area); DelNPC(InStore(act), true); return true; } } } } return false; }
//adds a temporary AreaEntry to the world map //this entry has two links for each direction, leading to the two areas //we were travelling between when using the supplied link void WorldMap::SetEncounterArea(const ieResRef area, WMPAreaLink *link) { unsigned int i; if (GetArea(area, i)) { return; } //determine the area the link came from unsigned int j, cnt = GetLinkCount(); for (j = 0; j < cnt; ++j) { if (link == area_links[j]) { break; } } i = WhoseLinkAmI(j); if (i == (unsigned int) -1) { Log(ERROR, "WorldMap", "Could not add encounter area"); return; } WMPAreaEntry *ae = GetNewAreaEntry(); ae->SetAreaStatus(WMP_ENTRY_VISIBLE|WMP_ENTRY_ACCESSIBLE|WMP_ENTRY_VISITED, BM_SET); CopyResRef(ae->AreaName, area); CopyResRef(ae->AreaResRef, area); ae->LocCaptionName = -1; ae->LocTooltipName = -1; ae->IconSeq = -1; CopyResRef(ae->LoadScreenResRef, ""); WMPAreaEntry *src = area_entries[i]; WMPAreaEntry *dest = area_entries[link->AreaIndex]; ae->X = src->X + (int) (dest->X - src->X) / 2; ae->Y = src->Y + (int) (dest->Y - src->Y) / 2; //setup the area links WMPAreaLink *ldest = new WMPAreaLink(); memcpy(ldest, link, sizeof(WMPAreaLink)); ldest->DistanceScale /= 2; ldest->EncounterChance = 0; link = GetLink(dest->AreaName, src->AreaName); if (!link) { Log(ERROR, "WorldMap", "Could not find link from %s to %s", dest->AreaName, src->AreaName); delete ae; delete ldest; return; } WMPAreaLink *lsrc = new WMPAreaLink(); memcpy(lsrc, link, sizeof(WMPAreaLink)); lsrc->DistanceScale /= 2; lsrc->EncounterChance = 0; unsigned int idx = area_links.size(); AddAreaLink(ldest); AddAreaLink(lsrc); for (i = 0; i < 4; ++i) { ae->AreaLinksCount[i] = 2; ae->AreaLinksIndex[i] = idx; } encounterArea = area_entries.size(); AddAreaEntry(ae); }
Game::Game(void) : Scriptable( ST_GLOBAL ) { protagonist = PM_YES; //set it to 2 for iwd/iwd2 and 0 for pst partysize = 6; Ticks = 0; version = 0; Expansion = 0; LoadMos[0] = 0; TextScreen[0] = 0; SelectedSingle = 1; //the PC we are looking at (inventory, shop) PartyGold = 0; SetScript( core->GlobalScript, 0 ); MapIndex = -1; Reputation = 0; ControlStatus = 0; CombatCounter = 0; //stored here until we know better StateOverrideTime = 0; StateOverrideFlag = 0; BanterBlockTime = 0; BanterBlockFlag = 0; WeatherBits = 0; crtable = NULL; kaputz = NULL; beasts = NULL; mazedata = NULL; timestop_owner = NULL; timestop_end = 0; event_timer = 0; event_handler = NULL; weather = new Particles(200); weather->SetRegion(0, 0, core->Width, core->Height); LastScriptUpdate = 0; //loading master areas AutoTable table; if (table.load("mastarea")) { int i = table->GetRowCount(); mastarea.reserve(i); while(i--) { char *tmp = (char *) malloc(9); strnuprcpy (tmp,table->QueryField(i,0),8); mastarea.push_back( tmp ); } } //loading rest/daylight switching movies (only bg2 has them) memset(restmovies,'*',sizeof(restmovies)); memset(daymovies,'*',sizeof(daymovies)); memset(nightmovies,'*',sizeof(nightmovies)); if (table.load("restmov")) { for(int i=0;i<8;i++) { strnuprcpy(restmovies[i],table->QueryField(i,0),8); strnuprcpy(daymovies[i],table->QueryField(i,1),8); strnuprcpy(nightmovies[i],table->QueryField(i,2),8); } } //loading npc starting levels ieResRef tn; if (Expansion == 5) { // tob is special CopyResRef(tn, "npclvl25"); } else { CopyResRef(tn, "npclevel"); } if (table.load(tn)) { int cols = table->GetColumnCount(); int rows = table->GetRowCount(); int i, j; npclevels.reserve(rows); for (i = 0; i < rows; i++) { npclevels.push_back (std::vector<char *>(cols+1)); for(j = -1; j < cols; j++) { char *ref = new char[9]; if (j == -1) { CopyResRef(ref, table->GetRowName(i)); npclevels[i][j+1] = ref; } else { CopyResRef(ref, table->QueryField(i, j)); npclevels[i][j+1] = ref; } } } } interval = 1000/AI_UPDATE_TIME; hasInfra = false; familiarBlock = false; //FIXME:i'm not sure in this... NoInterrupt(); bntchnc = NULL; bntrows = -1; }