// Project Lab - NHTV Igad #include "UnrealProject.h" #include "ItemBase.h" #include "BaseSkillObject.h" #include "CharacterBase.h" // Sets default values AItemBase::AItemBase() { // Create a mesh subcomponent without collision. Mesh = CreateDefaultSubobject(TEXT("Mesh")); RootComponent = Mesh; Mesh->SetCollisionEnabled(ECollisionEnabled::NoCollision); } void AItemBase::CreateItemsFromSkill(UWorld* world, class UBaseSkillObject* skillObject, class ACharacterBase* character) { // Check if passed arguments are valid. if (world && skillObject && character) { for (size_t i = 0; i < skillObject->visibleItems.itemsToEquip.Num(); i++) { if (!skillObject->visibleItems.itemsToEquip[i].mesh) { TERROR("Skill item does not have a mesh attached to it!"); continue; } // Get the Skeletal Mesh of the character. USkeletalMeshComponent* charMesh = character->GetMesh(); // Check if the socket has already been taken by another item. bool hasBeenTaken = false; for (auto SceneComp : charMesh->AttachChildren) { AItemBase* item = Cast(SceneComp->GetOwner()); if (item) { if (item->type == skillObject->visibleItems.itemsToEquip[i].type) { hasBeenTaken = true; break; } } } if (!hasBeenTaken) { // Spawn a new item. AItemBase* createdItem = Cast(world->SpawnActor(StaticClass())); // Set the item with the correct settings and mesh. createdItem->type = skillObject->visibleItems.itemsToEquip[i].type; createdItem->SetMesh(skillObject->visibleItems.itemsToEquip[i].mesh); createdItem->skillObject = skillObject; createdItem->AttachItemToCharacter(character); } } return; } TERROR("Either world (" + world + "), skillObject (" + skillObject + ") or character (" + character + ") passed to AItemBase::CreateItemFromSkill was a nullptr."); } AItemBase* AItemBase::CheckSlotOccupied(EItemTypeEnum slotType, class ACharacterBase* character) { // Check if passed arguments are valid. if(character) { UWorld* world = character->GetWorld(); // Get the Skeletal Mesh of the character. USkeletalMeshComponent* charMesh = character->GetMesh(); // Check if the socket has already been taken by another item. bool hasBeenTaken = false; for(auto SceneComp : charMesh->AttachChildren) { AItemBase* item = Cast(SceneComp->GetOwner()); if (item) { if(item->type == slotType) return item; } } } return nullptr; } void AItemBase::Destroyed() { ACharacterBase* attachedParent = Cast(this->GetAttachParentActor()); if(IsValid(attachedParent)) { attachedParent->m_OnItemRemoved(this); } Super::Destroyed(); } void AItemBase::SetMesh(USkeletalMesh* newMesh) { Mesh->SetSkeletalMesh(newMesh); } bool AItemBase::AttachItemToCharacter(class ACharacterBase* networkCharacter) { // Variable used to retrieve names of the EItemTypeEnum values. const static UEnum* EnumPtr = FindObject(ANY_PACKAGE, TEXT("EItemTypeEnum"), true); // Retrieve the name of the type the item was assigned to. This is to attach the item to a socket. FName socketName = FName(*EnumPtr->GetEnumName((int32)type)); // Get the Skeletal Mesh of the character. USkeletalMeshComponent* charMesh = networkCharacter->GetMesh(); // Check if the socket actually exists. if(!charMesh->DoesSocketExist(socketName)) { return false; } // Attach the item to the socket. RootComponent->AttachTo(charMesh, NAME_None, EAttachLocation::SnapToTargetIncludingScale); Mesh->SetMasterPoseComponent(charMesh); // Notify character networkCharacter->m_OnItemAdded(this); return true; }