int Item::UseCharge(ieWord *Charges, int header, bool expend) const { ITMExtHeader *ieh = GetExtHeader(header); if (!ieh) return 0; int type = ieh->ChargeDepletion; int ccount = 0; if ((header>=CHARGE_COUNTERS) || (header<0) || MaxStackAmount) { header = 0; } ccount=Charges[header]; //if the item started from 0 charges, then it isn't depleting if (ieh->Charges==0) { return CHG_NONE; } if (expend) { Charges[header] = --ccount; } if (ccount>0) { return CHG_NONE; } if (type == CHG_NONE) { Charges[header]=0; } return type; }
//get the casting distance of the spell //it depends on the casting level of the actor //if actor isn't given, then the first header is used unsigned int Spell::GetCastingDistance(Scriptable *Sender) const { int level = 0; Actor *actor = NULL; if (Sender && Sender->Type==ST_ACTOR) { actor = (Actor *) Sender; level = actor->GetCasterLevel(SpellType); } if (level<1) { level = 1; } int idx = GetHeaderIndexFromLevel(level); SPLExtHeader *seh = GetExtHeader(idx); if (!seh) { Log(ERROR, "Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d", idx, (int) ExtHeaderCount); return 0; } if (seh->Target==TARGET_DEAD) { return 0xffffffff; } return (unsigned int) seh->Range; }
unsigned int Item::GetCastingDistance(int idx) const { ITMExtHeader *seh = GetExtHeader(idx); if (!seh) { Log(ERROR, "Item", "Cannot retrieve item header!!! required header: %d, maximum: %d", idx, (int) ExtHeaderCount); return 0; } return (unsigned int) seh->Range; }
Projectile *Spell::GetProjectile(Scriptable *self, int header, int level, const Point &target) const { SPLExtHeader *seh = GetExtHeader(header); if (!seh) { Log(ERROR, "Spell", "Cannot retrieve spell header!!! required header: %d, maximum: %d", header, (int) ExtHeaderCount); return NULL; } Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(seh->ProjectileAnimation); if (seh->FeatureCount) { pro->SetEffects(GetEffectBlock(self, target, header, level, seh->ProjectileAnimation)); } return pro; }
//returns a projectile loaded with the effect queue Projectile *Item::GetProjectile(Scriptable *self, int header, const Point &target, ieDwordSigned invslot, int miss) const { ITMExtHeader *eh = GetExtHeader(header); if (!eh) { return NULL; } ieDword idx = eh->ProjectileAnimation; Projectile *pro = core->GetProjectileServer()->GetProjectileByIndex(idx); int usage ; if (header>= 0) usage = header; else usage = GetWeaponHeaderNumber(header==-2); if (!miss) { EffectQueue *fx = GetEffectBlock(self, target, usage, invslot, idx); pro->SetEffects(fx); } return pro; }
int Item::GetEquipmentHeaderNumber(int cnt) const { for(int ehc=0; ehc<ExtHeaderCount; ehc++) { ITMExtHeader *ext_header = GetExtHeader(ehc); if (ext_header->Location!=ITEM_LOC_EQUIPMENT) { continue; } if (ext_header->AttackType!=ITEM_AT_MAGIC) { continue; } if (cnt) { cnt--; continue; } return ehc; } return 0xffff; //invalid extheader number }
int Item::GetWeaponHeaderNumber(bool ranged) const { for(int ehc=0; ehc<ExtHeaderCount; ehc++) { ITMExtHeader *ext_header = GetExtHeader(ehc); if (ext_header->Location!=ITEM_LOC_WEAPON) { continue; } unsigned char AType = ext_header->AttackType; if (ranged) { if ((AType!=ITEM_AT_PROJECTILE) && (AType!=ITEM_AT_BOW) ) { continue; } } else { if (AType!=ITEM_AT_MELEE) { continue; } } return ehc; } return 0xffff; //invalid extheader number }
ITMExtHeader *Item::GetWeaponHeader(bool ranged) const { //start from the beginning return GetExtHeader(GetWeaponHeaderNumber(ranged)) ; }
Item* ITMImporter::GetItem(Item *s) { unsigned int i; ieByte k1,k2,k3,k4; if( !s) { return NULL; } str->ReadDword( &s->ItemName ); str->ReadDword( &s->ItemNameIdentified ); str->ReadResRef( s->ReplacementItem ); str->ReadDword( &s->Flags ); str->ReadWord( &s->ItemType ); str->ReadDword( &s->UsabilityBitmask ); str->Read( s->AnimationType,2 ); //intentionally not reading word! for (i=0;i<2;i++) { if (s->AnimationType[i]==' ') { s->AnimationType[i]=0; } } str->Read( &s->MinLevel, 1 ); str->Read( &s->unknown1, 1 ); str->Read( &s->MinStrength,1 ); str->Read( &s->unknown2, 1 ); str->Read( &s->MinStrengthBonus, 1 ); str->Read( &k1,1 ); str->Read( &s->MinIntelligence, 1 ); str->Read( &k2,1 ); str->Read( &s->MinDexterity, 1 ); str->Read( &k3,1 ); str->Read( &s->MinWisdom, 1 ); str->Read( &k4,1 ); s->KitUsability=(k1<<24) | (k2<<16) | (k3<<8) | k4; //bg2/iwd2 specific str->Read( &s->MinConstitution, 1 ); str->Read( &s->WeaProf, 1 ); //bg2 specific //hack for non bg2 weapon proficiencies if (!s->WeaProf) { s->WeaProf = GetProficiency(s->ItemType); } str->Read( &s->MinCharisma, 1 ); str->Read( &s->unknown3, 1 ); str->ReadDword( &s->Price ); str->ReadWord( &s->MaxStackAmount ); //hack for non stacked items, so MaxStackAmount could be used as a boolean if (s->MaxStackAmount==1) { s->MaxStackAmount = 0; } str->ReadResRef( s->ItemIcon ); str->ReadWord( &s->LoreToID ); str->ReadResRef( s->GroundIcon ); str->ReadDword( &s->Weight ); str->ReadDword( &s->ItemDesc ); str->ReadDword( &s->ItemDescIdentified ); str->ReadResRef( s->DescriptionIcon ); str->ReadDword( &s->Enchantment ); str->ReadDword( &s->ExtHeaderOffset ); str->ReadWord( &s->ExtHeaderCount ); str->ReadDword( &s->FeatureBlockOffset ); str->ReadWord( &s->EquippingFeatureOffset ); str->ReadWord( &s->EquippingFeatureCount ); s->Dialog[0] = 0; s->DialogName = 0; s->WieldColor = 0xffff; memset( s->unknown, 0, 26 ); //skipping header data for iwd2 if (version == ITM_VER_IWD2) { str->Read( s->unknown, 16 ); } //pst data if (version == ITM_VER_PST) { str->ReadResRef( s->Dialog ); str->ReadDword( &s->DialogName ); ieWord WieldColor; str->ReadWord( &WieldColor ); if (s->AnimationType[0]) { s->WieldColor = WieldColor; } str->Read( s->unknown, 26 ); } else { //all non pst s->DialogName = core->GetItemDialStr(s->Name); core->GetItemDialRes(s->Name, s->Dialog); } s->ItemExcl=core->GetItemExcl(s->Name); s->ext_headers = core->GetITMExt( s->ExtHeaderCount ); for (i = 0; i < s->ExtHeaderCount; i++) { str->Seek( s->ExtHeaderOffset + i * 56, GEM_STREAM_START ); GetExtHeader( s, s->ext_headers + i ); } //48 is the size of the feature block s->equipping_features = core->GetFeatures( s->EquippingFeatureCount); str->Seek( s->FeatureBlockOffset + 48*s->EquippingFeatureOffset, GEM_STREAM_START ); for (i = 0; i < s->EquippingFeatureCount; i++) { GetFeature(s->equipping_features+i); } if (!core->IsAvailable( IE_BAM_CLASS_ID )) { print( "[ITMImporter]: No BAM Importer Available.\n" ); return NULL; } return s; }