From: Laszlo T. <ave...@us...> - 2006-12-28 21:05:47
|
Update of /cvsroot/gemrb/gemrb/gemrb/plugins/GUIScript In directory sc8-pr-cvs2.sourceforge.net:/tmp/cvs-serv8243 Modified Files: GUIScript.cpp Log Message: fix for bug#1622948 (swapping items) Index: GUIScript.cpp =================================================================== RCS file: /cvsroot/gemrb/gemrb/gemrb/plugins/GUIScript/GUIScript.cpp,v retrieving revision 1.434 retrieving revision 1.435 diff -C2 -d -r1.434 -r1.435 *** GUIScript.cpp 28 Dec 2006 14:26:17 -0000 1.434 --- GUIScript.cpp 28 Dec 2006 21:05:45 -0000 1.435 *************** *** 116,120 **** EffectRef learn_spell_ref={"Spell:Learn",NULL,-1}; ! inline bool valid_number(const char* string, long& val) { char* endpr; --- 116,120 ---- EffectRef learn_spell_ref={"Spell:Learn",NULL,-1}; ! static inline bool valid_number(const char* string, long& val) { char* endpr; *************** *** 125,129 **** // Like PyString_FromString(), but for ResRef ! inline PyObject* PyString_FromResRef(char* ResRef) { unsigned int i; --- 125,129 ---- // Like PyString_FromString(), but for ResRef ! static inline PyObject* PyString_FromResRef(char* ResRef) { unsigned int i; *************** *** 136,140 **** // Like PyString_FromString(), but for ResRef ! inline PyObject* PyString_FromAnimID(char* AnimID) { unsigned int i; --- 136,140 ---- // Like PyString_FromString(), but for ResRef ! static inline PyObject* PyString_FromAnimID(char* AnimID) { unsigned int i; *************** *** 149,153 **** * can be called in `return'. */ ! inline PyObject* RuntimeError(char* msg) { printMessage( "GUIScript", "Runtime Error:\n", LIGHT_RED ); --- 149,153 ---- * can be called in `return'. */ ! static inline PyObject* RuntimeError(char* msg) { printMessage( "GUIScript", "Runtime Error:\n", LIGHT_RED ); *************** *** 164,168 **** * call to e.g. PyArg_ParseTuple() */ ! inline PyObject* AttributeError(char* doc_string) { printMessage( "GUIScript", "Syntax Error:\n", LIGHT_RED ); --- 164,168 ---- * call to e.g. PyArg_ParseTuple() */ ! static inline PyObject* AttributeError(char* doc_string) { printMessage( "GUIScript", "Syntax Error:\n", LIGHT_RED ); *************** *** 174,178 **** } ! inline Control *GetControl( int wi, int ci, int ct) { char errorbuffer[256]; --- 174,178 ---- } ! static inline Control *GetControl( int wi, int ci, int ct) { char errorbuffer[256]; *************** *** 219,222 **** --- 219,368 ---- } + static inline void DragItem(CREItem *si) + { + if (!si) { + return; + } + Item *item = core->GetItem (si->ItemResRef ); + if (!item) { + return; + } + core->DragItem(si, item->ItemIcon); + core->FreeItem( item, si->ItemResRef, false ); + } + + static void ReadSpecialSpells() + { + int i; + + SpecialSpellsCount = 0; + int table = core->LoadTable("splspec"); + if (table>=0) { + TableMgr *tab = core->GetTable(table); + if (!tab) goto table_loaded; + SpecialSpellsCount = tab->GetRowCount(); + SpecialSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialSpellsCount); + for (i=0;i<SpecialSpellsCount;i++) { + strnlwrcpy(SpecialSpells[i].resref, tab->GetRowName(i),8 ); + //if there are more flags, compose this value into a bitfield + SpecialSpells[i].value = atoi(tab->QueryField(i,0) ); + } + table_loaded: + core->DelTable(table); + } + } + + static void ReadUsedItems() + { + int i; + + UsedItemsCount = 0; + int table = core->LoadTable("item_use"); + if (table>=0) { + TableMgr *tab = core->GetTable(table); + if (!tab) goto table_loaded; + UsedItemsCount = tab->GetRowCount(); + UsedItems = (UsedItemType *) malloc( sizeof(UsedItemType) * UsedItemsCount); + for (i=0;i<UsedItemsCount;i++) { + strnlwrcpy(UsedItems[i].itemname, tab->GetRowName(i),8 ); + strnlwrcpy(UsedItems[i].username, tab->QueryField(i,0),32 ); + //if there are more flags, compose this value into a bitfield + UsedItems[i].value = atoi(tab->QueryField(i,1) ); + } + table_loaded: + core->DelTable(table); + } + } + + static void ReadSpecialItems() + { + int i; + + SpecialItemsCount = 0; + int table = core->LoadTable("itemspec"); + if (table>=0) { + TableMgr *tab = core->GetTable(table); + if (!tab) goto table_loaded; + SpecialItemsCount = tab->GetRowCount(); + SpecialItems = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialItemsCount); + for (i=0;i<SpecialItemsCount;i++) { + strnlwrcpy(SpecialItems[i].resref, tab->GetRowName(i),8 ); + //if there are more flags, compose this value into a bitfield + SpecialItems[i].value = atoi(tab->QueryField(i,0) ); + } + table_loaded: + core->DelTable(table); + } + } + + static ieStrRef GetSpellDesc(ieResRef CureResRef) + { + int i; + + if (StoreSpellsCount==-1) { + StoreSpellsCount = 0; + int table = core->LoadTable("speldesc"); + if (table>=0) { + TableMgr *tab = core->GetTable(table); + if (!tab) goto table_loaded; + StoreSpellsCount = tab->GetRowCount(); + StoreSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * StoreSpellsCount); + for (i=0;i<StoreSpellsCount;i++) { + strnlwrcpy(StoreSpells[i].resref, tab->GetRowName(i),8 ); + StoreSpells[i].value = atoi(tab->QueryField(i,0) ); + } + table_loaded: + core->DelTable(table); + } + } + if (StoreSpellsCount==0) { + Spell *spell = core->GetSpell(CureResRef); + if (!spell) { + return 0; + } + int ret = spell->SpellDescIdentified; + core->FreeSpell(spell, CureResRef, 0); + return ret; + } + for (i=0;i<StoreSpellsCount;i++) { + if (!strnicmp(StoreSpells[i].resref, CureResRef, 8) ) { + return StoreSpells[i].value; + } + } + return 0; + } + + static CREItem *TryToUnequip(Actor *actor, unsigned int Slot, unsigned int Count) + { + CREItem *si = NULL; + + ///check if item is undroppable because the actor likes it + if (UsedItemsCount==-1) { + ReadUsedItems(); + } + unsigned int i=UsedItemsCount; + //we should use GetSlotItem here. + //getitem would remove the item from the inventory! + si = actor->inventory.GetSlotItem(Slot); + while(i--) { + if (UsedItems[i].itemname[0] && strnicmp(UsedItems[i].itemname, si->ItemResRef,8) ) { + continue; + } + if (UsedItems[i].username[0] && strnicmp(UsedItems[i].username, actor->GetScriptName(), 32) ) { + continue; + } + core->DisplayString(UsedItems[i].value,0xffffff, IE_STR_SOUND); + return NULL; + } + ///fixme: make difference between cursed/unmovable + if (! actor->inventory.UnEquipItem( Slot, false )) { + // Item is currently undroppable/cursed + core->DisplayConstantString(STR_CANT_DROP_ITEM,0xffffff); + return NULL; + } + si = actor->inventory.RemoveItem( Slot, Count ); + return si; + } + PyDoc_STRVAR( GemRB_SetInfoTextColor__doc, "SetInfoTextColor(red, green, blue, [alpha])\n\n" *************** *** 5101,5205 **** } - static void ReadSpecialSpells() - { - int i; - - SpecialSpellsCount = 0; - int table = core->LoadTable("splspec"); - if (table>=0) { - TableMgr *tab = core->GetTable(table); - if (!tab) goto table_loaded; - SpecialSpellsCount = tab->GetRowCount(); - SpecialSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialSpellsCount); - for (i=0;i<SpecialSpellsCount;i++) { - strnlwrcpy(SpecialSpells[i].resref, tab->GetRowName(i),8 ); - //if there are more flags, compose this value into a bitfield - SpecialSpells[i].value = atoi(tab->QueryField(i,0) ); - } - table_loaded: - core->DelTable(table); - } - } - - static void ReadUsedItems() - { - int i; - - UsedItemsCount = 0; - int table = core->LoadTable("item_use"); - if (table>=0) { - TableMgr *tab = core->GetTable(table); - if (!tab) goto table_loaded; - UsedItemsCount = tab->GetRowCount(); - UsedItems = (UsedItemType *) malloc( sizeof(UsedItemType) * UsedItemsCount); - for (i=0;i<UsedItemsCount;i++) { - strnlwrcpy(UsedItems[i].itemname, tab->GetRowName(i),8 ); - strnlwrcpy(UsedItems[i].username, tab->QueryField(i,0),32 ); - //if there are more flags, compose this value into a bitfield - UsedItems[i].value = atoi(tab->QueryField(i,1) ); - } - table_loaded: - core->DelTable(table); - } - } - - static void ReadSpecialItems() - { - int i; - - SpecialItemsCount = 0; - int table = core->LoadTable("itemspec"); - if (table>=0) { - TableMgr *tab = core->GetTable(table); - if (!tab) goto table_loaded; - SpecialItemsCount = tab->GetRowCount(); - SpecialItems = (SpellDescType *) malloc( sizeof(SpellDescType) * SpecialItemsCount); - for (i=0;i<SpecialItemsCount;i++) { - strnlwrcpy(SpecialItems[i].resref, tab->GetRowName(i),8 ); - //if there are more flags, compose this value into a bitfield - SpecialItems[i].value = atoi(tab->QueryField(i,0) ); - } - table_loaded: - core->DelTable(table); - } - } - - static ieStrRef GetSpellDesc(ieResRef CureResRef) - { - int i; - - if (StoreSpellsCount==-1) { - StoreSpellsCount = 0; - int table = core->LoadTable("speldesc"); - if (table>=0) { - TableMgr *tab = core->GetTable(table); - if (!tab) goto table_loaded; - StoreSpellsCount = tab->GetRowCount(); - StoreSpells = (SpellDescType *) malloc( sizeof(SpellDescType) * StoreSpellsCount); - for (i=0;i<StoreSpellsCount;i++) { - strnlwrcpy(StoreSpells[i].resref, tab->GetRowName(i),8 ); - StoreSpells[i].value = atoi(tab->QueryField(i,0) ); - } - table_loaded: - core->DelTable(table); - } - } - if (StoreSpellsCount==0) { - Spell *spell = core->GetSpell(CureResRef); - if (!spell) { - return 0; - } - int ret = spell->SpellDescIdentified; - core->FreeSpell(spell, CureResRef, 0); - return ret; - } - for (i=0;i<StoreSpellsCount;i++) { - if (!strnicmp(StoreSpells[i].resref, CureResRef, 8) ) { - return StoreSpells[i].value; - } - } - return 0; - } - PyDoc_STRVAR( GemRB_GetStoreCure__doc, "GetStoreCure(idx) => dictionary\n\n" --- 5247,5250 ---- *************** *** 5914,5946 **** si = cc->RemoveItem(Slot, Count); } else { ! ! ///check if item is undroppable because the actor likes it ! if (UsedItemsCount==-1) { ! ReadUsedItems(); ! } ! Slot = core->QuerySlot(Slot); ! unsigned int i=UsedItemsCount; ! //we should use GetSlotItem here. ! //getitem would remove the item from the inventory! ! si = actor->inventory.GetSlotItem(Slot); ! while(i--) { ! if (UsedItems[i].itemname[0] && strnicmp(UsedItems[i].itemname, si->ItemResRef,8) ) { ! continue; ! } ! if (UsedItems[i].username[0] && strnicmp(UsedItems[i].username, actor->GetScriptName(), 32) ) { ! continue; ! } ! core->DisplayString(UsedItems[i].value,0xffffff, IE_STR_SOUND); ! Py_INCREF( Py_None ); ! return Py_None; ! } ! ///fixme: make difference between cursed/unmovable ! if (! actor->inventory.UnEquipItem( Slot, false )) { ! // Item is currently undroppable/cursed ! core->DisplayConstantString(STR_CANT_DROP_ITEM,0xffffff); ! Py_INCREF( Py_None ); ! return Py_None; ! } ! si = actor->inventory.RemoveItem( Slot, Count ); actor->RefreshEffects(); actor->ReinitQuickSlots(); --- 5959,5963 ---- si = cc->RemoveItem(Slot, Count); } else { ! si = TryToUnequip( actor, core->QuerySlot(Slot), Count ); actor->RefreshEffects(); actor->ReinitQuickSlots(); *************** *** 5964,5968 **** "If Slot==-2, puts it to a ground pile. " "If Slot==-3, puts it to the first empty inventory slot. " ! "Returns 0 (unsuccessful), 1 (partial success) or 2 (complete success)." ); static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args) --- 5981,5986 ---- "If Slot==-2, puts it to a ground pile. " "If Slot==-3, puts it to the first empty inventory slot. " ! "Returns 0 (unsuccessful), 1 (partial success) or 2 (complete success)." ! "Can also return 3 (swapped item)\n" ); static PyObject* GemRB_DropDraggedItem(PyObject * /*self*/, PyObject* args) *************** *** 5998,6048 **** } res = cc->AddItem(core->GetDraggedItem()); ! } else { ! int Slottype, Effect; ! switch(Slot) { ! case -1: ! //anything but inventory ! Slottype = ~SLOT_INVENTORY; ! Effect = 1; ! break; ! case -3: ! //only inventory ! Slottype = -1; ! Effect = 0; ! break; ! default: ! Slot = core->QuerySlot(Slot); ! Slottype = core->QuerySlotType( Slot ); ! Effect = core->QuerySlotEffects( Slot ); ! } ! CREItem * slotitem = core->GetDraggedItem(); ! Item *item = core->GetItem( slotitem->ItemResRef ); ! if (!item) { ! return PyInt_FromLong( -1 ); ! } ! // can't equip item because of similar already equipped ! if (Effect && item->ItemExcl & actor->inventory.GetEquipExclusion()) { ! return PyInt_FromLong( 0 ); } ! int Itemtype = item->ItemType; ! int Use1 = item->UsabilityBitmask; ! int Use2 = item->KitUsability; ! core->FreeItem( item, slotitem->ItemResRef, false ); ! //CanUseItemType will check actor's class bits too ! Slottype =core->CanUseItemType (Itemtype, Slottype, Use1, Use2, actor); ! if ( Slottype) { ! res = actor->inventory.AddSlotItem( slotitem, Slot, Slottype ); ! actor->RefreshEffects(); ! actor->ReinitQuickSlots(); } else { res = 0; } } ! ! if (res == 2) { ! // Whole amount was placed ! core->ReleaseDraggedItem (); ! } ! //this is PST specific, change animation core->GetGUIScriptEngine()->RunFunction("UpdateAnimation", false); --- 6016,6081 ---- } res = cc->AddItem(core->GetDraggedItem()); ! if (res == 2) { ! // Whole amount was placed ! core->ReleaseDraggedItem (); } ! return PyInt_FromLong( res ); ! } ! ! int Slottype, Effect; ! switch(Slot) { ! case -1: ! //anything but inventory ! Slottype = ~SLOT_INVENTORY; ! Effect = 1; ! break; ! case -3: ! //only inventory ! Slottype = -1; ! Effect = 0; ! break; ! default: ! Slot = core->QuerySlot(Slot); ! Slottype = core->QuerySlotType( Slot ); ! Effect = core->QuerySlotEffects( Slot ); ! } ! CREItem * slotitem = core->GetDraggedItem(); ! Item *item = core->GetItem( slotitem->ItemResRef ); ! if (!item) { ! return PyInt_FromLong( -1 ); ! } ! // can't equip item because of similar already equipped ! if (Effect && item->ItemExcl & actor->inventory.GetEquipExclusion()) { ! return PyInt_FromLong( 0 ); ! } ! int Itemtype = item->ItemType; ! int Use1 = item->UsabilityBitmask; ! int Use2 = item->KitUsability; ! core->FreeItem( item, slotitem->ItemResRef, false ); ! //CanUseItemType will check actor's class bits too ! Slottype =core->CanUseItemType (Itemtype, Slottype, Use1, Use2, actor); ! if ( !Slottype) { ! return PyInt_FromLong( 0 ); ! } ! res = actor->inventory.AddSlotItem( slotitem, Slot, Slottype ); ! //couldn't place item there, try swapping (only if slot is explicit) ! if ((res == 0) && (Slot >= 0) ) { ! CREItem *tmp = TryToUnequip(actor, Slot, 0 ); ! if (tmp) { ! //this addslotitem MUST succeed because the slot was ! //just emptied (canuseitemtype already confirmed too) ! actor->inventory.AddSlotItem( slotitem, Slot, Slottype ); ! core->ReleaseDraggedItem (); ! DragItem(tmp); ! res = 3; } else { res = 0; } + goto done; } ! core->ReleaseDraggedItem (); ! done: ! actor->RefreshEffects(); ! actor->ReinitQuickSlots(); //this is PST specific, change animation core->GetGUIScriptEngine()->RunFunction("UpdateAnimation", false); |