Passed
Push — master ( cba0a9...d9de1f )
by Karthik
13:36
created

ItemCode::removeBinding()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 8
ccs 0
cts 0
cp 0
crap 2
rs 10
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 = 20;
25
26
    /**
27
     * @var int
28
     */
29
    protected $_itemCode;
30
    protected $_itemGrade = 0;
31
    protected $_itemBinding = 0;
32
33
    /**
34
     * Item constructor.
35
     *
36
     * @param $itemCode
37
     */
38 39
    public function __construct($itemCode)
39
    {
40 39
        $this->_itemCode = $itemCode;
41 39
    }
42
43
    /**
44
     * Returns the item code
45
     *
46
     * @return int
47
     */
48 3
    public function getItemCode()
49
    {
50 3
        return $this->_itemCode;
51
    }
52
53
    /**
54
     * Returns the current grade of the item
55
     *
56
     * @return int
57
     */
58 12
    public function getGrade()
59
    {
60 12
        return $this->_itemGrade;
61
    }
62
63
    /**
64
     * Sets the grade of the item to generated
65
     *
66
     * @param int $value
67
     * @return ItemCode $this
68
     */
69 15
    public function setGrade($value)
70
    {
71 15
        $value = (int)$value;
72 15
        if ($value < self::MIN_GRADE) {
73 3
            $value = self::MIN_GRADE;
74
        }
75 15
        if ($value > self::MAX_GRADE) {
76 3
            $value = self::MAX_GRADE;
77
        }
78 15
        $this->_itemGrade = $value;
79 15
        return $this;
80
    }
81
82
    /**
83
     * Returns current item binding
84
     *
85
     * @return int
86
     */
87 15
    public function getBinding()
88
    {
89 15
        return $this->_itemBinding;
90
    }
91
92
    /**
93
     * Sets the item binding to account
94
     *
95
     * @return ItemCode $this
96
     */
97 6
    public function setAccountBinding()
98
    {
99 6
        $this->_itemBinding = self::ITEM_BIND_ACCOUNT_CONSTANT;
100 6
        return $this;
101
    }
102
103
    /**
104
     * Sets the item binding to character
105
     *
106
     * @return ItemCode $this
107
     */
108 6
    public function setCharacterBinding()
109
    {
110 6
        $this->_itemBinding = self::ITEM_BIND_CHARACTER_CONSTANT;
111 6
        return $this;
112
    }
113
114
    /**
115
     * Sets the item binding to character binding on usage
116
     *
117
     * @return ItemCode $this
118
     */
119 12
    public function setCharacterBindingOnUsage()
120
    {
121 12
        $this->_itemBinding = self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT;
122 12
        return $this;
123
    }
124
125
    /**
126
     * Removes the item binding
127
     *
128
     * @return ItemCode $this
129
     */
130 3
    public function setNoBinding()
131
    {
132 3
        $this->_itemBinding = 0;
133 3
        return $this;
134
    }
135
136
    /**
137
     * Returns the generated item code based up on the criteria set
138
     *
139
     * @return int
140
     */
141 6
    public function generate()
142
    {
143 6
        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
     * @param int $generatedItemCode
150
     * @return array
151
     */
152 3
    public static function extract($generatedItemCode)
153
    {
154
        // We cannot extract data if either of these conditions are met hence return the input item code itself
155 3
        if ($generatedItemCode > self::MAX_GENERATED_ITEM_CODE || $generatedItemCode <= self::MAX_BASE_ITEM_CODE) {
156
            return [
157 3
                'itemCode' => $generatedItemCode,
158 3
                'binding' => 0,
159 3
                'grade' => 0
160
            ];
161
        }
162 3
        $binding = 0;
163
        // Find the binding constant
164 3
        if ($generatedItemCode > self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT) {
165 3
            $binding = self::ITEM_BIND_CHARACTER_ON_USAGE_CONSTANT;
166 3
        } else if ($generatedItemCode > self::ITEM_BIND_CHARACTER_CONSTANT) {
167 3
            $binding = self::ITEM_BIND_CHARACTER_CONSTANT;
168
        }
169
        // Subtract the binding constant
170 3
        $itemCode = $generatedItemCode - $binding;
171 3
        $grade = 0;
172
        // Subtract grade constant until base item code has been reached
173 3
        while ($itemCode > self::ITEM_GRADE_CONSTANT) {
174 3
            $grade++;
175 3
            $itemCode -= self::ITEM_GRADE_CONSTANT;
176
        }
177
        // After grade subtraction if item code exceeds account binding constant then it is account bound item
178 3
        if ($itemCode > self::ITEM_BIND_ACCOUNT_CONSTANT) {
179 3
            $itemCode -= self::ITEM_BIND_ACCOUNT_CONSTANT;
180 3
            $binding = self::ITEM_BIND_ACCOUNT_CONSTANT;
181
        }
182
        return [
183 3
            'itemCode' => $itemCode,
184 3
            'binding' => $binding,
185 3
            'grade' => $grade
186
        ];
187
    }
188
189
    public static function removeBinding($itemCode)
190
    {
191
        // Extract item code
192
        $extractedItemCode = self::extract($itemCode);
193
        // Regenerate item code without binding and return
194
        $generator = new self($extractedItemCode['itemCode']);
195
        $generator->setGrade($extractedItemCode['grade']);
196
        return $generator->generate();
197
    }
198
}