rodecomp/Source/Contents/Actors/Item.cpp
ragnarok-clanker 4f1abe4e7b Decompile fn_22252 (CItem::SendMsg)
Batch #7367 by gordaoprogramas: 0 byte-identical, 1 confirmed by peer review.

- fn_22252 CItem::SendMsg: logic confirmed by peer review

Peer-reviewed-by: eAthena, aDw
Accepted without human review: peers confirmed the logic ("same" ahead by at least 3, with 70% of the votes).
2026-10-31 07:13:06 +00:00

170 lines
5.8 KiB
C++

#include "Contents/Actors/Item.h"
#include "Client/Mode/CGameMode.h"
#include "Client/Input/InputCharset.h"
#include "Client/Mode/ModeMgr.h"
#include "Contents/Configuration/ServiceConfiguration.h"
#include "Contents/Effects/EffectLists.h"
#include "Contents/Effects/RagEffect.h"
#include "Contents/Items/ItemDescription.h"
#include "Contents/Items/ItemInfo.h"
#include "Contents/Items/ItemInfoMgr.h"
#include "Contents/Items/ItemNaming.h"
#include "Contents/Items/ItemResources.h"
#include "Contents/MessageTable.h"
#include "Contents/PlayerNameDictionary.h"
#include "Contents/World/World.h"
#include "Resource/ResourceMgr.h"
#include "Resource/World/TerrainResource.h"
#include "Utility/Text/FormatString.h"
#include <cstdlib>
#include <windows.h>
#include <timeapi.h>
struct ItemFallEntry {
/* 0000 */ char itemId[0x20];
/* 0020 */ std::uint32_t aid;
/* 0024 */ int column;
/* 0028 */ int row;
/* 002C */ int subColumn;
/* 0030 */ int subRow;
/* 0034 */ int falling;
/* 0038 */ int count;
/* 003C */ unsigned char identified;
/* 003E */ std::uint16_t unknown_003E;
/* 0040 */ unsigned char showEffect;
/* 0042 */ std::uint16_t grade;
};
// OFFSET: 0x00D8B5A0
// FUNCTION: fn_22248
void CItem::SubD8B5A0() {
}
// OFFSET: 0x00D8B5B0
// FUNCTION: fn_22249
void CItem::SubD8B5B0() {
this->render.unknown_00A4Bytes[0] = 1;
this->render.unknown_00A4Bytes[1] = 1;
this->render.scale = 1.0f;
this->render.overrideColor = 0xFFFFFF00;
}
// OFFSET: 0x00D8B5D0
// FUNCTION: fn_22250
bool CItem::OnProcess() {
const float elapsed = static_cast<float>((timeGetTime() - this->render.unknown_008C) / 24.0);
this->render.isSingleColor = static_cast<int>(elapsed) % 92 >= 90;
if (this->isFalling) {
this->render.position.y = (elapsed * 0.083f + this->fallVelocity) * elapsed + this->fallOrigin;
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
if (this->render.position.y > mode->scene->terrain->Grid().Height(this->render.position.x, this->render.position.z)) {
this->render.position.y = mode->scene->terrain->Grid().Height(this->render.position.x, this->render.position.z);
this->isFalling = 0;
}
}
return true;
}
// OFFSET: 0x00D8B6D0
// FUNCTION: fn_22251
void CItem::Render(int argument) {
if (this->render.visible) {
this->DrawShadow(argument, this->render.scale * 0.4f);
this->DrawSprite(argument, false, 0.0f);
}
}
// OFFSET: 0x00D8B720
// FUNCTION: fn_22252
void CItem::SendMsg(CGameObject* sender, int message, int a, int b, int c, int d, int e, int f, int g, int h, int i, int, int, int, int) {
CGameMode* mode = static_cast<CGameMode*>(g_modeMgr.GetGameMode());
if (message != 4 || a != 0) {
this->EffectActor::SendMsg(sender, message, a, b, c, d, e, f, g, h, i, 0, 0, 0, 0);
return;
}
const ItemFallEntry* entry = reinterpret_cast<const ItemFallEntry*>(b);
this->itemAid = entry->aid;
this->name = entry->itemId;
std::string itemName = this->name;
mode->SubcellPosition(entry->column, entry->row, entry->subColumn, entry->subRow, this->render.position.x, this->render.position.z);
this->render.position.y = mode->scene->terrain->Grid().Height(this->render.position.x, this->render.position.z);
if (entry->falling) {
this->fallVelocity = -0.6f;
this->render.position.y -= 15.0f;
this->isFalling = 1;
} else {
this->isFalling = 0;
}
this->fallOrigin = this->render.position.y;
ItemDescriptions descriptions{g_itemDescriptions};
std::string spriteName = ItemDragResource(descriptions, this->name.c_str(), entry->identified);
spriteName += ".spr";
std::string actionName = ItemDragResource(descriptions, this->name.c_str(), entry->identified);
actionName += ".act";
this->SetSpriteName(ResourceMgr::Instance(), spriteName.c_str());
this->SetActionName(ResourceMgr::Instance(), actionName.c_str());
ITEM_INFO item;
this->itemIndex = std::atoi(entry->itemId);
this->unknown_018C = entry->unknown_003E;
this->itemId = static_cast<std::uint16_t>(std::atoi(entry->itemId));
this->identified = entry->identified;
item.itemId = itemName;
item.identified = entry->identified;
item.unknown_0060 = 0;
bool languagePrefix = false;
WORD language = g_serverLanguage->language;
ItemNaming naming{descriptions, g_itemCardNames, *g_playerNameDictionary, languagePrefix, g_serviceType, language};
this->name = static_cast<const std::string&>(FormatOwnedString(LookupMessage(183), naming.DisplayName(item, 0).c_str(), entry->count));
this->GetActRes();
this->render.unknown_008C = timeGetTime();
if (entry->showEffect == 1) {
const float x = this->render.position.x;
const float z = this->render.position.z;
const float height = mode->scene->terrain->Grid().Height(x, z);
const int effectId = g_itemInfoMgr->GetEffectId(this->itemIndex);
if (effectId >= 0 && !g_effectMgr->Spawn(entry->aid, effectId, x, height, z, 0, -1, 0, 0)) {
if (CRagEffect* effect = this->LaunchEffect(effectId, vector3d{0.0f, 0.0f, 0.0f}, 0.0f)) {
effect->render.position.x = x;
effect->render.position.y = height;
effect->render.position.z = z;
}
}
if (static_cast<std::uint16_t>(entry->grade - 1) <= 4) {
int gradeEffectId = 2485;
switch (entry->grade) {
case 1:
gradeEffectId = 1869;
break;
case 2:
gradeEffectId = 1189;
break;
case 3:
gradeEffectId = 1190;
break;
case 4:
gradeEffectId = 1870;
break;
case 5:
gradeEffectId = 1871;
break;
}
if (!g_effectMgr->Spawn(entry->aid, gradeEffectId, x, height, z, 0, -1, 0, 0)) {
if (CRagEffect* effect = this->LaunchEffect(gradeEffectId, vector3d{0.0f, 0.0f, 0.0f}, 0.0f)) {
effect->render.position.x = x;
effect->render.position.y = height;
effect->render.position.z = z;
}
}
}
}
}