Completed
Push — master ( 9104ac...800544 )
by Karthik
14:39
created

ItemCode::extract()   B

Complexity

Conditions 7
Paths 13

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
cc 7
eloc 22
nc 13
nop 0
dl 0
loc 34
ccs 0
cts 0
cp 0
crap 56
rs 8.6346
c 0
b 0
f 0
1
<?php
2
3
namespace cyberinferno\Cabal\Helpers;
4
5
/**
6
 * Class ItemCode
7
 *
8
 * Contains methods helpful to generate item code
9
 *
10
 * @package cyberinferno\Cabal\Helpers
11
 * @author Karthik P
12
 */
13
class ItemCode
14
{
15
    const ITEM_GRADE_CONSTANT = 8192;
16
    const ITEM_BIND_ACCOUNT_CONSTANT = 4096;
17
    const ITEM_BIND_CHARACTER_CONSTANT = 524288;
18
    const ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT = 1572864;
19
20
    const MAX_BASE_ITEM_CODE = 4095;
21
    const MAX_GENERATED_ITEM_CODE = 1699839;
22
23
    const MIN_GRADE = 0;
24
    const MAX_GRADE = 15;
25
26
    /**
27
     * @var int
28
     */
29
    protected $_itemCode;
30
    protected $_itemGrade = 0;
31
    protected $_itemBinding = 0;
32
33
    /**
34
     * Item constructor.
35 36
     *
36
     * @param $itemCode
37 36
     */
38 36
    public function __construct($itemCode)
39
    {
40
        $this->_itemCode = $itemCode;
41
    }
42
43
    /**
44
     * Returns the item code
45 3
     *
46
     * @return int
47 3
     */
48
    public function getItemCode()
49
    {
50
        return $this->_itemCode;
51
    }
52
53
    /**
54
     * Returns the current grade of the item
55 12
     *
56
     * @return int
57 12
     */
58
    public function getGrade()
59
    {
60
        return $this->_itemGrade;
61
    }
62
63
    /**
64
     * Sets the grade of the item to generated
65
     *
66 12
     * @param int $value
67
     * @return ItemCode $this
68 12
     */
69 12
    public function setGrade($value)
70 3
    {
71
        $value = (int)$value;
72 12
        if ($value < self::MIN_GRADE) {
73 3
            $value = self::MIN_GRADE;
74
        }
75 12
        if ($value > self::MAX_GRADE) {
76 12
            $value = self::MAX_GRADE;
77
        }
78
        $this->_itemGrade = $value;
79
        return $this;
80
    }
81
82
    /**
83
     * Returns current item binding
84 15
     *
85
     * @return int
86 15
     */
87
    public function getBinding()
88
    {
89
        return $this->_itemBinding;
90
    }
91
92
    /**
93
     * Sets the item binding to account
94 3
     *
95
     * @return ItemCode $this
96 3
     */
97 3
    public function setAccountBinding()
98
    {
99
        $this->_itemBinding = self::ITEM_BIND_ACCOUNT_CONSTANT;
100
        return $this;
101
    }
102
103
    /**
104
     * Sets the item binding to character
105 3
     *
106
     * @return ItemCode $this
107 3
     */
108 3
    public function setCharacterBinding()
109
    {
110
        $this->_itemBinding = self::ITEM_BIND_CHARACTER_CONSTANT;
111
        return $this;
112
    }
113
114
    /**
115
     * Sets the item binding to character binding on usage
116 9
     *
117
     * @return ItemCode $this
118 9
     */
119 9
    public function setCharacterBindingOnUsage()
120
    {
121
        $this->_itemBinding = self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT;
122
        return $this;
123
    }
124
125
    /**
126
     * Removes the item binding
127 3
     *
128
     * @return ItemCode $this
129 3
     */
130 3
    public function setNoBinding()
131
    {
132
        $this->_itemBinding = 0;
133
        return $this;
134
    }
135
136
    /**
137
     * Returns the generated item code based up on the criteria set
138 3
     *
139
     * @return int
140 3
     */
141
    public function generate()
142
    {
143
        return $this->_itemCode + $this->_itemBinding + $this->_itemGrade * self::ITEM_GRADE_CONSTANT;
144
    }
145
146
    /**
147
     * Extracts information from the final generated item code
148
     *
149
     * @return array
150
     */
151
    public function extract()
152
    {
153
        // We cannot extract data if either of these conditions are met hence return the input item code itself
154
        if ($this->_itemCode > self::MAX_GENERATED_ITEM_CODE || $this->_itemCode <= self::MAX_BASE_ITEM_CODE) {
155
            return [
156
                'itemCode' => $this->_itemCode,
157
                'binding' => 0,
158
                'grade' => 0
159
            ];
160
        }
161
        $binding = 0;
162
        // Find the binding constant
163
        if ($this->_itemCode > self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT) {
164
            $binding = self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT;
165
        } else if ($this->_itemCode > self::ITEM_BIND_CHARACTER_CONSTANT) {
166
            $binding = self::ITEM_BIND_CHARACTER_CONSTANT;
167
        }
168
        // Subtract the binding constant
169
        $itemCode = $this->_itemCode - $binding;
170
        $grade = 0;
171
        // Subtract binding constant until base item code has been reached
172
        while ($itemCode > self::ITEM_GRADE_CONSTANT) {
173
            $grade++;
174
            $itemCode -= self::ITEM_GRADE_CONSTANT;
175
        }
176
        // After grade subtraction if item code exceeds account binding constant then it is account bound item
177
        if ($itemCode > self::ITEM_BIND_ACCOUNT_CONSTANT) {
178
            $itemCode -= self::ITEM_BIND_ACCOUNT_CONSTANT;
179
            $binding = self::ITEM_BIND_ACCOUNT_CONSTANT;
180
        }
181
        return [
182
            'itemCode' => $itemCode,
183
            'binding' => $binding,
184
            'grade' => $grade
185
        ];
186
    }
187
}