d2tools/src/D2Item.php

163 lines
6.2 KiB
PHP

<?php
require_once 'D2BitReader.php';
require_once 'D2ItemStructureData.php';
/**
*
*/
class D2Item {
/**
* @var null
*/
private $bits = null;
/**
* @var null
*/
public $iData = null;
/**
* @param $bits
*/
public function __construct($bits) {
if ($bits == '')
return false;
$this->bits = $bits;
return $this->parseItem();
}
/* set $this->iData to array of item details
*
* @return array of item details
*/
/**
* @return null
*/
private function parseItem() {
$b = new D2BitReader($this->bits);
$b->skip(16); // Skip JM
$b->skip(4); // skip unknown 4 bytes
$this->iData['identified'] = $b->read(1); // bit 20, identified
$b->skip(6); // skip unknown 6 bytes
$this->iData['socketed'] = $b->read(1); // bit 27, socketed
$b->skip(1);
// This bit is set on items which you have picked up since the last time the game was saved.
$this->iData['pickedUpSinceLastSave'] = $b->read(1); // bit 29
$b->skip(2);
$this->iData['ear'] = $b->read(1); // bit 32 bool
$this->iData['startingItem'] = $b->read(1); // bit 33 bool
$b->skip(3);
$this->iData['compact'] = $b->read(1); // bit 37 compact
$this->iData['ethereal'] = $b->read(1); // bit 38 ethereal
$b->skip(1); // unknown, seems always 1
$this->iData['personalized'] = $b->read(1); // bit 40 Item has been personalized (by Anya in Act V)
$b->skip(1);
$this->iData['runeword'] = $b->read(1); // bit 42 the item has been given a Rune Word.
$b->skip(15); // unknown; some of these bits may be set
// item location
$location = bindec($b->readr(3)); // bit 58 parent Item location.
$body = bindec($b->readr(4)); // bit 61 If the item is equipped
$col = bindec($b->readr(4)); // bit 65 Column number of the left corner of the item
$row = bindec($b->readr(4)); // bit 69 Row number of the top of the item, counting from 0.
$_stored = bindec($b->readr(3)); // bit 73
// weird behavior/bug
// if item is in a container, bodypart will be NULL
// if item is on bodypart, container will be NULL
switch ($location) {
case D2ItemLocation::STORED:
switch ($_stored) {
case D2ItemLocationStored::NONE:
$this->iData['container'] = ''; // item is not stored, check bit 58
break;
case D2ItemLocationStored::INVENTORY:
$this->iData['container'] = 'Inventory';
break;
case D2ItemLocationStored::CUBE:
$this->iData['container'] = 'Horadric Cube';
break;
case D2ItemLocationStored::STASH:
$this->iData['container'] = 'Stash';
break;
default: $this->iData['container'] = 'Unknown';
break;
}
break;
case D2ItemLocation::EQUIPPED:
switch ($body) {
case D2ItemLocationBody::HELMET: $this->iData['bodypart'] = 'Helmet';
break;
case D2ItemLocationBody::AMULET: $this->iData['bodypart'] = 'Amulet';
break;
case D2ItemLocationBody::ARMOR: $this->iData['bodypart'] = 'Armor';
break;
case D2ItemLocationBody::WEAPONR: $this->iData['bodypart'] = 'Weapon R';
break;
case D2ItemLocationBody::WEAPONL: $this->iData['bodypart'] = 'Weapon L';
break;
case D2ItemLocationBody::RINGR: $this->iData['bodypart'] = 'Ring R';
break;
case D2ItemLocationBody::RINGL: $this->iData['bodypart'] = 'Ring L';
break;
case D2ItemLocationBody::BELT: $this->iData['bodypart'] = 'Belt';
break;
case D2ItemLocationBody::BOOTS: $this->iData['bodypart'] = 'Boots';
break;
case D2ItemLocationBody::GLOVES: $this->iData['bodypart'] = 'Gloves';
break;
case D2ItemLocationBody::WEAPONR2: $this->iData['bodypart'] = 'Weapon Alt R';
break;
case D2ItemLocationBody::WEAPONL2: $this->iData['bodypart'] = 'Weapon Alt L';
break;
default: $this->iData['bodypart'] = 'Unknown';
break;
}
break;
}
// if item is ear
if ($this->iData['ear']){
// set item code/basename
$this->iData['itemCode'] = 'ear';
$this->iData['basename'] = 'Ear';
// get ear class/level
$eclass = bindec($b->readr(3)); // bit 76
$elevel = bindec($b->readr(7)); // bit 79
// get ear char's name
}
// get item code
$b->seek(76);
$itemCode = '';
foreach (str_split($b->read(32), 8) as $byte) {
$itemCode .= chr(bindec(strrev($byte)));
}
$this->iData['itemCode'] = trim($itemCode);
// get namestr
$sql = "SELECT code,namestr FROM armor WHERE code='{$this->iData['itemCode']}'";
$res = PDO_FetchAssoc($sql);
if (empty($res)){
$sql = "SELECT code,namestr FROM misc WHERE code='{$this->iData['itemCode']}'";
$res = PDO_FetchAssoc($sql);
}
if (empty($res)){
$sql = "SELECT code,namestr FROM weapons WHERE code='{$this->iData['itemCode']}'";
$res = PDO_FetchAssoc($sql);
}
$sql = "SELECT `String` FROM strings WHERE `Key`='{$res[$this->iData['itemCode']]}'";
$res = PDO_FetchOne($sql);
$this->iData['basename'] = $res;
return $this->iData;
}
}