Skip to content

Commit

Permalink
Added TEMPLATE support for the FUNC keyword, fixed FUNC keyword use a…
Browse files Browse the repository at this point in the history
…fter BREAK in triggers

Added function i16_narrow8.
  • Loading branch information
cbnolok committed Sep 25, 2023
1 parent fe27685 commit 8f306c1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 28 deletions.
6 changes: 1 addition & 5 deletions Changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3345,10 +3345,6 @@ Additionally, the problem of zig-zag issue following in the South direction has
- Fixed: Ship plank not remaining open when turning the ship around. (Issue #1089)
The ship plank will now autoclose after 5 seconds.

Fixed: Client Linger Timer is 3600 seconds on stoned players. (Issue #1081)
23-09-2023, Jhobean
Fixed: When deleting account, f_onchar_delete was not call on char and char's item was not remove causing warning on next server boot. ( Issue #1029)

25-09-2023, Nolok
- Added: FUNC keyword to item templates and template-triggers with special parsing (@CreateLoot, @NPCRestock). It allows to call a function with arguments on the last created ITEM.
- Added: FUNC keyword to item templates and template-triggers with special parsing (@Create, @CreateLoot, @NPCRestock). It allows to call a function with arguments on the last created ITEM.
Default object: the item. SRC: the character holding it.
17 changes: 17 additions & 0 deletions src/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,23 @@ auto i32_narrow16(const T a) noexcept
return static_cast<uint16>(a & umask);
}

template <typename T>
auto i16_narrow8(const T a) noexcept
{
static_assert(std::is_arithmetic_v<T>, "Input variable is not an arithmetic type.");
static_assert(std::is_integral_v<T>, "Only integral types are supported by this function.");
static_assert(sizeof(T) == 2, "Input variable is not a 16 bit number.");

// Since the narrowing can be implementation specific, here we decide that we take only the lower 16 bytes and discard the upper ones.
constexpr uint16 umask = 0x00FF;
if constexpr (std::is_signed_v<T>)
{
return static_cast<int8>(a & umask);
}
else
return static_cast<uint8>(a & umask);
}


//#define IMulDiv(a,b,c) (((((int)(a)*(int)(b)) + (int)(c / 2)) / (int)(c)) - (IsNegative((int)(a)*(int)(b))))
inline int IMulDiv(const int a, const int b, const int c) noexcept
Expand Down
22 changes: 13 additions & 9 deletions src/game/chars/CChar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1276,19 +1276,19 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
{
ADDTOCALLSTACK("CChar::ReadScriptReduced");
bool fFullInterp = false;
bool fBlockItemAttr = false; //Set a temporary boolean to block item attributes to set on Character.

bool fBlockItemAttr = false; // Set a temporary boolean to block item attributes to set on Character.
CItem * pItem = nullptr;
while ( s.ReadKeyParse() )
{
if ( s.IsKeyHead("ON", 2) )
break;

bool fItemCreated = false; // With the current keyword, have i created an item?
int iCmd = FindTableSorted(s.GetKey(), CItem::sm_szTemplateTable, ARRAY_COUNT(CItem::sm_szTemplateTable)-1);
bool fItemCreation = false;
if (iCmd == ITC_FUNC)
{
if (!pItem)
if (!pItem || fBlockItemAttr)
continue;

lptstr ptcFunctionName = s.GetArgRaw();
Expand All @@ -1305,9 +1305,10 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
pItem->r_Call(ptcFunctionName, this, pScriptArgs.get());
if (pItem->IsDeleted())
{
fItemCreation = false;
g_Log.EventDebug("FUNC deleted the item.\n");
pItem = nullptr;
//g_Log.EventDebug("FUNC deleted the item.\n");
}
continue;
}
else if ( fVendor )
{
Expand All @@ -1319,7 +1320,7 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
case ITC_SELL:
{
fBlockItemAttr = false; //Make sure we reset the value, if the last input is not a ITEM(NEWBIE) or CONTAINER.
CItemContainer * pCont = GetBank((iCmd == ITC_SELL) ? LAYER_VENDOR_STOCK : LAYER_VENDOR_BUYS );
CItemContainer * pCont = GetBank((iCmd == ITC_SELL) ? LAYER_VENDOR_STOCK : LAYER_VENDOR_BUYS);
if ( pCont )
{
pItem = CItem::CreateHeader(s.GetArgRaw(), pCont, false);
Expand All @@ -1329,6 +1330,7 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
pItem = nullptr;
continue;
}
//case ITC_BREAK: // I don't find a use case for that...
case ITC_ITEM:
case ITC_CONTAINER:
case ITC_ITEMNEWBIE:
Expand Down Expand Up @@ -1374,7 +1376,8 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
case ITC_CONTAINER:
case ITC_ITEMNEWBIE:
{
fItemCreation = true;
fBlockItemAttr = false;
fItemCreated = true;

if (IsStatFlag(STATF_CONJURED) && iCmd != ITC_ITEMNEWBIE) // This check is not needed (sure?).
break; // conjured creates have no loot.
Expand Down Expand Up @@ -1419,10 +1422,11 @@ bool CChar::ReadScriptReduced(CResourceLock &s, bool fVendor)
else
pItem->r_LoadVal( s );
}
else if (!fItemCreation)
else if (!fItemCreated)
{
// I'm setting an attribute to myself, not the item (e.g. @Create trigger). Run that script line.
TRIGRET_TYPE tRet = OnTriggerRun( s, TRIGRUN_SINGLE_EXEC, &g_Serv, nullptr, nullptr );
if ( (tRet == TRIGRET_RET_FALSE) && fFullInterp )
if ((tRet == TRIGRET_RET_FALSE) && fFullInterp)
;
else if ( tRet != TRIGRET_RET_DEFAULT )
{
Expand Down
47 changes: 33 additions & 14 deletions src/game/items/CItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,35 +582,31 @@ CItem * CItem::ReadTemplate( CResourceLock & s, CObjBase * pCont ) // static
}
}

bool fItemAttrib = false;
CItem * pNewTopCont = nullptr;
CItem * pItem = nullptr;
while ( s.ReadKeyParse())
{
if ( s.IsKeyHead( "ON", 2 ))
break;

int index = FindTableSorted( s.GetKey(), sm_szTemplateTable, ARRAY_COUNT( sm_szTemplateTable )-1 );
switch (index)
int iCmd = FindTableSorted( s.GetKey(), sm_szTemplateTable, ARRAY_COUNT( sm_szTemplateTable )-1 );
switch (iCmd)
{
case ITC_BUY: // "BUY"
case ITC_SELL: // "SELL"
fItemAttrib = false;
if (pVendorBuy != nullptr)
{
pItem = CItem::CreateHeader( s.GetArgRaw(), (index==ITC_SELL)?pVendorSell:pVendorBuy, false );
pItem = CItem::CreateHeader(s.GetArgRaw(), (iCmd == ITC_SELL) ? pVendorSell : pVendorBuy, false);
if ( pItem == nullptr )
continue;
if ( pItem->IsItemInContainer())
{
fItemAttrib = true;
pItem->SetContainedLayer( (char)(pItem->GetAmount())); // set the Restock amount.
pItem->SetContainedLayer(i16_narrow8(pItem->GetAmount())); // set the Restock amount.
}
}
continue;

case ITC_CONTAINER:
fItemAttrib = false;
{
pItem = CItem::CreateHeader( s.GetArgRaw(), pCont, false, pVendor );
if ( pItem == nullptr )
Expand All @@ -620,7 +616,6 @@ CItem * CItem::ReadTemplate( CResourceLock & s, CObjBase * pCont ) // static
DEBUG_ERR(( "CreateTemplate: CContainer %s is not a container\n", pItem->GetResourceName() ));
else
{
fItemAttrib = true;
if ( ! pNewTopCont )
pNewTopCont = pItem;
}
Expand All @@ -629,16 +624,40 @@ CItem * CItem::ReadTemplate( CResourceLock & s, CObjBase * pCont ) // static

case ITC_ITEM:
case ITC_ITEMNEWBIE:
fItemAttrib = false;
if ( pCont == nullptr && pItem != nullptr )
continue; // Don't create anymore items til we have some place to put them !
continue; // Don't create anymore items until we have some place to put them !
pItem = CItem::CreateHeader( s.GetArgRaw(), pCont, false, pVendor );
if ( pItem != nullptr )
fItemAttrib = true;
continue;

case ITC_FUNC:
if (!pItem)
continue;
{
lptstr ptcFunctionName = s.GetArgRaw();
std::unique_ptr<CScriptTriggerArgs> pScriptArgs;
// Locate arguments for the called function
tchar* ptcArgs = strchr(ptcFunctionName, ' ');
if (ptcArgs)
{
*ptcArgs = 0;
++ptcArgs;
GETNONWHITESPACE(ptcArgs);
pScriptArgs = std::make_unique<CScriptTriggerArgs>(ptcArgs);
}

CObjBaseTemplate* pContObjBaseT = pCont->GetTopLevelObj();
ASSERT(pContObjBaseT);
pItem->r_Call(ptcFunctionName, dynamic_cast<CTextConsole*>(pContObjBaseT), pScriptArgs.get());
if (pItem->IsDeleted())
{
pItem = nullptr;
//g_Log.EventDebug("FUNC deleted the template item.\n");
}
continue;
}
}

if ( pItem != nullptr && fItemAttrib )
if ( pItem != nullptr )
pItem->r_LoadVal( s );
}

Expand Down

0 comments on commit 8f306c1

Please sign in to comment.