Spell* GameData::GetSpell(const ieResRef resname, bool silent) { Spell *spell = (Spell *) SpellCache.GetResource(resname); if (spell) { return spell; } DataStream* str = GetResource( resname, IE_SPL_CLASS_ID, silent ); PluginHolder<SpellMgr> sm(IE_SPL_CLASS_ID); if (!sm) { delete ( str ); return NULL; } if (!sm->Open(str)) { return NULL; } spell = new Spell(); //this is required for storing the 'source' strnlwrcpy(spell->Name, resname, 8); sm->GetSpell( spell, silent ); if (spell == NULL) { return NULL; } SpellCache.SetAt(resname, (void *) spell); return spell; }
DataStream* KEYImporter::GetStream(const char *resname, ieWord type) { if (type == 0) return NULL; const ieDword *ResLocator = resources.get(resname, type); if (!ResLocator) return 0; unsigned int bifnum = ( *ResLocator & 0xFFF00000 ) >> 20; if (!biffiles[bifnum].found) { print( "Cannot find %s... Resource unavailable.\n", biffiles[bifnum].name ); return NULL; } PluginHolder<IndexedArchive> ai(IE_BIF_CLASS_ID); if (ai->OpenArchive( biffiles[bifnum].path ) == GEM_ERROR) { print("Cannot open archive %s\n", biffiles[bifnum].path ); return NULL; } DataStream* ret = ai->GetStream( *ResLocator, type ); if (ret) { strnlwrcpy( ret->filename, resname, 8 ); strcat( ret->filename, "." ); strcat( ret->filename, core->TypeExt( type ) ); return ret; } return NULL; }
void Game::SetMasterArea(const char *area) { if (MasterArea(area) ) return; char *tmp = (char *) malloc(9); strnlwrcpy (tmp,area,8); mastarea.push_back(tmp); }
/** This function sets the actual Label Text */ int Label::SetText(const char* string, int /*pos*/) { if (Buffer ) free( Buffer ); if (Alignment == IE_FONT_ALIGN_CENTER) { if (core->HasFeature( GF_LOWER_LABEL_TEXT )) { int len = strlen(string); Buffer = (char *) malloc( len+1 ); strnlwrcpy( Buffer, string, len ); } else { Buffer = strdup( string ); } } else { Buffer = strdup( string ); } if (!palette) { Color white = {0xff, 0xff, 0xff, 0x00}, black = {0x00, 0x00, 0x00, 0x00}; SetColor(white, black); } if (Owner) { Owner->Invalidate(); } return 0; }
Store* GameData::GetStore(const ieResRef ResRef) { StoreMap::iterator it = stores.find(ResRef); if (it != stores.end()) { return it->second; } DataStream* str = gamedata->GetResource(ResRef, IE_STO_CLASS_ID); PluginHolder<StoreMgr> sm(IE_STO_CLASS_ID); if (sm == NULL) { delete ( str ); return NULL; } if (!sm->Open(str)) { return NULL; } Store* store = sm->GetStore(new Store()); if (store == NULL) { return NULL; } strnlwrcpy(store->Name, ResRef, 8); // The key needs to last as long as the store, // so use the one we just copied. stores[store->Name] = store; return store; }
void VEFObject::Load2DA(const ieResRef resource) { Init(); AutoTable tab(resource); if (!tab) { return; } SingleObject = false; strnlwrcpy(ResName, resource, 8); ieDword GameTime = core->GetGame()->GameTime; int rows = tab->GetRowCount(); while(rows--) { Point offset; int delay, duration; ieResRef resource; offset.x=atoi(tab->QueryField(rows,0)); offset.y=atoi(tab->QueryField(rows,1)); delay = atoi(tab->QueryField(rows,3)); duration = atoi(tab->QueryField(rows,4)); strnuprcpy(resource, tab->QueryField(rows,2), 8); AddEntry(resource, delay, duration, offset, VEF_VVC, GameTime); } }
Item* GameData::GetItem(const ieResRef resname, bool silent) { Item *item = (Item *) ItemCache.GetResource(resname); if (item) { return item; } DataStream* str = GetResource(resname, IE_ITM_CLASS_ID, silent); PluginHolder<ItemMgr> sm(IE_ITM_CLASS_ID); if (!sm) { delete ( str ); return NULL; } if (!sm->Open(str)) { return NULL; } item = new Item(); //this is required for storing the 'source' strnlwrcpy(item->Name, resname, 8); sm->GetItem( item ); if (item == NULL) { return NULL; } ItemCache.SetAt(resname, (void *) item); return item; }
static const char *ConstructFilename(const char* resname, const char* ext) { static char buf[_MAX_PATH]; strnlwrcpy(buf, resname, _MAX_PATH-4, false); strcat(buf, "."); strcat(buf, ext); return buf; }
bool Font::AddResRef(const ieResRef resref) { if (resref) { resRefs = (ieResRef*)realloc(resRefs, sizeof(ieResRef) * ++numResRefs); strnlwrcpy( resRefs[numResRefs - 1], resref, sizeof(ieResRef)-1); return true; } return false; }
void Font::SetName(const char* newName) { strnlwrcpy( name, newName, sizeof(name)-1); if (strnicmp(name, "STATES", 6) == 0) { // state fonts are NEVER multibyte; regardless of TKL encoding. multibyte = false; } }
Effect* EFFImporter::GetEffectV20(Effect *fx) { ieDword tmp; memset( fx, 0, sizeof( Effect ) ); str->Seek(8, GEM_CURRENT_POS); str->ReadDword( &fx->Opcode ); str->ReadDword( &fx->Target ); str->ReadDword( &fx->Power ); str->ReadDword( &fx->Parameter1 ); str->ReadDword( &fx->Parameter2 ); str->ReadWord( &fx->TimingMode ); str->ReadWord( &fx->unknown2 ); str->ReadDword( &fx->Duration ); str->ReadWord( &fx->Probability1 ); str->ReadWord( &fx->Probability2 ); str->ReadResRef( fx->Resource ); str->ReadDword( &fx->DiceThrown ); str->ReadDword( &fx->DiceSides ); str->ReadDword( &fx->SavingThrowType ); str->ReadDword( &fx->SavingThrowBonus ); str->ReadWord( &fx->IsVariable ); //if this field was set to 1, this is a variable str->ReadWord( &fx->IsSaveForHalfDamage ); //if this field was set to 1, save for half damage str->ReadDword( &fx->PrimaryType ); str->Seek( 12, GEM_CURRENT_POS ); str->ReadDword( &fx->Resistance ); str->ReadDword( &fx->Parameter3 ); str->ReadDword( &fx->Parameter4 ); str->Seek( 8, GEM_CURRENT_POS ); str->ReadResRef( fx->Resource2 ); str->ReadResRef( fx->Resource3 ); str->ReadDword( &fx->PosX); str->ReadDword( &fx->PosY); //FIXME: these two points are actually different str->ReadDword( &fx->PosX); str->ReadDword( &fx->PosY); str->ReadDword( &fx->SourceType ); str->ReadResRef( fx->Source ); str->ReadDword( &fx->SourceFlags ); str->ReadDword( &fx->Projectile ); str->ReadDword( &tmp ); fx->InventorySlot=(ieDwordSigned) (tmp); //Variable simply overwrites the resource fields (Keep them grouped) //They have to be continuous if (fx->IsVariable) { str->Read( fx->Resource, 32 ); strnlwrcpy( fx->Resource, fx->Resource, 32 ); } else { str->Seek( 32, GEM_CURRENT_POS); } str->Seek( 8, GEM_CURRENT_POS ); str->ReadDword( &fx->SecondaryType ); str->Seek( 60, GEM_CURRENT_POS ); return fx; }
void ScriptedAnimation::SetFullPalette(int idx) { ieResRef PaletteResRef; //make sure this field is zero terminated, or strlwr will run rampant!!! snprintf(PaletteResRef,sizeof(PaletteResRef),"%.7s%d",ResName, idx); strnlwrcpy(PaletteResRef,PaletteResRef,8); SetFullPalette(PaletteResRef); //no need to call twin }
//tiled objects TileObject* TileMap::AddTile(const char *ID, const char* Name, unsigned int Flags, unsigned short* openindices, int opencount, unsigned short* closeindices, int closecount) { TileObject* tile = new TileObject(); tile->Flags=Flags; strnspccpy(tile->Name, Name, 32); strnlwrcpy(tile->Tileset, ID, 8); tile->SetOpenTiles( openindices, opencount ); tile->SetClosedTiles( closeindices, closecount ); tiles.push_back(tile); return tile; }
void Game::InitActorPos(Actor *actor) { //start.2da row labels const char *mode[PMODE_COUNT] = { "NORMAL", "TUTORIAL", "EXPANSION" }; unsigned int ip = (unsigned int) (actor->InParty-1); AutoTable start("start"); AutoTable strta("startpos"); if (!start || !strta) { error("Game", "Game is missing character start data.\n"); } // 0 - single player, 1 - tutorial, 2 - expansion ieDword playmode = 0; core->GetDictionary()->Lookup( "PlayMode", playmode ); //Sometimes playmode is set to -1 (in pregenerate) //normally execution shouldn't ever come here, but it actually does //preventing problems by defaulting to the regular entry points if (playmode>PMODE_COUNT) { playmode = 0; } const char *xpos = start->QueryField(mode[playmode],"XPOS"); const char *ypos = start->QueryField(mode[playmode],"YPOS"); const char *area = start->QueryField(mode[playmode],"AREA"); const char *rot = start->QueryField(mode[playmode],"ROT"); actor->Pos.x = actor->Destination.x = (short) atoi( strta->QueryField( strta->GetRowIndex(xpos), ip ) ); actor->Pos.y = actor->Destination.y = (short) atoi( strta->QueryField( strta->GetRowIndex(ypos), ip ) ); actor->HomeLocation.x = actor->Pos.x; actor->HomeLocation.y = actor->Pos.y; actor->SetOrientation( atoi( strta->QueryField( strta->GetRowIndex(rot), ip) ), false ); if (strta.load("startare")) { strnlwrcpy(actor->Area, strta->QueryField( strta->GetRowIndex(area), 0 ), 8 ); } else { strnlwrcpy(actor->Area, CurrentArea, 8 ); } }
VEFObject *VEFObject::CreateObject(const ieResRef res, SClass_ID id) { if (gamedata->Exists( res, id, true) ) { VEFObject *obj = new VEFObject(); if (id==IE_2DA_CLASS_ID) { obj->Load2DA(res); } else { DataStream* stream = gamedata->GetResource(res, id); strnlwrcpy(obj->ResName, res, 8); obj->LoadVEF(stream); } return obj; } return NULL; }
void Inventory::AddSlotItemRes(const ieResRef ItemResRef, int SlotID, int Charge0, int Charge1, int Charge2) { CREItem *TmpItem = new CREItem(); strnlwrcpy(TmpItem->ItemResRef, ItemResRef, 8); TmpItem->Expired=0; TmpItem->Usages[0]=(ieWord) Charge0; TmpItem->Usages[1]=(ieWord) Charge1; TmpItem->Usages[2]=(ieWord) Charge2; TmpItem->Flags=0; if (core->ResolveRandomItem(TmpItem) && gamedata->Exists(TmpItem->ItemResRef, IE_ITM_CLASS_ID)) { AddSlotItem( TmpItem, SlotID ); } else { delete TmpItem; } CalculateWeight(); }
VEFObject::VEFObject(ScriptedAnimation *sca) { XPos=sca->XPos; YPos=sca->YPos; ZPos=sca->ZPos; //sometimes this is not an actual ZPos - PST portals, don't use it for rendering? strnlwrcpy(ResName, sca->ResName, 8); SingleObject=true; ScheduleEntry entry; entry.start = core->GetGame()->GameTime; if (sca->Duration==0xffffffff) entry.length = 0xffffffff; else entry.length = sca->Duration+entry.start; entry.offset = Point(0,0); entry.type = VEF_VVC; entry.ptr = sca; memcpy(entry.resourceName, sca->ResName, sizeof(ieResRef) ); entries.push_back(entry); }
void TextArea::RefreshSprite(const char *portrait) { if (AnimPicture) { if (!strnicmp(PortraitResRef, portrait, 8) ) { return; } SetAnimPicture(NULL); } strnlwrcpy(PortraitResRef, portrait, 8); if (!strnicmp(PortraitResRef, "none", 8) ) { return; } ResourceHolder<ImageMgr> im(PortraitResRef); if (im == NULL) { return; } SetAnimPicture ( im->GetSprite2D() ); }
//if the default setup doesn't fit for an animation //create a vvc for it! ScriptedAnimation* GameData::GetScriptedAnimation( const char *effect, bool doublehint) { ScriptedAnimation *ret = NULL; if (Exists( effect, IE_VVC_CLASS_ID, true ) ) { DataStream *ds = GetResource( effect, IE_VVC_CLASS_ID ); ret = new ScriptedAnimation(ds); } else { AnimationFactory *af = (AnimationFactory *) GetFactoryResource( effect, IE_BAM_CLASS_ID, IE_NORMAL ); if (af) { ret = new ScriptedAnimation(); ret->LoadAnimationFactory( af, doublehint?2:0); } } if (ret) { strnlwrcpy(ret->ResName, effect, 8); } return ret; }
void Inventory::SetSlotItemRes(const ieResRef ItemResRef, int SlotID, int Charge0, int Charge1, int Charge2) { if(ItemResRef[0]) { CREItem *TmpItem = new CREItem(); strnlwrcpy(TmpItem->ItemResRef, ItemResRef, 8); TmpItem->Expired=0; TmpItem->Usages[0]=(ieWord) Charge0; TmpItem->Usages[1]=(ieWord) Charge1; TmpItem->Usages[2]=(ieWord) Charge2; TmpItem->Flags=0; if (core->ResolveRandomItem(TmpItem) && gamedata->Exists(TmpItem->ItemResRef, IE_ITM_CLASS_ID)) { SetSlotItem( TmpItem, SlotID ); } else { delete TmpItem; } } else { //if the item isn't creatable, we still destroy the old item KillSlot( SlotID ); } CalculateWeight(); }
DataStream* KEYImporter::GetStream(const char *resname, ieWord type) { if (type == 0) return NULL; const ieDword *ResLocator = resources.get(resname, type); if (!ResLocator) return 0; unsigned int bifnum = ( *ResLocator & 0xFFF00000 ) >> 20; if (core->GameOnCD && (biffiles[bifnum].cd != 0)) FindBIFOnCD(&biffiles[bifnum]); if (!biffiles[bifnum].found) { print( "Cannot find %s... Resource unavailable.\n", biffiles[bifnum].name ); return NULL; } // simple one-BIF cache to avoid opening the same BIF repeatedly if (lastSeenCache.bifnum != bifnum) { PluginHolder<ArchiveImporter> ai(IE_BIF_CLASS_ID); if (ai->OpenArchive( biffiles[bifnum].path ) == GEM_ERROR) { print("Cannot open archive %s\n", biffiles[bifnum].path ); return NULL; } lastSeenCache.bifnum = bifnum; lastSeenCache.plugin = ai; } DataStream* ret = lastSeenCache.plugin->GetStream( *ResLocator, type ); if (ret) { strnlwrcpy( ret->filename, resname, 8 ); strcat( ret->filename, "." ); strcat( ret->filename, core->TypeExt( type ) ); return ret; } return NULL; }
VEFObject* GameData::GetVEFObject(const char *effect, bool doublehint) { VEFObject *ret = NULL; if (Exists( effect, IE_VEF_CLASS_ID, true ) ) { DataStream *ds = GetResource( effect, IE_VEF_CLASS_ID ); ret = new VEFObject(); strnlwrcpy(ret->ResName, effect, 8); ret->LoadVEF(ds); } else { if (Exists( effect, IE_2DA_CLASS_ID, true ) ) { ret = new VEFObject(); ret->Load2DA(effect); } else { ScriptedAnimation *sca = GetScriptedAnimation(effect, doublehint); if (sca) { ret = new VEFObject(sca); } } } return ret; }
FactoryObject::FactoryObject(const char* name, SClass_ID SuperClassID) { strnlwrcpy( ResRef, name, 8 ); this->SuperClassID = SuperClassID; }
//this is the short name (not the scripting name) void Door::SetName(const char* name) { strnlwrcpy( ID, name, 8 ); }
bool KeyMap::InitializeKeyMap(const char *inifile, const char *tablefile) { AutoTable kmtable(tablefile); if (!kmtable) { return false; } char tINIkeymap[_MAX_PATH]; PathJoin( tINIkeymap, core->GamePath, inifile, NULL ); FileStream* config = FileStream::OpenFile( tINIkeymap ); if (config == NULL) { Log(WARNING, "KeyMap", "There is no '%s' file...", inifile); return false; } char name[KEYLENGTH+1], value[_MAX_PATH + 3]; while (config->Remains()) { char line[_MAX_PATH]; if (config->ReadLine(line, _MAX_PATH) == -1) break; if ((line[0] == '#') || ( line[0] == '[' ) || ( line[0] == '\r' ) || ( line[0] == '\n' ) || ( line[0] == ';' )) { continue; } name[0] = 0; value[0] = 0; //ignore possible space after the =, sadly we cannot do the same with //spaces before it if (sscanf( line, "%[^=]= %[^\r\n]", name, value )!=2) continue; strnlwrcpy(name,name,KEYLENGTH); //remove trailing spaces (bg1 ini file contains them) char *nameend = name + strlen( name ) - 1; while (nameend >= name && strchr( " \t\r\n", *nameend )) { *nameend-- = '\0'; } //change internal spaces to underscore for(int c=0;c<KEYLENGTH;c++) if (name[c]==' ') name[c]='_'; int l = strlen(value); Function *fun; void *tmp; if (l<0 || l>1 || keymap.Lookup(value, tmp) ) { print("Ignoring key %s", value); continue; } const char *module; const char *function; const char *group; if (kmtable->GetRowIndex(name)>=0 ) { module = kmtable->QueryField(name, "MODULE"); function = kmtable->QueryField(name, "FUNCTION"); group = kmtable->QueryField(name, "GROUP"); } else { module = kmtable->QueryField("Default","MODULE"); function = kmtable->QueryField("Default","FUNCTION"); group = kmtable->QueryField("Default","GROUP"); print("Adding key %s with function %s::%s", value, module, function); } fun = new Function(module, function, atoi(group)); keymap.SetAt(value, fun); } delete config; return true; }
//unimplemented tags (* marks partially implemented, # marks not working in original either): //*check_crowd // control_var // spec_area //*death_faction //*death_team // check_by_view_port //*do_not_spawn // hold_selected_point_key // inc_spawn_point_index //*find_safest_point //#spawn_time_of_day // exit - similar to enter[spawn], this is a spawn branch type (on exiting an area?) // PST only //*auto_buddy //*detail_level void IniSpawn::ReadCreature(DataFileMgr *inifile, const char *crittername, CritterEntry &critter) const { const char *s; int ps; memset(&critter,0,sizeof(critter)); //first assume it is a simple numeric value critter.TimeOfDay = (ieDword) inifile->GetKeyAsInt(crittername,"time_of_day", 0xffffffff); //at this point critter.TimeOfDay is usually 0xffffffff s = inifile->GetKeyAsString(crittername,"time_of_day",NULL); if (s && strlen(s)>=24) { ieDword value = 0; ieDword j = 1; for(int i=0;i<24 && s[i];i++) { if (s[i]=='0' || s[i]=='o') value |= j; j<<=1; } //turn off individual bits marked by a 24 long string scheduling //example: '0000xxxxxxxxxxxxxxxx00000000' critter.TimeOfDay^=value; } if (inifile->GetKeyAsBool(crittername,"do_not_spawn",false)) { //if the do not spawn flag is true, ignore this entry return; } s = inifile->GetKeyAsString(crittername,"detail_level",NULL); if (s) { ieDword level; switch(s[0]) { case 'h': case 'H': level = 2; break; case 'm': case 'M': level = 1; break; default: level = 0; break; } //If the detail level is lower than this creature's detail level, //skip this entry, creature_count is 0, so it will be ignored at evaluation of the spawn if (level>detail_level) { return; } } //all specvars are using global, but sometimes it is explicitly given s = inifile->GetKeyAsString(crittername,"spec_var",NULL); if (s) { if ((strlen(s)>9) && s[6]==':' && s[7]==':') { strnuprcpy(critter.SpecContext, s, 6); strnlwrcpy(critter.SpecVar, s+8, 32); } else { strnuprcpy(critter.SpecContext, "GLOBAL", 6); strnlwrcpy(critter.SpecVar, s, 32); } } //add this to specvar at each spawn ps = inifile->GetKeyAsInt(crittername,"spec_var_inc", 0); critter.SpecVarInc=ps; //use this value with spec_var_operation to determine spawn ps = inifile->GetKeyAsInt(crittername,"spec_var_value",0); critter.SpecVarValue=ps; //this operation uses DiffCore s = inifile->GetKeyAsString(crittername,"spec_var_operation",""); critter.SpecVarOperator=GetDiffMode(s); //the amount of critters to spawn critter.TotalQuantity = inifile->GetKeyAsInt(crittername,"spec_qty",1); critter.SpawnCount = inifile->GetKeyAsInt(crittername,"create_qty",critter.TotalQuantity); //the creature resource(s) s = inifile->GetKeyAsString(crittername,"cre_file",NULL); if (s) { critter.creaturecount = CountElements(s,','); critter.CreFile=new ieResRef[critter.creaturecount]; GetElements(s, critter.CreFile, critter.creaturecount); } else { Log(ERROR, "IniSpawn", "Invalid spawn entry: %s", crittername); } s = inifile->GetKeyAsString(crittername,"point_select",NULL); if (s) { ps=s[0]; } else { ps=0; } s = inifile->GetKeyAsString(crittername,"spawn_point",NULL); if (s) { //expect more than one spawnpoint if (ps=='r') { //select one of the spawnpoints randomly int count = core->Roll(1,CountElements(s,']'),-1); //go to the selected spawnpoint while(count--) { while(*s++!=']') ; } } //parse the selected spawnpoint int x,y,o; if (sscanf(s,"[%d,%d:%d]", &x, &y, &o)==3) { critter.SpawnPoint.x=(short) x; critter.SpawnPoint.y=(short) y; critter.Orientation=o; } else if (sscanf(s,"[%d.%d:%d]", &x, &y, &o)==3) { critter.SpawnPoint.x=(short) x; critter.SpawnPoint.y=(short) y; critter.Orientation=o; } else if (sscanf(s,"[%d,%d]", &x, &y)==2) { critter.SpawnPoint.x=(short) x; critter.SpawnPoint.y=(short) y; critter.Orientation=core->Roll(1,16,-1); } else if (sscanf(s,"[%d.%d]", &x, &y)==2) { critter.SpawnPoint.x=(short) x; critter.SpawnPoint.y=(short) y; critter.Orientation=core->Roll(1,16,-1); } } //store or retrieve spawn point s = inifile->GetKeyAsString(crittername,"spawn_point_global", NULL); if (s) { switch (ps) { case 'e': critter.SpawnPoint.fromDword(CheckVariable(map, s+8,s)); break; default: //see save_selected_point //SetVariable(map, s+8, s, critter.SpawnPoint.asDword()); break; } } //take facing from variable s = inifile->GetKeyAsString(crittername,"spawn_facing_global", NULL); if (s) { switch (ps) { case 'e': critter.Orientation=(int) CheckVariable(map, s+8,s); break; default: //see save_selected_point //SetVariable(map, s+8, s, (ieDword) critter.Orientation); break; } } s = inifile->GetKeyAsString(crittername,"save_selected_point",NULL); if (s) { if ((strlen(s)>9) && s[6]==':' && s[7]==':') { SetVariable(map, s+8, s, critter.SpawnPoint.asDword()); } else { SetVariable(map, s, "GLOBAL", critter.SpawnPoint.asDword()); } } s = inifile->GetKeyAsString(crittername,"save_selected_facing",NULL); if (s) { if ((strlen(s)>9) && s[6]==':' && s[7]==':') { SetVariable(map, s+8, s, (ieDword) critter.Orientation); } else { SetVariable(map, s, "GLOBAL", (ieDword) critter.Orientation); } } //sometimes only the orientation is given, the point is stored in a variable ps = inifile->GetKeyAsInt(crittername,"facing",-1); if (ps!=-1) critter.Orientation = ps; ps = inifile->GetKeyAsInt(crittername, "ai_ea",-1); if (ps!=-1) critter.SetSpec[AI_EA] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_team",-1); if (ps!=-1) critter.SetSpec[AI_TEAM] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_general",-1); if (ps!=-1) critter.SetSpec[AI_GENERAL] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_race",-1); if (ps!=-1) critter.SetSpec[AI_RACE] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_class",-1); if (ps!=-1) critter.SetSpec[AI_CLASS] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_specifics",-1); if (ps!=-1) critter.SetSpec[AI_SPECIFICS] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_gender",-1); if (ps!=-1) critter.SetSpec[AI_GENDER] = (ieByte) ps; ps = inifile->GetKeyAsInt(crittername, "ai_alignment",-1); if (ps!=-1) critter.SetSpec[AI_ALIGNMENT] = (ieByte) ps; s = inifile->GetKeyAsString(crittername,"spec",NULL); if (s) { int x[9]; ps = sscanf(s,"[%d.%d.%d.%d.%d.%d.%d.%d.%d]", x, x+1, x+2, x+3, x+4, x+5, x+6, x+7, x+8); if (ps == 0) { strnuprcpy(critter.ScriptName, s, 32); critter.Flags|=CF_CHECK_NAME; memset(critter.Spec,-1,sizeof(critter.Spec)); } else { while(ps--) { critter.Spec[ps]=(ieByte) x[ps]; } } } s = inifile->GetKeyAsString(crittername,"script_name",NULL); if (s) { strnuprcpy(critter.ScriptName, s, 32); } //iwd2 script names (override remains the same) //special 1 == area s = inifile->GetKeyAsString(crittername,"script_special_1",NULL); if (s) { strnuprcpy(critter.AreaScript,s, 8); } //special 2 == class s = inifile->GetKeyAsString(crittername,"script_special_2",NULL); if (s) { strnuprcpy(critter.ClassScript,s, 8); } //special 3 == general s = inifile->GetKeyAsString(crittername,"script_special_3",NULL); if (s) { strnuprcpy(critter.GeneralScript,s, 8); } //team == specific s = inifile->GetKeyAsString(crittername,"script_team",NULL); if (s) { strnuprcpy(critter.SpecificScript,s, 8); } //combat == race s = inifile->GetKeyAsString(crittername,"script_combat",NULL); if (s) { strnuprcpy(critter.RaceScript,s, 8); } //movement == default s = inifile->GetKeyAsString(crittername,"script_movement",NULL); if (s) { strnuprcpy(critter.DefaultScript,s, 8); } //pst script names s = inifile->GetKeyAsString(crittername,"script_override",NULL); if (s) { strnuprcpy(critter.OverrideScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_class",NULL); if (s) { strnuprcpy(critter.ClassScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_race",NULL); if (s) { strnuprcpy(critter.RaceScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_general",NULL); if (s) { strnuprcpy(critter.GeneralScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_default",NULL); if (s) { strnuprcpy(critter.DefaultScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_area",NULL); if (s) { strnuprcpy(critter.AreaScript,s, 8); } s = inifile->GetKeyAsString(crittername,"script_specifics",NULL); if (s) { strnuprcpy(critter.SpecificScript,s, 8); } s = inifile->GetKeyAsString(crittername,"dialog",NULL); if (s) { strnuprcpy(critter.Dialog,s, 8); } //flags if (inifile->GetKeyAsBool(crittername,"death_scriptname",false)) { critter.Flags|=CF_DEATHVAR; } if (inifile->GetKeyAsBool(crittername,"death_faction",false)) { critter.Flags|=CF_FACTION; } if (inifile->GetKeyAsBool(crittername,"death_team",false)) { critter.Flags|=CF_TEAM; } ps = inifile->GetKeyAsInt(crittername,"good_mod",0); if (ps) { critter.Flags|=CF_GOOD; critter.DeathCounters[DC_GOOD] = ps; } ps = inifile->GetKeyAsInt(crittername,"law_mod",0); if (ps) { critter.Flags|=CF_LAW; critter.DeathCounters[DC_LAW] = ps; } ps = inifile->GetKeyAsInt(crittername,"lady_mod",0); if (ps) { critter.Flags|=CF_LADY; critter.DeathCounters[DC_LADY] = ps; } ps = inifile->GetKeyAsInt(crittername,"murder_mod",0); if (ps) { critter.Flags|=CF_MURDER; critter.DeathCounters[DC_MURDER] = ps; } if(inifile->GetKeyAsBool(crittername,"auto_buddy", false)) { critter.Flags|=CF_BUDDY; } //don't spawn when spawnpoint is visible if (inifile->GetKeyAsBool(crittername,"ignore_can_see",false)) { critter.Flags|=CF_IGNORECANSEE; } //unsure, but could be similar to previous if (inifile->GetKeyAsBool(crittername,"check_view_port", false)) { critter.Flags|=CF_CHECKVIEWPORT; } //unknown, this is used only in pst if (inifile->GetKeyAsBool(crittername,"check_crowd", false)) { critter.Flags|=CF_CHECKCROWD; } //unknown, this is used only in pst if (inifile->GetKeyAsBool(crittername,"find_safest_point", false)) { critter.Flags|=CF_SAFESTPOINT; } //disable spawn based on game difficulty if (inifile->GetKeyAsBool(crittername,"area_diff_1", false)) { critter.Flags|=CF_NO_DIFF_1; } if (inifile->GetKeyAsBool(crittername,"area_diff_2", false)) { critter.Flags|=CF_NO_DIFF_2; } if (inifile->GetKeyAsBool(crittername,"area_diff_3", false)) { critter.Flags|=CF_NO_DIFF_3; } }
void IniSpawn::InitSpawn(const ieResRef DefaultArea) { const char *s; Holder<DataFileMgr> inifile = GetIniFile(DefaultArea); if (!inifile) { strnuprcpy(NamelessSpawnArea, DefaultArea, 8); return; } s = inifile->GetKeyAsString("nameless","destare",DefaultArea); strnuprcpy(NamelessSpawnArea, s, 8); s = inifile->GetKeyAsString("nameless","point","[0.0]"); int x,y; if (sscanf(s,"[%d.%d]", &x, &y)!=2) { x=0; y=0; } NamelessSpawnPoint.x=x; NamelessSpawnPoint.y=y; s = inifile->GetKeyAsString("nameless", "partyarea", DefaultArea); strnuprcpy(PartySpawnArea, s, 8); s = inifile->GetKeyAsString("nameless", "partypoint", "[0.0]"); if (sscanf(s,"[%d.%d]", &x, &y) != 2) { x = NamelessSpawnPoint.x; y = NamelessSpawnPoint.y; } PartySpawnPoint.x = x; PartySpawnPoint.y = y; //35 - already standing //36 - getting up NamelessState = inifile->GetKeyAsInt("nameless","state",36); namelessvarcount = inifile->GetKeysCount("namelessvar"); if (namelessvarcount) { NamelessVar = new VariableSpec[namelessvarcount]; for (y=0;y<namelessvarcount;y++) { const char* Key = inifile->GetKeyNameByIndex("namelessvar",y); strnlwrcpy(NamelessVar[y].Name, Key, 32); NamelessVar[y].Value = inifile->GetKeyAsInt("namelessvar",Key,0); } } localscount = inifile->GetKeysCount("locals"); if (localscount) { Locals = new VariableSpec[localscount]; for (y=0;y<localscount;y++) { const char* Key = inifile->GetKeyNameByIndex("locals",y); strnlwrcpy(Locals[y].Name, Key, 32); Locals[y].Value = inifile->GetKeyAsInt("locals",Key,0); } } s = inifile->GetKeyAsString("spawn_main","enter",NULL); if (s) { ReadSpawnEntry(inifile.get(), s, enterspawn); } s = inifile->GetKeyAsString("spawn_main","exit",NULL); if (s) { ReadSpawnEntry(inifile.get(), s, exitspawn); } s = inifile->GetKeyAsString("spawn_main","events",NULL); if (s) { eventcount = CountElements(s,','); eventspawns = new SpawnEntry[eventcount]; ieVariable *events = new ieVariable[eventcount]; GetElements(s, events, eventcount); int ec = eventcount; while(ec--) { ReadSpawnEntry(inifile.get(), events[ec], eventspawns[ec]); } delete[] events; } //maybe not correct InitialSpawn(); }