bool CRecentImp<T, S>::AppendItem( ReceiveType pItemData ) { int i; if( !IsAvailable() ) return false; if( !pItemData ) return false; if( false == ValidateReceiveType(pItemData) ) return false; //登録済みか調べる。 int nIndex = FindItem( pItemData ); if( nIndex >= 0 ) { CopyItem( GetItemPointer(nIndex), pItemData ); //先頭に持ってくる。 MoveItem( nIndex, 0 ); goto reconfigure; } //いっぱいのときは最古の通常アイテムを削除する。 if( m_nArrayCount <= *m_pnUserItemCount ) { nIndex = GetOldestItem( *m_pnUserItemCount - 1, false ); if( -1 == nIndex ) { return false; } DeleteItem( nIndex ); } for( i = *m_pnUserItemCount; i > 0; i-- ) { CopyItem( i - 1, i ); } CopyItem( GetItemPointer(0), pItemData ); //(void)SetFavorite( 0, true ); //内部処理しないとだめ。 if( m_pbUserItemFavorite ) m_pbUserItemFavorite[0] = false; *m_pnUserItemCount += 1; reconfigure: //お気に入りを表示内に移動する。 if( m_pnUserViewCount ) { ChangeViewCount( *m_pnUserViewCount ); } return true; }
bool CRecentImp<T, S>::CopyItem( int nSrcIndex, int nDstIndex ) { if( ! IsAvailable() ) return false; if( nSrcIndex < 0 || nSrcIndex >= m_nArrayCount ) return false; if( nDstIndex < 0 || nDstIndex >= m_nArrayCount ) return false; if( nSrcIndex == nDstIndex ) return true; memcpy_raw( GetItemPointer( nDstIndex ), GetItemPointer( nSrcIndex ), sizeof(DataType) ); //(void)SetFavorite( nDstIndex, IsFavorite( nSrcIndex ) ); //内部処理しないとだめ。 if( m_pbUserItemFavorite ) m_pbUserItemFavorite[nDstIndex] = m_pbUserItemFavorite[nSrcIndex]; return true; }
const CItem &CItemCtx::GetItem(void) // GetItem // // Returns the item struct { // If we've got an item, then return a reference to it // Whoever set this is responsible to guaranteeing its lifespan if (m_pItem) return *m_pItem; // Otherwise, we need to cons one up const CItem *pItem = GetItemPointer(); if (pItem == NULL) return CItem::GetNullItem(); // We cache it for later m_Item = *pItem; m_pItem = &m_Item; // Done return *m_pItem; }
void Inventory::AddSlotEffects(ieDword index) { CREItem* slot; const Item *itm = GetItemPointer(index, slot); if (!itm) { printMessage("Inventory","Invalid item equipped...\n",LIGHT_RED); return; } ItemExcl|=itm->ItemExcl; ieDword pos = itm->ItemType/32; ieDword bit = itm->ItemType%32; if (pos<4) { ItemTypes[pos]|=1<<bit; } ieWord gradient = itm->GetWieldedGradient(); if (gradient!=0xffff) { Owner->SetBase(IE_COLORS, gradient); } //get the equipping effects EffectQueue *eqfx = itm->GetEffectBlock(-1, index, 0); gamedata->FreeItem( itm, slot->ItemResRef, false ); Owner->RefreshEffects(eqfx); //call gui for possible paperdoll animation changes if (Owner->InParty) { core->SetEventFlag(EF_UPDATEANIM); } }
bool CRecentImp<T, S>::EditItemText( int nIndex, LPCTSTR pText ) { DataType data; ReceiveType receiveData; memcpy_raw( &data, GetItemPointer( nIndex ), sizeof(data) ); if( !TextToDataType( &data, pText ) ){ return false; } if( !DataToReceiveType( &receiveData, &data ) ){ return false; } int findIndex = FindItem( receiveData ); if( -1 != findIndex && nIndex != findIndex ){ // 重複不可。ただし同じ場合は大文字小文字の変更かもしれないのでOK return false; } CopyItem( GetItemPointer(nIndex), receiveData ); return true; }
void Inventory::UpdateWeaponAnimation() { int slot = GetEquippedSlot(); int effect = core->QuerySlotEffects( slot ); if (effect == SLOT_EFFECT_MISSILE) { // ranged weapon slot = FindRangedWeapon(); } int WeaponType = -1; char AnimationType[2]={0,0}; ieWord MeleeAnimation[3]={100,0,0}; CREItem *Slot; // TODO: fix bows? ITMExtHeader *header = 0; const Item *itm = GetItemPointer(slot, Slot); if (itm) { itm->GetDamagePotential(false, header); memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) ); //for twohanded flag, you don't need itm if (Slot->Flags & IE_INV_ITEM_TWOHANDED) WeaponType = IE_ANI_WEAPON_2H; else { // Examine shield slot to check if we're using two weapons // TODO: for consistency, use same Item* access method as above bool twoweapon = false; int slot = GetShieldSlot(); CREItem* si = NULL; if (slot>0) { si = GetSlotItem( (ieDword) slot ); } if (si) { Item* it = gamedata->GetItem(si->ItemResRef); if (core->CanUseItemType(SLOT_WEAPON, it)) twoweapon = true; gamedata->FreeItem(it, si->ItemResRef, false); } if (twoweapon) WeaponType = IE_ANI_WEAPON_2W; else WeaponType = IE_ANI_WEAPON_1H; } } if (header) memcpy(MeleeAnimation,header->MeleeAnimation, sizeof(MeleeAnimation) ); if (itm) gamedata->FreeItem( itm, Slot->ItemResRef, false ); Owner->SetUsedWeapon(AnimationType, MeleeAnimation, WeaponType); }
void CRecentImp<T, S>::ZeroItem( int nIndex ) { if( ! IsAvailable() ) return; if( nIndex < 0 || nIndex >= m_nArrayCount ) return; memset_raw( GetItemPointer( nIndex ), 0, sizeof(DataType) ); if( m_pbUserItemFavorite ) m_pbUserItemFavorite[nIndex] = false; return; }
int CRecentImp<T, S>::FindItem( ReceiveType pItemData ) const { if( !IsAvailable() ) return -1; if( !pItemData ) return -1; for( int i = 0; i < *m_pnUserItemCount; i++ ) { if( CompareItem(GetItemPointer(i), pItemData) == 0 )return i; } return -1; }
ICCItem *CItemCtx::CreateItemVariable(CCodeChain &CC) // CreateItemVariable // // Creates a variable for the item (or Nil) { const CItem *pItem = GetItemPointer(); if (pItem == NULL) return CC.CreateNil(); return CreateListFromItem(CC, *pItem); }
bool CRecentImp<T, S>::MoveItem( int nSrcIndex, int nDstIndex ) { int i; bool bFavorite; if( ! IsAvailable() ) return false; if( nSrcIndex < 0 || nSrcIndex >= *m_pnUserItemCount ) return false; if( nDstIndex < 0 || nDstIndex >= *m_pnUserItemCount ) return false; if( nSrcIndex == nDstIndex ) return true; DataType pri; //移動する情報を退避 memcpy_raw( &pri, GetItemPointer( nSrcIndex ), sizeof(pri) ); bFavorite = IsFavorite( nSrcIndex ); if( nSrcIndex < nDstIndex ) { for( i = nSrcIndex; i < nDstIndex; i++ ) { CopyItem( i + 1, i ); } } else { for( i = nSrcIndex; i > nDstIndex; i-- ) { CopyItem( i - 1, i ); } } //新しい位置に格納 memcpy_raw( GetItemPointer( nDstIndex ), &pri, sizeof(pri) ); SetFavorite( nDstIndex, bFavorite ); return true; }
//The slot index value is optional, if you supply it, // then ItemExcl will be returned as if the item was already unequipped ieDword Inventory::GetEquipExclusion(int index) const { if (index<0) { return ItemExcl; } CREItem *slot; const Item *itm = GetItemPointer(index, slot); if (!itm) { return ItemExcl; } ieDword ret = ItemExcl&~itm->ItemExcl; gamedata->FreeItem(itm, slot->ItemResRef, false); return ret; }
int Inventory::FindSlotRangedWeapon(unsigned int slot) const { if ((int)slot >= SLOT_MELEE) return SLOT_FIST; CREItem *Slot; Item *itm = GetItemPointer(slot, Slot); if (!itm) return SLOT_FIST; //always look for a ranged header when looking for a projectile/projector ITMExtHeader *ext_header = itm->GetWeaponHeader(true); unsigned int type = 0; if (ext_header) { type = ext_header->ProjectileQualifier; } gamedata->FreeItem(itm, Slot->ItemResRef, false); return FindTypedRangedWeapon(type); }
void Inventory::BreakItemSlot(ieDword slot) { ieResRef newItem; CREItem *Slot; const Item *itm = GetItemPointer(slot, Slot); if (!itm) return; //if it is the magic weapon slot, don't break it, just remove it, because it couldn't be removed if(slot ==(unsigned int) SLOT_MAGIC) { newItem[0]=0; } else { memcpy(newItem, itm->ReplacementItem,sizeof(newItem) ); } gamedata->FreeItem( itm, Slot->ItemResRef, true ); //this depends on setslotitemres using setslotitem SetSlotItemRes(newItem, slot, 0,0,0); }
// find the projectile // type = 1 - bow // 2 - xbow // 4 - sling //returns equipped code int Inventory::FindRangedProjectile(unsigned int type) const { for(int i=SLOT_RANGED;i<=LAST_RANGED;i++) { CREItem *Slot; const Item *itm = GetItemPointer(i, Slot); if (!itm) continue; ITMExtHeader *ext_header = itm->GetExtHeader(0); unsigned int weapontype = 0; if (ext_header) { weapontype = ext_header->ProjectileQualifier; } gamedata->FreeItem(itm, Slot->ItemResRef, false); if (weapontype & type) { return i-SLOT_MELEE; } } return IW_NO_EQUIPPED; }
// find bow for a specific projectile type int Inventory::FindTypedRangedWeapon(unsigned int type) const { if (!type) { return SLOT_FIST; } for(int i=SLOT_MELEE;i<=LAST_MELEE;i++) { CREItem *Slot; const Item *itm = GetItemPointer(i, Slot); if (!itm) continue; //always look for a ranged header when looking for a projectile/projector ITMExtHeader *ext_header = itm->GetWeaponHeader(true); int weapontype = 0; if (ext_header) { weapontype = ext_header->ProjectileQualifier; } gamedata->FreeItem(itm, Slot->ItemResRef, false); if (weapontype & type) { return i; } } return SLOT_FIST; }
void Exec_MSG_PutoutSeal(int conn, char *pMsg) { MSG_PutoutSeal *m = (MSG_PutoutSeal*)pMsg; if (pUser[conn].Mode != USER_PLAY) { SendHpMode(conn); return; } if (pUser[conn].Trade.OpponentID) { RemoveTrade(conn); return; } if (pMob[conn].MOB.CurrentScore.Hp == 0) { SendHpMode(conn); AddCrackError(conn, 1, 15); if (m->SourType == ITEM_PLACE_CARRY) SendItem(conn, m->SourType, m->SourPos, &pMob[conn].MOB.Carry[m->SourPos]); else if (m->SourType == ITEM_PLACE_CARGO) SendItem(conn, m->SourType, m->SourPos, &pUser[conn].Cargo[m->SourPos]); else SendItem(conn, m->SourType, m->SourPos, &pMob[conn].MOB.Equip[m->SourPos]); return; } if (m->GridX >= MAX_GRIDX || m->GridY >= MAX_GRIDY) { CrackLog(conn, " Drop grid, out of range"); return; } STRUCT_ITEM *item = GetItemPointer(&pMob[conn].MOB, pUser[conn].Cargo, m->SourType, m->SourPos); if (item == NULL) { sprintf(temp, "err,use item fail source %d %d", m->SourType, m->SourPos); Log(temp, "-system", 0); return; } if(item->sIndex != 3443) { CrackLog(conn, "outseal no 3443"); return; } if(item->stEffect[0].cEffect == 0) { CrackLog(conn, "outseal no effect"); return; } m->MobName[NAME_LENGTH - 1] = 0; m->MobName[NAME_LENGTH - 2] = 0; if (BASE_CheckValidString(m->MobName) == 0) { SendItem(conn, m->SourType, m->SourPos, item); return; } CharLogOut(conn); MSG_DBOutCapsule sm_outc; memset(&sm_outc, 0, sizeof(MSG_DBOutCapsule)); sm_outc.Size = sizeof(MSG_DBOutCapsule); sm_outc.Type = _MSG_DBOutCapsule; sm_outc.ID = conn; sm_outc.Slot = pUser[conn].Slot; sm_outc.SourType = m->SourType; sm_outc.SourPos = m->SourPos; sm_outc.DestType = m->DestType; sm_outc.DestPos = m->DestPos; sm_outc.GridX = m->GridX; sm_outc.GridY = m->GridY; sm_outc.WarpID = m->WarpID; strncpy(sm_outc.MobName, m->MobName, 12); sprintf(temp, "etc,outcapsule srctype:%d srcslot:%d name:%s", m->SourType, m->SourPos, m->MobName); Log(temp, pMob[conn].MOB.MobName, pUser[conn].IP); DBServerSocket.SendOneMessage((char*)&sm_outc, sizeof(MSG_DBOutCapsule)); }
void Inventory::EquipBestWeapon(int flags) { int i; int damage = -1; ieDword best_slot = SLOT_FIST; ITMExtHeader *header; CREItem *Slot; char AnimationType[2]={0,0}; ieWord MeleeAnimation[3]={100,0,0}; //cannot change equipment when holding magic weapons if (Equipped == SLOT_MAGIC-SLOT_MELEE) { return; } if (flags&EQUIP_RANGED) { for(i=SLOT_RANGED;i<LAST_RANGED;i++) { const Item *itm = GetItemPointer(i, Slot); if (!itm) continue; //best ranged int tmp = itm->GetDamagePotential(true, header); if (tmp>damage) { best_slot = i; damage = tmp; memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) ); memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) ); } gamedata->FreeItem( itm, Slot->ItemResRef, false ); } //ranged melee weapons like throwing daggers (not bows!) for(i=SLOT_MELEE;i<=LAST_MELEE;i++) { const Item *itm = GetItemPointer(i, Slot); if (!itm) continue; //best ranged int tmp = itm->GetDamagePotential(true, header); if (tmp>damage) { best_slot = i; damage = tmp; memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) ); memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) ); } gamedata->FreeItem( itm, Slot->ItemResRef, false ); } } if (flags&EQUIP_MELEE) { for(i=SLOT_MELEE;i<=LAST_MELEE;i++) { const Item *itm = GetItemPointer(i, Slot); if (!itm) continue; //the Slot flag is enough for this //though we need animation type/damagepotential anyway if (Slot->Flags&IE_INV_ITEM_BOW) continue; //best melee int tmp = itm->GetDamagePotential(false, header); if (tmp>damage) { best_slot = i; damage = tmp; memcpy(AnimationType,itm->AnimationType,sizeof(AnimationType) ); memcpy(MeleeAnimation,header->MeleeAnimation,sizeof(MeleeAnimation) ); } gamedata->FreeItem( itm, Slot->ItemResRef, false ); } } EquipItem(best_slot); UpdateWeaponAnimation(); }
/* returns true if there are more item usages not fitting in given array */ bool Inventory::GetEquipmentInfo(ItemExtHeader *array, int startindex, int count) { int pos = 0; int actual = 0; memset(array, 0, count * sizeof(ItemExtHeader) ); for(unsigned int idx=0;idx<Slots.size();idx++) { if (!core->QuerySlotEffects(idx)) { continue; } CREItem *slot; const Item *itm = GetItemPointer(idx, slot); if (!itm) { continue; } for(int ehc=0;ehc<itm->ExtHeaderCount;ehc++) { ITMExtHeader *ext_header = itm->ext_headers+ehc; if (ext_header->Location!=ITEM_LOC_EQUIPMENT) { continue; } //skipping if we cannot use the item int idreq1 = (slot->Flags&IE_INV_ITEM_IDENTIFIED); int idreq2 = ext_header->IDReq; switch (idreq2) { case ID_NO: if (idreq1) continue; break; case ID_NEED: if (!idreq1) continue; default:; } actual++; if (actual>startindex) { //store the item, return if we can't store more if (!count) { gamedata->FreeItem(itm, slot->ItemResRef, false); return true; } count--; memcpy(array[pos].itemname, slot->ItemResRef, sizeof(ieResRef) ); array[pos].slot = idx; array[pos].headerindex = ehc; int slen = ((char *) &(array[pos].itemname)) -((char *) &(array[pos].AttackType)); memcpy(&(array[pos].AttackType), &(ext_header->AttackType), slen); if (ext_header->Charges) { //don't modify ehc, it is a counter if (ehc>=CHARGE_COUNTERS) { array[pos].Charges=slot->Usages[0]; } else { array[pos].Charges=slot->Usages[ehc]; } } else { array[pos].Charges=0xffff; } pos++; } } gamedata->FreeItem(itm, slot->ItemResRef, false); } return false; }
void Exec_MSG_DropItem(int conn, char *pMsg) { MSG_DropItem *m = (MSG_DropItem*)pMsg; if (pMob[conn].MOB.CurrentScore.Hp <= 0 || pUser[conn].Mode != USER_PLAY) { AddCrackError(conn, 1, 14); SendHpMode(conn); return; } if (pUser[conn].Trade.OpponentID) { RemoveTrade(pUser[conn].Trade.OpponentID); RemoveTrade(conn); return; } if (pUser[conn].TradeMode) { SendClientMessage(conn, g_pMessageStringTable[_NN_CantWhenAutoTrade]); return; } if (m->GridX >= MAX_GRIDX || m->GridY >= MAX_GRIDY) { sprintf(temp, "err,wrong drop pos %d %d", m->GridX, m->GridY); Log(temp, pUser[conn].AccountName, pUser[conn].IP); return; } if (isDropItem == 0) return; int gridx = m->GridX; int gridy = m->GridY; int titem = GetEmptyItemGrid(&gridx, &gridy); m->GridX = gridx; m->GridY = gridy; if (titem == 0) { SendClientMessage(conn, g_pMessageStringTable[_NN_Cant_Drop_Here]); return; } if (m->SourType == ITEM_PLACE_EQUIP) { Log("err,dropitem - sourtype", pUser[conn].AccountName, pUser[conn].IP); return; } if (m->SourType) { if (m->SourType == ITEM_PLACE_CARRY) { if (m->SourPos < 0 || m->SourPos >= pMob[conn].MaxCarry) { Log("err,dropitem - carry equip", pUser[conn].AccountName, pUser[conn].IP); return; } } else { if (m->SourType != ITEM_PLACE_CARGO) { Log("err,dropitem - sourtype", pUser[conn].AccountName, pUser[conn].IP); return; } if (m->SourPos < 0 || m->SourPos >= MAX_CARGO) { Log("err,dropitem - sourpos cargo", pUser[conn].AccountName, pUser[conn].IP); return; } } } STRUCT_ITEM *SrcItem = GetItemPointer(&pMob[conn].MOB, pUser[conn].Cargo, m->SourType, m->SourPos); STRUCT_ITEM *BackupItem = GetItemPointer(&pMob[conn].MOB, pUser[conn].Cargo, m->SourType, m->SourPos); if (SrcItem == NULL || BackupItem == NULL) return; if (SrcItem->sIndex <= 0 || SrcItem->sIndex >= MAX_ITEMLIST) return; if (SrcItem->sIndex != 508 && SrcItem->sIndex != 509 && SrcItem->sIndex != 522 && (SrcItem->sIndex < 526 || SrcItem->sIndex > 537) && SrcItem->sIndex != 446 && SrcItem->sIndex != 747 && SrcItem->sIndex != 3993 && SrcItem->sIndex != 3994) { int drop = CreateItem(m->GridX, m->GridY, SrcItem, m->Rotate, 1); if (drop <= 0 || drop >= MAX_ITEM) { SendClientMessage(conn, "Can't create object(item)"); return; } char tmplog[2048]; BASE_GetItemCode(SrcItem, tmplog); sprintf(temp, "dropitem, %s", tmplog); ItemLog(temp, pUser[conn].AccountName, pUser[conn].IP); memset(SrcItem, 0, sizeof(STRUCT_ITEM)); MSG_CNFDropItem sm_ditem; memset(&sm_ditem, 0, sizeof(MSG_CNFDropItem)); sm_ditem.Type = _MSG_CNFDropItem; sm_ditem.Size = sizeof(MSG_CNFDropItem); sm_ditem.SourType = m->SourType; sm_ditem.SourPos = m->SourPos; sm_ditem.Rotate = m->Rotate; sm_ditem.GridX = m->GridX; sm_ditem.GridY = m->GridY; pUser[conn].cSock.SendOneMessage((char*)&sm_ditem, sizeof(MSG_CNFDropItem)); } else { SendClientMessage(conn, g_pMessageStringTable[_NN_Guild_Medal_Cant_Be_Droped]); return; } }