Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
void Game::SetMasterArea(const char *area)
{
	if (MasterArea(area) ) return;
	char *tmp = (char *) malloc(9);
	strnlwrcpy (tmp,area,8);
	mastarea.push_back(tmp);
}
Ejemplo n.º 4
0
/** 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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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);
	}
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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;
	}
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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
}
Ejemplo n.º 13
0
//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;
}
Ejemplo n.º 14
0
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 );
	}
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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();
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
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() );
}
Ejemplo n.º 19
0
//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;
}
Ejemplo n.º 20
0
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();
}
Ejemplo n.º 21
0
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;
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
FactoryObject::FactoryObject(const char* name, SClass_ID SuperClassID)
{
	strnlwrcpy( ResRef, name, 8 );
	this->SuperClassID = SuperClassID;
}
Ejemplo n.º 24
0
//this is the short name (not the scripting name)
void Door::SetName(const char* name)
{
	strnlwrcpy( ID, name, 8 );
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
//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;
	}
}
Ejemplo n.º 27
0
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();
}