예제 #1
0
void CWorld::ScanCell()
{
	auto player = DYNAMIC_CAST( LookupFormByID(0x14), TESForm, TESObjectREFR );
	if(!player) goto FAILED;
	auto cell = player->parentCell;
	if(!cell) goto FAILED;
	
	m_pWorld->markForWrite();
	if(m_pCell != cell)
	{
		LogInfo("Cell changed...");
		m_characters.clear();
		m_pCell = cell;

		for(auto& i : m_systems)
		{
			i.second->RemoveFromWorld();
			i.second->AddToWorld(m_pWorld);
		}
	}
	else
	{
		for(auto i=m_characters.begin(); i!=m_characters.end();)
		{
			auto form = i->first;
			auto object = (TESObjectREFR*)LookupFormByID(form);
			if(object->parentCell != cell)
			{
				LogInfo("%08x no longer in cell, release it", form);
				m_characters.erase(i++);
			}
			else if(!i->second->CreateIfValid())
			{
				LogInfo("%08x now invalid, release it", form);
				m_characters.erase(i++);
			}
			else (i++)->second->AddToWorld(m_pWorld);
		}

		for(int i=0; i<cell->objectList.count; ++i)
		{
			auto object = cell->objectList.arr.entries[i];
			if(DYNAMIC_CAST(object, TESObjectREFR, Actor))
				AddCharacter(object->formID);
		}
	}

	m_pWorld->unmarkForWrite();
	return;

FAILED:
	
	m_pWorld->markForWrite();
	m_characters.clear();
	m_pCell = 0;
	m_pWorld->unmarkForWrite();
}
예제 #2
0
TESForm* ScriptToken::GetTESForm() const
{
	// ###TODO: handle Ref (RefVariable)? Read() turns RefVariable into Form so that type is compile-time only
#if OBLIVION
	if (type == kTokenType_Form)
		return LookupFormByID(value.formID);
	else if (type == kTokenType_RefVar && value.var)
		return LookupFormByID(*((UInt64*)(&value.var->data)));
#endif

	if (type == kTokenType_Ref && value.refVar)
		return value.refVar->form;
	else
		return NULL;
}
예제 #3
0
EventResult TESEquipEventHandler::ReceiveEvent(TESEquipEvent* evn, EventDispatcher<TESEquipEvent>* dispatcher)
{
	if (evn->actor->baseForm != (*g_thePlayer)->baseForm)
		return kEvent_Continue;

	TESForm* equippedForm = LookupFormByID(evn->equippedFormID);

	EnchantmentItem* enchantment = DYNAMIC_CAST(equippedForm, TESForm, EnchantmentItem);

	if (!enchantment) //check active effects to see if an armor enchantment was equipped
	{
		if (evn->isEquipping)
			g_activeEnchantEffects.ProcessEquipped(); //find new equipped enchanted item and send event to papyrus
		else //unequipping
			g_activeEnchantEffects.ProcessUnequipped(); //find removed enchanted item and send event to papyrus
	}

	else if (enchantment->data.unk14 != 0x0C) //weapon enchantment equipped (but ignore staff enchantments for now)
	{
		if (evn->isEquipping)
			playerEquippedWeaponEnchantments.Push(evn->equippedFormID);
		else
			playerEquippedWeaponEnchantments.Pop(evn->equippedFormID);

		g_userExclusions.UpdateWeaponExclusions();

		g_hitEventExDispatcher->RemoveEventSink(&g_hitEventExHandler);
		if (playerEquippedWeaponEnchantments.HasData())
			g_hitEventExDispatcher->AddEventSink(&g_hitEventExHandler);
	}

	return kEvent_Continue;
}
예제 #4
0
void EditorHookWindow::OnButtonHit(void)
{
	char	text[256];
	GetWindowText(m_editText, text, sizeof(text));

	char	comment[256];
	GetWindowText(m_editText2, comment, sizeof(comment));

	UInt32	id;
	if(sscanf_s(text, "%x", &id) == 1)
	{
		void	* ptr = LookupFormByID(id);
		
		sprintf_s(text, sizeof(text), "%08X = %08X (%s)", id, (UInt32)ptr, GetObjectClassName(ptr));
		_MESSAGE("%s", text);

		MessageBox(m_window, text, "receive bacon", MB_OK);

		static int idx = 0;
		char	fileName[256];
		if(comment[0])
			sprintf_s(fileName, sizeof(fileName), "mem%08X_%08X_%08X_%s", idx, id, (UInt32)ptr, comment);
		else
			sprintf_s(fileName, sizeof(fileName), "mem%08X_%08X_%08X", idx, id, (UInt32)ptr);
		idx++;

		IFileStream	dst;
		if(dst.Create(fileName))
			dst.WriteBuf(ptr, 0x200);
	}
	else
	{
		MessageBox(m_window, "couldn't read text box", "receive bacon", MB_OK);
	}
};
예제 #5
0
		//now we process each cell...
		BOOST_FOREACH(TESObjectCELL *Cell,cells)
		{
			TESObjectCELL::ObjectListEntry * ListIterator = &Cell->objectList;		

			while(ListIterator) // Iterate the entities
			{
				if(IsRefIDIgnore(ListIterator->refr->refID)) // Do not synchronize objects used by OblivionOnline
				{
					ent = (ClientEntity *) gClient->GetEntities()->GetOrCreateEntity(ListIterator->refr->refID);
					if(GetIsMasterClient())
						SendActorPosition(ListIterator->refr,ent);					
					if(ListIterator->Info()->IsActor())
					{
						Actor * actor = (Actor *)LookupFormByID(ListIterator->refr->refID);
						{
							if(GetIsMasterClient())
							{
								SendActorValues(actor,ent);
								SendActorEquip(actor,ent);
								SendActorAnimation(actor,ent);		
							}
							SendActorValueMod(actor,ent);
						}				
					}
				}
				ListIterator = ListIterator->next;
			}
		}
예제 #6
0
__declspec(dllexport) bool GetScriptDataForForm(bool* OperationResult, UInt32 FormID, Script** ResultScript, ScriptEventList** ResultEventList)
{
	bool Result = false;

	if (FormID)
	{
		TESForm* Form = LookupFormByID(FormID);
		if (Form)
		{
			TESQuest* Quest = OBLIVION_CAST(Form, TESForm, TESQuest);
			TESObjectREFR* Ref = OBLIVION_CAST(Form, TESForm, TESObjectREFR);

			if (Quest)
			{
				*ResultScript = Quest->scriptable.script;
				*ResultEventList = Quest->scriptEventList;
				Result = true;
			}
			else if (Ref)
			{
				BSExtraData* xData = Ref->baseExtraList.GetByType(kExtraData_Script);
				if (xData)
				{
					ExtraScript* xScript = OBLIVION_CAST(xData, BSExtraData, ExtraScript);
					*ResultScript = xScript->script;
					*ResultEventList = xScript->eventList;
					Result = true;
				}
			}
		}
	}

	*OperationResult = Result;
	return Result;
}
예제 #7
0
TESObjectREFR * GetRefrFromEntity( ClientEntity * ent )
{
    if(ent->RefID() == gClient->GetLocalPlayer())
        return (TESObjectREFR * )(*g_thePlayer);
    else
        return (TESObjectREFR * )LookupFormByID(ent->RefID());
}
예제 #8
0
WorldSpace::WorldSpace(Location location) {
  if (location.has_world_space()) {
    auto world_space_form = LookupFormByID(location.world_space_id());
    if (world_space_form->GetFormType() == kFormType_WorldSpace) {
      world_space_ = static_cast<TESWorldSpace*>(world_space_form);
    }
  }
}
예제 #9
0
TESForm* TESHitEvent::GetProjectileForm()
{
	if (projectileFormID)
		return LookupFormByID(projectileFormID);

	TESObjectREFR* ref = GetProjectileRef();
	return (ref) ? ref->baseForm : NULL;
}
예제 #10
0
Cell::Cell(Location location) {
  if (location.has_cell()) {
    auto cell_form = LookupFormByID(location.cell_id());
    if(cell_form->GetFormType() == kFormType_Cell) {
      cell_ = static_cast<TESObjectCELL*>(cell_form);
    }
  }
}
예제 #11
0
void ActionHandler::actionSetActiveQuest(UInt32 refID)
{
	TESQuest *quest = DYNAMIC_CAST(LookupFormByID(refID), TESForm, TESQuest);
	if (quest == NULL) {
		return;
	}
	sprintf_s(commandBuf, "ForceActiveQuest %x", quest->refID);
	Script::RunScriptLine(commandBuf);
}
예제 #12
0
void ActionHandler::actionTuneRadio(UInt32 refID)
{
	sprintf_s(commandBuf, "pipboyRadio off");
	Script::RunScriptLine(commandBuf);
	if (refID != 0) {
		TESObjectREFR *radio = DYNAMIC_CAST(LookupFormByID(refID), TESForm, TESObjectREFR);
		if (radio == NULL)
			return;
		sprintf_s(commandBuf, "pipboyRadio on %x", radio->refID);
		Script::RunScriptLine(commandBuf);
	}
}
예제 #13
0
TESForm * AddItemHealthPercentOwner(TESObjectREFR* thisObj, UInt32 refID, SInt32 NumItems, float Health, TESForm* pOwner, UInt32 Rank)
{
	if (!thisObj) return NULL;

	TESForm * pForm = LookupFormByID(refID);
	if (!pForm) return NULL;
	TESHealthForm* pHealth = DYNAMIC_CAST(pForm, TESForm, TESHealthForm);
	if (!pHealth && (Health != -1.0)) {
		_MESSAGE("\t\tInventoryInfo\t\tAddItemHealthPercentOwner:\tInvalid refID:%#10X, no health attribute", thisObj->refID);
		return NULL;
	}
	TESScriptableForm* pScript = DYNAMIC_CAST(pForm, TESForm, TESScriptableForm);
	if (pScript && !pScript->script) pScript = NULL;  // Only existing scripts matter

	ExtraHealth* pXHealth = NULL;
	ExtraOwnership* pXOwner = NULL;
	ExtraRank* pXRank = NULL;
	ExtraCount* pXCount = NULL;
	ExtraDataList* pExtraDataList = NULL;
	ExtraScript * pXScript = NULL;

	if (!(1.0 == Health) || pOwner || Rank || pScript) {
		pExtraDataList = ExtraDataList::Create();
		if (!(1.0 == Health)) {
			pXHealth = ExtraHealth::Create();
			if (!pExtraDataList->Add(pXHealth))
				FormHeap_Free(pXHealth);
			else
				pXHealth->health = pHealth->GetHealth() * Health;
		}
		if (pOwner) {
			pXOwner = ExtraOwnership::Create();
			if (!pExtraDataList->Add(pXOwner))
				FormHeap_Free(pXOwner);
			else
				pXOwner->owner = pOwner;
		}
		if (Rank) {
			pXRank = ExtraRank::Create();
			if (!pExtraDataList->Add(pXRank))
				FormHeap_Free(pXRank);
			else
				pXRank->rank = Rank;
		}
		if (pScript) {
			pXScript = ExtraScript::Create(pForm, true);
			if (!pExtraDataList->Add(pXScript))
				FormHeap_Free(pXScript);
		}
	}
	thisObj->AddItem(pForm, pExtraDataList, NumItems);
	return pForm;
}
예제 #14
0
파일: GameForms.cpp 프로젝트: ashmedai/NVSE
void Script::RefVariable::Resolve(ScriptEventList * eventList)
{
	if(varIdx && eventList)
	{
		ScriptEventList::Var	* var = eventList->GetVariable(varIdx);
		if(var)
		{
			UInt32	refID = *((UInt32 *)&var->data);
			form = LookupFormByID(refID);
		}
	}
}
TESForm* GetJCStringForm(std::string formString)
{
	TESForm * result = nullptr;

	std::vector<std::string> stringData;

	std::string formData("__formData");

	std::istringstream str(formString);

	std::string token;
	while (std::getline(str, token, '|')) {
		//std::cout << token << std::endl;
		stringData.push_back(token);
	}

	if (stringData[0] != formData)
		return result;

	if (!stringData[2].length())
		return result;

	UInt8 modIndex = 0xff;

	if (stringData[1].length()) {
		DataHandler* pDataHandler = DataHandler::GetSingleton();
		modIndex = pDataHandler->GetModIndex(stringData[1].c_str());
	}

	if (modIndex == 0xff)
		return result;

	std::string formIdString(stringData[2].c_str());

	UInt32 formId;

	try {
		formId = std::stoul(std::string(formIdString.begin(), formIdString.end()), nullptr, 0);
	}
	catch (const std::invalid_argument&) {
		return result;
	}
	catch (const std::out_of_range&) {
		return result;
	}

	formId |= modIndex << 24;
	result = LookupFormByID(formId);
	return result;
}
예제 #16
0
void UpdateItem3D(const FxDelegateArgs & params)
{
	if(params.menu) {
		UInt32 formId = (UInt32)params.args->GetNumber();
		if(formId) {
			TESForm * form = LookupFormByID(formId);
			if(form) {
				CALL_MEMBER_FN(Inventory3DManager::GetSingleton(), UpdateMagic3D)(form, 0);
			}
		} else {
			CALL_MEMBER_FN(Inventory3DManager::GetSingleton(), Clear3D)();
		}
	}
}
bool AddOneItemCommand(Actor *thisObj,UINT32 FormID)
{
	TESObjectREFR *refr = (TESObjectREFR * )LookupFormByID(FormID);
	if(!refr || !thisObj)
		return false;
	//TODO: Is Inventory Item?
	//TODO: rework this
	double result;
	TESObjectREFR * arg1[2] = 
	{
		refr,
		(TESObjectREFR *) 1
	}; 
	// Parameter list, parameters, thisOBj, arg3= param count, ScriptEventList ( what to put in there?) , Result ptr, and offset ( is 0 ok ? ) 
	CallCmdExecuteGeneric(Cmd_AddItem_Execute,kParams_CmdAddItem,&arg1, 1,thisObj,&result); // NULL denotes incomplete params
}
예제 #18
0
UInt32 ProcessLoadEntry(SKSESerializationInterface* intfc)
{
	EnchantmentInfoEntry thisEntry;
	UInt32 sizeRead = intfc->ReadRecordData(&thisEntry, sizeof(EnchantmentInfoEntry));
	if (sizeRead == sizeof(EnchantmentInfoEntry))
	{
		EnchantmentItem* thisEnchant = DYNAMIC_CAST(LookupFormByID(thisEntry.formID), TESForm, EnchantmentItem);
		if (!thisEnchant)
			return 0;

		thisEnchant->data.unk00.unk04 |= thisEntry.flags; //Set to manualCalc and correct cost
		thisEnchant->data.unk00.unk00 = thisEntry.enchantmentCost;
		
		//This ended up causing a crash on subsequent loads, most likely because the game rebuilds the condition table.
		//I could probably work around it by detaching all conditions during Revert, and then letting the Load process
		//re-attach them. But I'm just going to disable them for now to be safe, it's relatively unimportant.

		// if (thisEntry.cData.hasConditions) //Update enchantment conditions
		// {
		// 	EnchantmentItem* parentEnchant = DYNAMIC_CAST(LookupFormByID(thisEntry.cData.parentFormID), TESForm, EnchantmentItem);
		// 	if (parentEnchant)
		// 	{
		// 		for (UInt32 i = 0; (i < parentEnchant->effectItemList.count) && (i < thisEnchant->effectItemList.count); ++i)
		// 		{
		// 			MagicItem::EffectItem* parentEffect = NULL;
		// 			parentEnchant->effectItemList.GetNthItem(i, parentEffect);
		// 			if (parentEffect && parentEffect->condition)
		// 			{
		// 				MagicItem::EffectItem* childEffect = NULL;
		// 				thisEnchant->effectItemList.GetNthItem(i, childEffect);
		// 				childEffect->condition = parentEffect->condition;
		// 			}
		// 		}
		// 	}
		// }

		enchantTracker[thisEnchant] = thisEntry; //Add to main tracker
		return 1;
	}
	else
	{
		_MESSAGE("Error Reading From Cosave: INVALID CHUNK SIZE (%u Expected %u)"
		" -- Data Entry Will Be Skipped.", sizeRead, sizeof(EnchantmentInfoEntry));
		return 0;
	}
}
bool EquipItemCommand(Actor *thisObj,UINT32 FormID)
{
	TESObjectREFR *refr = (TESObjectREFR * ) LookupFormByID(FormID);
	if(!refr || !thisObj)
		return false;
	//TODO: Is Inventory Item?
	//TODO: rework this
	double result;
	// Call AddItem: 1 Pointer to the form
	TESForm * arg1 [2]= {
		refr,
		(TESObjectREFR *)0
	}; // Set parameter 1 ( Object) 
	// Parameter list, parameters, thisOBj, arg3= param count, ScriptEventList ( what to put in there?) , Result ptr, and offset ( is 0 ok ? ) 
	CallCmdExecuteGeneric(Cmd_EquipItem_Execute,kParams_CmdEquipItem,&arg1,2,thisObj,&result);
	return true;
}
예제 #20
0
bool InjectEquip( ClientEntity *ent,BYTE slot,UINT32 formid )
{
    return true;
    if(!ent)
        return false;
    TESObjectREFR * refr = GetRefrFromEntity(ent);
    if(!refr || !refr->IsActor())
        return false;
    else
    {
        Actor * act= (Actor*)refr;
        if(formid && LookupFormByID(formid))
        {
            feGetObject getObject;
            double itemResult;
            UInt32* itemRef = (UInt32 *)&itemResult;
            if (FindEquipped(act, slot, &getObject, &itemResult)  ) // If we find nothing, there already is no equip
            {
                ent->AddUnequipItem(*itemRef);
                ent->AddRemoveItem(*itemRef);
                //UnEquipItemCommand(act,*itemRef);
                //RemoveOneItemQueue.push(pair<Actor *,UINT32>(act,*itemRef));
            }
            //AddOneItemCommand(act,formid);
            ent->AddAddItem(formid);
            //ent->AddEquipItem(formid);
        }
        else
        {
            //Unequip the item in that slot.
            feGetObject getObject;
            double itemResult;
            UInt32* itemRef = (UInt32 *)&itemResult;
            if (FindEquipped(act, slot, &getObject, &itemResult)  ) // If we find nothing, there already is no equip
            {
                ent->AddUnequipItem(*itemRef);
                //ent->AddRemoveItem(*itemRef);
                //UnEquipItemCommand(act,*itemRef);
                //RemoveOneItemQueue.push(pair<Actor *,UINT32>(act,*itemRef));
            }
        }
        SafeAddUpdateQueue(ent);

    }
    return true;
}
예제 #21
0
bool GameClient::RunFrame()
{
	ClientEntity * ent;  
	Actor  * actor = NULL;
	BYTE Status;
	if(!gClient->GetIsConnected())
		return false;
	//Check if Menu Mode:

	InterfaceManager* intfc = InterfaceManager::GetSingleton();
	if(!intfc->IsGameMode())
		g_bRenderGUI = false;
	else
		g_bRenderGUI = true;

	if(!gClient->GetIsInitialized() )
	{
		gClient->GetConnection().Process();//Poll connection until a player id is received
		return true;
	}
	// A heavy command xD
	// 1 - send local player data up .
	// 2 - send health magicka and fatigue  + equip up.
	// if MC :
	// 2 - send up position , stat equip , etc of NPCs
	//(*g_thePlayer) is ignored
	ent = (ClientEntity *)gClient->GetEntities()->GetOrCreateEntity(gClient->GetLocalPlayer());
	//gClient->GetServerStream()->Send(); // Prevent Lag
	SendActorPosition(*g_thePlayer,ent);
	SendActorValues(*g_thePlayer,ent);
	SendActorEquip(*g_thePlayer,ent);
	SendActorAnimation(*g_thePlayer,ent);
		//Find all cells any "ignored objects" are in. these are mostly players.
		std::set<TESObjectCELL *> cells;
		cells.insert((*g_thePlayer)->parentCell);
		BOOST_FOREACH(UINT32 i,ignore)
		{
			TESObjectREFR *form = (TESObjectREFR *)LookupFormByID(i);
			if(!form)
				continue;
			if(!form->parentCell) continue;

			if(cells.find(form->parentCell)  == cells.end())//Not present
				cells.insert(form->parentCell);
		}
예제 #22
0
EnchantmentItem* TESHitEvent::GetMagicHitEnchantment()
{
	//enchantment hit will have either weapon or enchantment as sourceForm (for melee & bow attacks, respectively)
	TESForm* src = LookupFormByID(sourceFormID);
	EnchantmentItem* enchantment = DYNAMIC_CAST(src, TESForm, EnchantmentItem);
	if (!enchantment)
		if (src->formType == TESObjectWEAP::kTypeID)
			if (ActorMagicCaster* magicHitData = GetMagicHitData())
			{
				enchantment = DYNAMIC_CAST(magicHitData->magicItem, MagicItem, EnchantmentItem);
				if (!enchantment)
					enchantment = ExtraEnchantmentInfo::GetActorSourceEnchantment(*g_thePlayer, GetMagicHitSource());
					//This last part may not be necessary. In testing, as long as there was ActorMagicCaster data, I was
					//always able to retrieve the enchantment without checking actor's source equipData. Added just in case.
			}

	return enchantment;
}
예제 #23
0
void FormChangesMap::Load(OBSESerializationInterface* intfc)
{
	UInt32 recType, recVersion, recLength, formID, nuFormID;
	UInt16 changeType;
	TESForm* curForm = NULL;

	Clear();

	_MESSAGE("Loading form changes");
	bool bContinue = true;
	bool bSkipCurrentRecord = false;
	while (bContinue && intfc->GetNextRecordInfo(&recType, &recVersion, &recLength))
	{
		switch (recType)
		{
		case 'FMCE':			//end of data
			bContinue = false;
			break;
		case 'FMCR':			//new form
			bSkipCurrentRecord = false;
			intfc->ReadRecordData(&formID, sizeof(formID));
			bSkipCurrentRecord = !intfc->ResolveRefID(formID, &nuFormID);	//if can't resolve refID, skip changes

			curForm = LookupFormByID(nuFormID);
			if (!curForm)							//probably non-persistent reference; skip
				bSkipCurrentRecord = true;
			
			break;
		case 'FMCH':			//change entry for current form
			if (!bSkipCurrentRecord)
			{
				intfc->ReadRecordData(&changeType, sizeof(changeType));
				FormChangeInfo info(changeType, curForm, NULL);
				FormChangeEntry* changeEntry = FormChangeEntry::Create(info);
				if (changeEntry->Load(intfc))
					changes.insert(ChangeMapValue(curForm->refID, changeEntry));
			}
			break;
		default:
			_MESSAGE("Error loading form changes: unhandled chunk type %d", recType);
		}
	}
}
예제 #24
0
void VisitFormList(BGSListForm * formList, std::function<void(TESForm*)> functor)
{
	for (int i = 0; i < formList->forms.count; i++)
	{
		TESForm* childForm = NULL;
		if (formList->forms.GetNthItem(i, childForm))
			functor(childForm);
	}

	// Script Added Forms
	if (formList->addedForms) {
		for (int i = 0; i < formList->addedForms->count; i++) {
			UInt32 formid = 0;
			formList->addedForms->GetNthItem(i, formid);
			TESForm* childForm = LookupFormByID(formid);
			if (childForm)
				functor(childForm);
		}
	}
}
예제 #25
0
void ActionHandler::actionFastTravel(UInt32 refID)
{
	PlayerCharacter *player = PlayerCharacter::GetSingleton();
	TESObjectREFR *marker = (TESObjectREFR *)LookupFormByID(refID);
	if (marker == NULL) return;
	ExtraMapMarker *markerData = (ExtraMapMarker *)
		marker->extraDataList.GetByType(kExtraData_MapMarker);
	if (markerData == NULL || !markerData->CanTravel()) return;
	_MESSAGE("Flags %08x, %08x, %08x", player->unk650[6], player->unk650[7], player->unk650[8]);
	if (player->unk650[7] & 0x100 && !player->parentCell->IsInterior()) {
		_VMESSAGE("Fast travel");
		ExtraReferencePointer *ftp = (ExtraReferencePointer *)
			marker->extraDataList.GetByType(kExtraData_LinkedRef);
		if (ftp == NULL || ftp->refr == NULL) {
			_ERROR("Fast travel heading not found");
		}
		sprintf_s(commandBuf, "player.moveto %x 0 0 0", ftp->refr->refID);
		Script::RunScriptLine(commandBuf);
	}
	
}
void VisitFormListRecursive(BGSListForm * formList, std::function<void(TESForm*)> functor, UInt8 recurseMax = 3)
{
	if (recurseMax <= 0) {
		_WARNING("%s: Too many recursions, aborting!", __FUNCTION__);
		return;
	}
	_MESSAGE("%s: Checking formlist %08x, recursion %d of 3...", __FUNCTION__, formList->formID, 3 - recurseMax);
	for (int i = 0; i < formList->forms.count; i++)
	{
		TESForm* childForm = NULL;
		if (formList->forms.GetNthItem(i, childForm))
		{
			BGSListForm* childList = NULL;
			childList = DYNAMIC_CAST(childForm, TESForm, BGSListForm);
			if (childList) {
				_MESSAGE("%s: Recursing into formlist %08x...", __FUNCTION__, formList->formID);
				VisitFormListRecursive(childList, functor, recurseMax - 1);
			} else
				functor(childForm);
		}
	}

	// Script Added Forms
	if (formList->addedForms) {
		for (int i = 0; i < formList->addedForms->count; i++) {
			UInt32 formid = 0;
			formList->addedForms->GetNthItem(i, formid);
			TESForm* childForm = LookupFormByID(formid);
			if (childForm) {
				BGSListForm* childList = NULL;
				childList = DYNAMIC_CAST(childForm, TESForm, BGSListForm);
				if (childList) {
					VisitFormListRecursive(formList, functor, recurseMax - 1);
				}
				else
					functor(childForm);
			}
		}
	}
}
예제 #27
0
void SKSETaskRefreshTintMask::Run()
{
	TESForm * form = LookupFormByID(m_formId);
	Actor * actor = DYNAMIC_CAST(form, TESForm, Actor);
	if (!actor)
		return;

	NiTriBasedGeom * geometry = GetHeadTriBasedGeom(actor, BGSHeadPart::kTypeFace);
	if (geometry) {
		BSShaderProperty * shaderProperty = niptr_cast<BSShaderProperty>(geometry->m_spEffectState);
		if (shaderProperty) {
			if (shaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
				BSLightingShaderProperty * lightingShader = static_cast<BSLightingShaderProperty *>(shaderProperty);
				BSLightingShaderMaterial * material = static_cast<BSLightingShaderMaterial *>(shaderProperty->material);
				if (material) {
					material->textureSet->SetTexturePath(6, m_ddsPath.data);
					material->ReleaseTextures();
					CALL_MEMBER_FN(lightingShader, InvalidateTextures)(0);
					CALL_MEMBER_FN(lightingShader, InitializeShader)(geometry);
				}
			}
		}
	}
}
예제 #28
0
void SKSETaskExportHead::Run()
{
	if (!m_formId)
		return;

	TESForm * form = LookupFormByID(m_formId);
	Actor * actor = DYNAMIC_CAST(form, TESForm, Actor);
	if (!actor)
		return;

	BSFaceGenNiNode * faceNode = actor->GetFaceGenNiNode();
	TESNPC * actorBase = DYNAMIC_CAST(actor->baseForm, TESForm, TESNPC);
	if (!actorBase || !faceNode)
		return;

	BSFaceGenAnimationData * animationData = actor->GetFaceGenAnimationData();
	if (animationData) {
		FaceGen::GetSingleton()->isReset = 0;
		for (UInt32 t = BSFaceGenAnimationData::kKeyframeType_Expression; t <= BSFaceGenAnimationData::kKeyframeType_Phoneme; t++)
		{
			BSFaceGenKeyframeMultiple * keyframe = &animationData->keyFrames[t];
			for (UInt32 i = 0; i < keyframe->count; i++)
				keyframe->values[i] = 0.0;
			keyframe->isUpdated = 0;
		}
		UpdateModelFace(faceNode);
	}

	IFileStream::MakeAllDirs(m_nifPath.data);

	BSFadeNode * rootNode = BSFadeNode::Create();
	rootNode->IncRef();
	NiNode * skinnedNode = NiNode::Create(0);
	skinnedNode->m_name = BSFixedString("BSFaceGenNiNodeSkinned").data;

	std::map<NiAVObject*, NiAVObject*> boneMap;

	for (UInt32 i = 0; i < faceNode->m_children.m_size; i++)
	{
		NiAVObject * object = faceNode->m_children.m_data[i];
		if (!object)
			continue;

		if (NiGeometry * geometry = object->GetAsNiGeometry()) {
			NiGeometryData * geometryData = niptr_cast<NiGeometryData>(geometry->m_spModelData);
			NiGeometryData * newGeometryData = NULL;
			if (geometryData)
				CALL_MEMBER_FN(geometryData, DeepCopy)((NiObject **)&newGeometryData);

			NiProperty * trishapeEffect = niptr_cast<NiProperty>(geometry->m_spEffectState);
			NiProperty * newTrishapeEffect = NULL;
			if (trishapeEffect)
				CALL_MEMBER_FN(trishapeEffect, DeepCopy)((NiObject **)&newTrishapeEffect);

			NiProperty * trishapeProperty = niptr_cast<NiProperty>(geometry->m_spPropertyState);
			NiProperty * newTrishapeProperty = NULL;
			if (trishapeProperty)
				CALL_MEMBER_FN(trishapeProperty, DeepCopy)((NiObject **)&newTrishapeProperty);

			NiSkinInstance * skinInstance = niptr_cast<NiSkinInstance>(geometry->m_spSkinInstance);
			NiSkinInstance * newSkinInstance = NULL;
			if (skinInstance) {
				newSkinInstance = skinInstance->Clone(false);
				newSkinInstance->m_pkRootParent = skinnedNode;

				UInt32 numBones = 0;
				NiSkinData * skinData = niptr_cast<NiSkinData>(skinInstance->m_spSkinData);
				NiSkinData * newSkinData = NULL;
				if (skinData) {
					numBones = skinData->m_uiBones;
					CALL_MEMBER_FN(skinData, DeepCopy)((NiObject **)&newSkinData);
				}

				NiSkinPartition * skinPartition = niptr_cast<NiSkinPartition>(skinInstance->m_spSkinPartition);
				NiSkinPartition * newSkinPartition = NULL;
				if (skinPartition)
					CALL_MEMBER_FN(skinPartition, DeepCopy)((NiObject **)&newSkinPartition);

				newSkinInstance->m_spSkinData = newSkinData;
				newSkinData->DecRef();

				newSkinInstance->m_spSkinPartition = newSkinPartition;
				newSkinPartition->DecRef();

				// Remap the bones to new NiNode instances
				if (numBones > 0)
				{
					newSkinInstance->m_ppkBones = (NiAVObject**)NiAllocate(numBones * sizeof(NiAVObject*));
					for (UInt32 i = 0; i < numBones; i++)
					{
						NiAVObject * bone = skinInstance->m_ppkBones[i];
						if (bone)
						{
							auto it = boneMap.find(bone);
							if (it == boneMap.end()) {
								NiNode * newBone = NiNode::Create();
								newBone->m_name = bone->m_name;
								newBone->m_flags = bone->m_flags;
								boneMap.insert(std::make_pair(bone, newBone));
								newSkinInstance->m_ppkBones[i] = newBone;
							}
							else
								newSkinInstance->m_ppkBones[i] = it->second;
						}
						else
						{
							newSkinInstance->m_ppkBones[i] = nullptr;
						}
					}
				}
			}

			NiGeometry * newGeometry = NULL;

			if (NiTriShape * trishape = geometry->GetAsNiTriShape()) {
				NiTriShape * newTrishape = NiTriShape::Create(static_cast<NiTriShapeData*>(newGeometryData));
				newGeometryData->DecRef();
				newTrishape->m_localTransform = geometry->m_localTransform;
				newTrishape->m_name = geometry->m_name;
				memcpy(&newTrishape->unk88, &geometry->unk88, 0x1F);
				newTrishape->m_spEffectState = newTrishapeEffect;
				newTrishape->m_spPropertyState = newTrishapeProperty;
				newTrishape->m_spSkinInstance = newSkinInstance;
				newGeometry = newTrishape;
			}
			else if (NiTriStrips * tristrips = geometry->GetAsNiTriStrips()) {
				NiTriStrips * newTristrips = NiTriStrips::Create(static_cast<NiTriStripsData*>(newGeometryData));
				newGeometryData->DecRef();
				newTristrips->m_localTransform = geometry->m_localTransform;
				newTristrips->m_name = geometry->m_name;
				memcpy(&newTristrips->unk88, &geometry->unk88, 0x1F);
				newTristrips->m_spEffectState = newTrishapeEffect;
				newTristrips->m_spPropertyState = newTrishapeProperty;
				newTristrips->m_spSkinInstance = newSkinInstance;
				newGeometry = newTristrips;
			}

			if (newGeometry)
			{
				auto textureData = GetTextureSetForPartByName(actorBase, newGeometry->m_name);
				if (textureData.first && textureData.second) {
					BSShaderProperty * shaderProperty = niptr_cast<BSShaderProperty>(newGeometry->m_spEffectState);
					if (shaderProperty) {
						if (shaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
							BSLightingShaderProperty * lightingShader = static_cast<BSLightingShaderProperty *>(shaderProperty);
							BSLightingShaderMaterial * material = static_cast<BSLightingShaderMaterial *>(shaderProperty->material);
							if (material && material->textureSet) {
								for (UInt32 i = 0; i < BGSTextureSet::kNumTextures; i++)
									material->textureSet->SetTexturePath(i, textureData.first->textureSet.GetTexturePath(i));

								if (textureData.second->type == BGSHeadPart::kTypeFace)
									material->textureSet->SetTexturePath(6, m_ddsPath.data);
							}
						}
					}

					// Save the previous tint mask
					BSShaderProperty * originalShaderProperty = niptr_cast<BSShaderProperty>(geometry->m_spEffectState);
					if (originalShaderProperty) {
						if (originalShaderProperty->GetRTTI() == NiRTTI_BSLightingShaderProperty) {
							BSLightingShaderProperty * lightingShader = static_cast<BSLightingShaderProperty *>(originalShaderProperty);
							BSLightingShaderMaterial * material = static_cast<BSLightingShaderMaterial *>(originalShaderProperty->material);
							if (material) {
								if (material->GetShaderType() == BSShaderMaterial::kShaderType_FaceGen) {
									BSMaskedShaderMaterial * maskedMaterial = static_cast<BSMaskedShaderMaterial *>(material);
									SaveRenderedDDS(niptr_cast<NiRenderedTexture>(maskedMaterial->renderedTexture), m_ddsPath.data);
								}
							}
						}
					}
				}

				skinnedNode->AttachChild(newGeometry, true);
			}
		}
	}

	for (auto & bones : boneMap)
		rootNode->AttachChild(bones.second, true);

	rootNode->AttachChild(skinnedNode, true);

	UInt8 niStreamMemory[0x5B4];
	memset(niStreamMemory, 0, 0x5B4);
	NiStream * niStream = (NiStream *)niStreamMemory;
	CALL_MEMBER_FN(niStream, ctor)();
	CALL_MEMBER_FN(niStream, AddObject)(rootNode);
	niStream->SavePath(m_nifPath.data);
	CALL_MEMBER_FN(niStream, dtor)();

	rootNode->DecRef();

	if (animationData) {
		animationData->overrideFlag = 0;
		CALL_MEMBER_FN(animationData, Reset)(1.0, 1, 1, 0, 0);
		FaceGen::GetSingleton()->isReset = 1;
		UpdateModelFace(faceNode);
	}
}
예제 #29
0
파일: main.cpp 프로젝트: TES5Edit/TES5Edit
bool xEditCommand()
{
	#if RUNTIME_VERSION == REQUIRED_RUNTIME
		static const UInt32 s_doShowChangeFlagsName = 0x00CD6940;				// Skyrim 1.9.32: 00675DB0,					Fallout3: 006C9510	FalloutNV: 0x0083FEF0
		static const UInt32 s_changeFormTypeArray = 0x037C1F10;					// Skyrim: 012724C0							Fallout3: 00F6D1D0	FalloutNV: 0x011A2428
		// xRef at second xRef to s_changeFormTypeArray, offset 0x0B
		static const UInt32 s_FormToChangeType = 0x05AAC730;					// after initialisation Skyrim: 01B2E4D0	Fallout3: 01079BD0	FalloutNV: 0x011DE360
		// first entry is NONE, then TES4
		static const UInt32 s_nickNames = 0x02C830D8;							// Array of form signatures
		// 4th to last xRef to s_nickNames. array of 159 FormTypeNickName
		static const UInt32 s_formTypeNicknames = 0x0370E7D0;					// Skyrim: 0123F2C4							Fallout3: 00F4A74C	FalloutNV: 0x01187004
		// Starts with "Misc Stats" as aMiscStats_0, first xref
		static const UInt32 s_GlobalData1Names = 0x037C18C0;					// Skyrim: 01272310, 01272334, 01272370,	Fallout3: 00F6CED8	FalloutNV: 0x011A216C
		static const UInt32 s_GlobalData2Names = s_GlobalData1Names + 12;		// 100 + index
		static const UInt32 s_GlobalData3Names = s_GlobalData2Names + 18;		// 1000 + index
		static const UInt32 s_GlobalData3NamesEnd = s_GlobalData3Names + 8;
		static const UInt64 s_DialogSubtypes = 0x0374E430;						// First is CUST Custom as aCustom_0 xRef 2
		static const UInt64 s_DialogSubtypesEnd = 0x0374F7B8;					//	past PlayerAquireFeaturedItem as aPlayeraquirefe xRef 1
		static const UInt64 s_DefaultObjectManagerObjectArray = 0x03723C50;		// First is UNUSED01, WWSP as aUnused01 xRef 1
		static const UInt64 s_DefaultObjectManagerObjectArrayEnd = 0x03726D90;	// ??_R0?AVBGSDefaultObjectManager@@@8 as BGSDefaultObjectManager `RTTI Type Descriptor'
	#else 
	#error
	#endif

	typedef char * (* _s_doShowChangeFlagsName)(UInt32 flag, UInt32 formType, bool returnDescription);
	RelocAddr <_s_doShowChangeFlagsName> doShowChangeFlagsName(s_doShowChangeFlagsName);
	RelocPtr <UInt32> changeToFormType(s_changeFormTypeArray);

	struct FormTypeNickname
	{
		char formType;
		char pad01[7];
		char *nickname;
		UInt32 unk10;
		UInt32 pad14;
	};
	RelocPtr <FormTypeNickname> formTypeNicknames(s_formTypeNicknames);	// array size = kFormType_Max

	_MESSAGE("*****************************************************************************************************");

	// create the list of signatures
	_MESSAGE("formType;formSignature; %d elements not counting the 6 specials for Papyrus", kFormType_Max);
	for (UInt32 formType = 0; formType < kFormType_Max; formType++) {
		_MESSAGE("%03d;%s", formType, formTypeNicknames[formType].nickname);
	}
	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// create the list of script commands
	UInt32 i = 0;
	_MESSAGE("  wbConsoleFunctions : array[] of TFunction = (");
	for(ObScriptCommand * iter = g_firstConsoleCommand; iter->opcode < (kObScript_NumConsoleCommands+kObScript_ConsoleOpBase); ++iter, i++)
	{
			_MESSAGE("    (Index: %3d; Name: '%s'%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s),", i, iter->longName, 
				CheckParam(iter, 0) ? "; Paramtype1: pt" : "", CheckParam(iter, 0) ? iter->params[0].typeStr : "", 
				CheckParam(iter, 1) ? "; Paramtype2: pt" : "", CheckParam(iter, 1) ? iter->params[1].typeStr : "", 
				CheckParam(iter, 2) ? "; Paramtype3: pt" : "", CheckParam(iter, 2) ? iter->params[2].typeStr : "",
				CheckParam(iter, 3) ? "; Paramtype3: pt" : "", CheckParam(iter, 3) ? iter->params[3].typeStr : "",
				CheckParam(iter, 4) ? "; Paramtype4: pt" : "", CheckParam(iter, 4) ? iter->params[4].typeStr : "",
				CheckParam(iter, 5) ? "; Paramtype5: pt" : "", CheckParam(iter, 5) ? iter->params[5].typeStr : "",
				CheckParam(iter, 6) ? "; Paramtype6: pt" : "", CheckParam(iter, 6) ? iter->params[6].typeStr : "",
				CheckParam(iter, 7) ? "; Paramtype7: pt" : "", CheckParam(iter, 7) ? iter->params[7].typeStr : "",
				CheckParam(iter, 8) ? "; Paramtype8: pt" : "", CheckParam(iter, 8) ? iter->params[8].typeStr : "",
				CheckParam(iter, 9) ? "// ; More..." : "");
	}
	_MESSAGE("  );");	// Don't forget to remove the last ,

	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// create the list of script commands
	i = 0;
	_MESSAGE("  wbFunctions : array[] of TFunction = (");
	for(ObScriptCommand * iter = g_firstObScriptCommand; iter->opcode < (kObScript_NumObScriptCommands+kObScript_ScriptOpBase); ++iter, i++)
	{
			_MESSAGE("    (Index: %3d; Name: '%s'%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s),", i, iter->longName, 
				CheckParam(iter, 0) ? "; Paramtype1: pt" : "", CheckParam(iter, 0) ? iter->params[0].typeStr : "", 
				CheckParam(iter, 1) ? "; Paramtype2: pt" : "", CheckParam(iter, 1) ? iter->params[1].typeStr : "", 
				CheckParam(iter, 2) ? "; Paramtype3: pt" : "", CheckParam(iter, 2) ? iter->params[2].typeStr : "",
				CheckParam(iter, 3) ? "; Paramtype3: pt" : "", CheckParam(iter, 3) ? iter->params[3].typeStr : "",
				CheckParam(iter, 4) ? "; Paramtype4: pt" : "", CheckParam(iter, 4) ? iter->params[4].typeStr : "",
				CheckParam(iter, 5) ? "; Paramtype5: pt" : "", CheckParam(iter, 5) ? iter->params[5].typeStr : "",
				CheckParam(iter, 6) ? "; Paramtype6: pt" : "", CheckParam(iter, 6) ? iter->params[6].typeStr : "",
				CheckParam(iter, 7) ? "; Paramtype7: pt" : "", CheckParam(iter, 7) ? iter->params[7].typeStr : "",
				CheckParam(iter, 8) ? "; Paramtype8: pt" : "", CheckParam(iter, 8) ? iter->params[8].typeStr : "",
				CheckParam(iter, 9) ? "// ; More..." : "");
	}
	_MESSAGE("  );");	// Don't forget to remove the last ,

	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// create the list of condition commands
	i = 0;
	UInt32 j = 0;
	_MESSAGE("  wbCTDAFunctions : array[] of TCTDAFunction = (");
	for(ObScriptCommand * iter = g_firstObScriptCommand; iter->opcode < (kObScript_NumObScriptCommands+kObScript_ScriptOpBase); ++iter, i++)
	{
		if(iter->eval)
		{
			_MESSAGE("    (Index: %3d; Name: '%s'%s%s%s%s%s%s),\t\t// %3d", i, iter->longName, 
				CheckParam(iter, 0) ? "; Paramtype1: pt" : "", CheckParam(iter, 0) ? iter->params[0].typeStr : "", 
				CheckParam(iter, 1) ? "; Paramtype2: pt" : "", CheckParam(iter, 1) ? iter->params[1].typeStr : "", 
				CheckParam(iter, 2) ? "; Paramtype3: pt" : "", CheckParam(iter, 2) ? iter->params[2].typeStr : "",
				j);
			j++;
		}
	}
	_MESSAGE("  );");	// Don't forget to remove the last ,

	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// create the list of condition commands for WB
	i = 0;
	j = 0;
	_MESSAGE("conditionFunctionData = ( #--0: no param; 1: int param; 2: formid param; 3: float param");
	for (ObScriptCommand * iter = g_firstObScriptCommand; iter->opcode < (kObScript_NumObScriptCommands + kObScript_ScriptOpBase); ++iter, i++)
	{
		if (iter->eval)
		{
			_MESSAGE("    (%3d, '%s', %d, %d, %d),", i, iter->longName,
				CheckParam(iter, 0) ? WBEncode(iter->params[0]) : 0,
				CheckParam(iter, 1) ? WBEncode(iter->params[1]) : 0,
				CheckParam(iter, 2) ? WBEncode(iter->params[2]) : 0,
				j);
			j++;
		}
	}
	_MESSAGE("    )");	// Don't forget to add xSE functions

	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// create the Changed Form flags variables
	UInt32 changeTypeCount = 50; // First being 13 = TESClass. 16 different cases, 50 valid are: 0,     1,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,      2,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,      3,     4,   11h,   11h,    11h,     5,   11h,   11h,    11h,   11h,   11h,     4,    11h,   11h,   11h,   11h,    11h,   11h,     6,     7,      7,     7,     7,     7,      7,     7,     7,     7,      7,   11h,   11h,   11h,    11h,   11h,     8,     9,    11h,   0Ah,   11h,   11h,      4,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   0Bh,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    11h,   0Ch,   0Dh,   11h,    11h,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    0Eh,   11h,   11h,   11h,    11h,   11h,   11h,   11h,    0Fh,   10h
	for (UInt32 changeType = 0; changeType < changeTypeCount; changeType++) {
		_MESSAGE("  wbChangeFlags%03u        : IwbIntegerDef;", changeType);
	}
	_MESSAGE("");

	// create the Changed Form Data union variables
	for (UInt32 changeType = 0; changeType < changeTypeCount; changeType++) {
		UInt32 formType = changeToFormType[changeType];
		UInt32 flagValue;
		char * changeFlagsName;
		for (UInt8 flagShift = 0; flagShift < 32; flagShift++) {
			flagValue = 1 << flagShift;
			changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
			if (strcmp("Bad Flag Name", changeFlagsName)) {
				_MESSAGE("  wbUnion%s : IwbUnionDef;", changeFlagsName);
			}
		}
	}

	_MESSAGE("*****************************************************************************************************");

	// decode the Change Type name
	_MESSAGE("  wbChangeTypes := wbKey2Data6Enum([");
	for (UInt32 changeType = 0; changeType < changeTypeCount-1; changeType++) {
		UInt32 formType = changeToFormType[changeType];
		_MESSAGE("    '%02u (%03X : %s)',", changeType, formType, formTypeNicknames[formType].nickname);
	}
	UInt32 formType = changeToFormType[changeTypeCount-1];
	_MESSAGE("    '%02u (%03X : %s)'", changeTypeCount-1, formType, formTypeNicknames[formType].nickname);
	_MESSAGE("  ]);\n");

	_MESSAGE("*****************************************************************************************************");

	// decode the Changed form flags
	for (UInt32 changeType = 0; changeType < changeTypeCount; changeType++) {
		UInt32 formType = changeToFormType[changeType];
		_MESSAGE("  // changeType: %03u = formType: %03u : %s", changeType, formType,  formTypeNicknames[formType].nickname);
		_MESSAGE("  wbChangeFlags%03u := wbInteger('Change Flags', itU32 , wbFlags([", changeType);

		UInt32 flagValue;
		char * changeFlagsName;
		char * changeFlagsDescription;
		for (UInt8 flagShift = 0; flagShift < 31; flagShift++) {
			flagValue = 1 << flagShift;
			changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
			if (0==strcmp("Bad Flag Name", changeFlagsName)) {
				_MESSAGE("    {%02u} 'UnnamedFlag%02u',", flagShift, flagShift);
			} else {
				changeFlagsDescription = doShowChangeFlagsName(flagValue, formType, 1);
				_MESSAGE("    {%02u} '%s', // %s", flagShift, changeFlagsName, changeFlagsDescription);
			}
		}
		flagValue = 1 << 31;
		changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
		if (0==strcmp("Bad Flag Name", changeFlagsName)) {
			_MESSAGE("    {%02u} 'UnnamedFlag%02u'", 31, 31);
		} else {
			changeFlagsDescription = doShowChangeFlagsName(flagValue, formType, 1);
			_MESSAGE("    {%02u} '%s' // %s", 31, changeFlagsName, changeFlagsDescription);
		}
		_MESSAGE("  ]));\n");
	}

	_MESSAGE("*****************************************************************************************************");

	// Build the Changed Form flags union
	_MESSAGE("  wbChangeFlags := wbUnion('Change Flags', ChangedFormFlagsDecider, [");
	for (UInt32 changeType = 0; changeType < changeTypeCount-1; changeType++) {
		_MESSAGE("    wbChangeFlags%03u,", changeType);
	}
	_MESSAGE("    wbChangeFlags%03u", changeTypeCount-1);
	_MESSAGE("  ]);\n");

	// Build the Changed Form union
	for (UInt32 changeType = 0; changeType < changeTypeCount; changeType++) {
		UInt32 formType = changeToFormType[changeType];
		UInt32 flagValue;
		char * changeFlagsName;
		for (UInt8 flagShift = 0; flagShift < 32; flagShift++) {
			flagValue = 1 << flagShift;
			changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
			if (strcmp("Bad Flag Name", changeFlagsName)) {
				_MESSAGE("  wbUnion%s := wbUnion('%s', ChangedFlag%02uDecider, [wbNull, wbNull]);", changeFlagsName, doShowChangeFlagsName(flagValue, formType, 1), flagShift);
			}
		}
		_MESSAGE("");
	}
	_MESSAGE("");

	_MESSAGE("*****************************************************************************************************");

	// Build the Changed Form Data struct
	UInt32 flagValue = 1;
	char * changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
	_MESSAGE("  wbChangedFormData := wbStruct('Changed Form Data', [");
	_MESSAGE("    wbInitialDataType,");
	_MESSAGE("    wbUnion('CForm Union', ChangedFormDataDecider, [");
	_MESSAGE("       wbNull");
	for (UInt32 changeType = 0; changeType < changeTypeCount; changeType++) {
		bool first = true;
		UInt32 formType = changeToFormType[changeType];
		_MESSAGE("      ,wbStruct('Change %s Data', [ {%03X}", formTypeNicknames[formType].nickname, formType);
		for (UInt8 flagShift = 0; flagShift < 32; flagShift++) {
			flagValue = 1 << flagShift;
			changeFlagsName = doShowChangeFlagsName(flagValue, formType, 0);
			if (strcmp("Bad Flag Name", changeFlagsName)) {
				if (first) {
					first = false;
					_MESSAGE("         wbUnion%s", changeFlagsName);
				} else
				_MESSAGE("        ,wbUnion%s", changeFlagsName);
			}
		}
		_MESSAGE("       ])");
	}
	_MESSAGE("    ]),");
	_MESSAGE("    wbByteArray('Undecoded Data', ChangedFormRemainingDataCounter)");
	_MESSAGE("  ]);\n");

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	_MESSAGE("avID;avName;formID;\"fullName\";description.unk08;flags;avType");
	UInt32 firstAV = 0x2BC;
	UInt32 avID = 0;
	do
	{
		TESForm* pForm = LookupFormByID(avID+firstAV);
		ActorValueInfo_X* pActorValueInfo = NULL;

		if (pForm && pForm->formType == 98)
			pActorValueInfo = (ActorValueInfo_X*)pForm;
		if (pActorValueInfo) {
			_MESSAGE("%d;%s;%x;\"%s\";%x;%x;%x", avID, pActorValueInfo->avName, pActorValueInfo->formID, 
				pActorValueInfo->fullName.Get(), 
				pActorValueInfo->description.unk08, pActorValueInfo->avFlags, pActorValueInfo->avType);
		}
		avID++;
	} while ((avID+firstAV) < 0x800);

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	struct DialogSubtype
	{
		const char	* name;			// 000
		char		unk008;			// 008
		char		fil009[3];		// 009
		char		shortName[4];	// 00C
		char		dstID;			// 010
		char		fil011[3];		// 011
		char		unk014;			// 014
		char		unk015;			// 015
		char		fil016[2];		// 016
		char		unk018;			// 018
		char		fil019[15];		// 019
	};	// 028

	_MESSAGE("dstID;dstName;dstType;dstShort;dstUnk014;dstUnk015;dstUnk018");
	RelocPtr <DialogSubtype>	g_DialogSubtypes(s_DialogSubtypes);
	RelocPtr <DialogSubtype>	g_DialogSubtypesEnd(s_DialogSubtypesEnd);
	DialogSubtype* curr = g_DialogSubtypes;
	UInt32 dstID = 0;
	do
	{
		char shortName[5] = "    ";
		for (UInt8 i = 0; i < 4 ; i++) shortName[i] = curr->shortName[i]; shortName[4] = 0;
		_MESSAGE("%d;\"%s\";%d;\"%s\";%d;%d;%d", dstID, curr->name, curr->dstID, shortName, curr->unk008, curr->unk014, curr->unk015, curr->unk018);
		dstID++;
		curr++;
	} while (curr < g_DialogSubtypesEnd);

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	struct DataDOM
	{
		const char	* name;			// 000
		UInt8		formType;		// 008
		UInt8		fil009[3];		// 009
		char		shortName[4];	// 00C
		UInt32		unk010;			// 010
		UInt32		unk014;			// 014
		UInt32		formID;			// 018
		UInt32		pad01C;			// 01C
	};	// 020

	RelocPtr <DataDOM>	g_DefaultObjectManagerObject(s_DefaultObjectManagerObjectArray);
	UInt32 domCount = (s_DefaultObjectManagerObjectArrayEnd - s_DefaultObjectManagerObjectArray) / sizeof(DataDOM);
	DataDOM* dom = g_DefaultObjectManagerObject;
	_MESSAGE("domID;domName;domShort;formType;domUnk010;domUnk014;domFormID; %d elements", domCount);
	for (UInt32 domID = 0; domID < domCount ; domID++)
	{
		char shortName[5] = "    ";
		for (UInt8 i = 0; i < 4 ; i++) shortName[i] = dom->shortName[i]; shortName[4] = 0;
		_MESSAGE("%d;\"%s\";\"%s\";%d;%d;%d;%08x", domID, dom->name, shortName, dom->formType, dom->unk010, dom->unk014, dom->formID);
		dom++;
	};

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	dom = g_DefaultObjectManagerObject;
	for (UInt32 domID = 0; domID < domCount ; domID++)
	{
		char shortName[5] = "    ";
		for (UInt8 i = 0; i < 4 ; i++) shortName[i] = dom->shortName[i]; shortName[4] = 0;
		_MESSAGE("sig2Int('%s'), '%s'", shortName, dom->name);
		dom++;
	};

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	DefaultObjectMap * domap = *(g_defaultObjectMap);
	domap->Dump();

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	_MESSAGE("formType;formSignature;formID;");
	DataHandler* theDH = *g_dataHandler.GetPtr();
	UnkFormXArray* unkFormArrays = (UnkFormXArray*)&(theDH->arrNONE);
	for (UInt8 i = 0; i < kFormType_Max; i++)
	{
		UnkFormXArray* a = (UnkFormXArray*) ((uintptr_t)unkFormArrays + i * sizeof(UnkFormXArray));
		for (UInt64 j = 0; j < a->count; j++)
		{
			TESForm_X* f = (*a)[j];
			if (f && !f->mods)
				_MESSAGE("%04d;%s;%08X;", f->formType, formTypeNicknames[f->formType].nickname, f->formID);
		}
	}

	_MESSAGE("*****************************************************************************************************");
	_MESSAGE("\n\n\n");

	return true;
}
예제 #30
0
static bool GetActiveMenuElement(COMMAND_ARGS, eMenuValue whichValue, MenuInfo* out, UInt32 whichMenu = 0)
{
	InterfaceManager* intfc = InterfaceManager::GetSingleton();
	Menu* activeMenu = intfc->activeMenu;
	Tile* activeTile = intfc->activeTile;
	if (!activeTile) {
		// theoretically this is active tile if user is navigating by keyboard - for this to work user must pass whichMenu arg
		activeTile = intfc->altActiveTile;
	}

	bool gotValue = false;
	UInt32 intArg = -1;

	//Extract arguments
	if (whichValue < kMenu_Ingredient && whichValue >= kMenu_Selection)	//optional int param specifies menu type
	{
		ExtractArgs(EXTRACT_ARGS, &intArg);
		if (intArg != -1)
			activeMenu = GetMenuByType(intArg);
	}
	else if (whichValue >= kMenu_Ingredient)
	{
		ExtractArgs(EXTRACT_ARGS, &intArg);
		if (intArg == -1)
			return false;
	}

	if (whichMenu)	//specific menu, so look it up directly
		activeMenu = GetMenuByType(whichMenu);

	if (!activeMenu)
		return false;

	//get element based on menu type
	switch (activeMenu->id)
	{
	case kMenuType_Message:
		{
			MessageMenu* msgMenu = (MessageMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Object:
				if (ShowMessageBox_pScriptRefID && msgMenu->IsScriptMessageBox())
				{
					out->form = LookupFormByID(*ShowMessageBox_pScriptRefID);
					gotValue = true;
				}
				else
					out->form = 0;
			default:
				break;
			}
		}
		break;
	case kMenuType_Alchemy:
		{
			AlchemyMenu* menu = (AlchemyMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Object:
				out->form = menu->potion;
				gotValue = true;
				break;
			case kMenu_Ingredient:
				out->form = menu->GetIngredientItem(intArg);
				gotValue = true;
				break;
			case kMenu_IngredientCount:
				out->integer = menu->GetIngredientCount(intArg);
				gotValue = true;
				break;
			case kMenu_Apparatus:
				out->form = menu->GetApparatus(intArg);
				gotValue = true;
				break;
			default:
				break;
			}
		}
		break;
	case kMenuType_Container:
		{
			ContainerMenu* menu = (ContainerMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_ContainerView:
				if (menu->isContainerContents)
					out->integer = 0;
				else
					out->integer = 1;
				gotValue = true;
				break;
			case kMenu_Ref:
				{
					out->form = menu->refr;
					gotValue = true;
					break;
				}
			case kMenu_Filter:
				out->integer = menu->filterType;
				gotValue = true;
				break;
			case kMenu_Selection:
				{
					if (activeTile)
					{
						float fIndex;
						if (activeTile->GetFloatValue(kTileValue_user11, &fIndex))
						{
							UInt32 index = fIndex;
							if (menu->isContainerContents)
								out->form = menu->refr->GetInventoryItem(index, menu->isBarter);
							else
								out->form = (*g_thePlayer)->GetInventoryItem(index, 0);
							gotValue = true;
						}
					}
				}
				break;
			case kMenu_Barter:
				out->integer = menu->isBarter;
				gotValue = true;
				break;
			default:
				break;
			}
			break;
		}
	case kMenuType_Magic:
		{
			MagicMenu* menu = (MagicMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Selection:
				{
					if (activeTile && menu->filterType != MagicMenu::kFilter_ActiveEffects)
					{
						float fIndex;
						if (activeTile->GetFloatValue(kTileValue_user13, &fIndex)) {
							DEBUG_PRINT("Index of active magic item: %.0f", fIndex);
							UInt32 index = fIndex;
							float fObjType;
							if (activeTile->GetFloatValue(kTileValue_user7, &fObjType)) {
								if (fObjType == 8)	{	// a scroll
									TESForm* form = menu->GetMagicItemForIndex(index);
									if (form) {
										out->form = form;
										gotValue = true;
									}
								}
								else {	// a spell
									out->form = MenuSpellListVisitor(&menu->spells).GetNthInfo(index-1);
									gotValue = true;
								}
							}
						}
					}
				}
				break;
			case kMenu_Filter:
				out->integer = menu->filterType;
				gotValue = true;
				break;
			default:
				break;
			}
			break;
		}
	case kMenuType_SpellPurchase:
		{
			SpellPurchaseMenu* menu = (SpellPurchaseMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Selection:
				{
					if (activeTile)
					{
						float fIndex;
						//if (activeTile->GetFloatValue(kTileValue_user11, &fIndex))
						if (activeTile->GetFloatValue(kTileValue_user0, &fIndex))
						{
							UInt32 index = fIndex;
							out->form = MenuSpellListVisitor(&menu->spells).GetNthInfo(index);
							gotValue = true;
						}
					}
					break;
				}
			case kMenu_Ref:
				{
					out->form = menu->spellMerchant;
					gotValue = true;
					break;
				}
			default:
				break;
			}
		}
		break;
	case kMenuType_Enchantment:
		{
			EnchantmentMenu* menu = (EnchantmentMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Soulgem:
				if (menu->soulGemInfo)
				{
					out->form = menu->soulGemInfo->form;
					gotValue = true;
				}
				break;
			case kMenu_EnchantItem:
				out->form = menu->enchantItem;
				gotValue = true;
				break;
			default:
				break;
			}
		}
		break;
	case kMenuType_Book:
		{
			BookMenu* menu = (BookMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Ref:
				out->form = menu->bookRef;
				gotValue = true;
				break;
			case kMenu_Object:
				out->form = menu->book;
				gotValue = true;
				break;
			default:
				break;
			}
		}
		break;
	case kMenuType_Inventory:
		{
			InventoryMenu* menu = (InventoryMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Selection:
				{
					if (activeTile)
					{
						float fIndex;
						if (activeTile->GetFloatValue(kTileValue_user11, &fIndex))
						{
							UInt32 index = fIndex;
							out->form = (*g_thePlayer)->GetInventoryItem(index, 0);
							gotValue = true;
						}
					}
				}
				break;
			case kMenu_Filter:
				out->integer = menu->filterType;
				gotValue = true;
				break;
			default:
				break;
			}
		}
		break;
	case kMenuType_Dialog:
		{
			DialogMenu* menu = (DialogMenu*)activeMenu;
			switch (whichValue)
			{
			case kMenu_Ref:
				out->form = menu->speaker;
				gotValue = true;
				break;
			default:
				break;
			}
		}
		break;
	default:
		break;
	}

	return gotValue;
}