5
5
* modify it under the terms of the GNU General Public License
6
6
* as published by the Free Software Foundation; either version 2
7
7
* of the License, or (at your option) any later version.
9
9
* This program is distributed in the hope that it will be useful,
10
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27
27
ShogunStone::ShogunStone(int holes) : Stone () {
28
28
objFlags |= holes << 24;
31
31
ShogunStone* ShogunStone::clone() {
32
32
return new ShogunStone(*this);
35
35
void ShogunStone::dispose() {
36
36
if (subShogun != NULL) {
37
37
SendMessage(subShogun, "disconnect");
45
45
std::string ShogunStone::getClass() const {
46
46
return "st_shogun";
49
49
void ShogunStone::setAttr(const string& key, const Value &val) {
50
50
if (key == "flavor") {
51
51
ASSERT(!isDisplayable(), XLevelRuntime, "ShogunStone: attempt to reflavor an existing shogun");
98
98
void ShogunStone::setState(int extState) {
99
99
// reject any write attempts
102
102
void ShogunStone::init_model() {
103
103
set_model(ecl::strf("st_shogun%d", getHoles()/S));
106
106
void ShogunStone::setOwnerPos(GridPos po) {
107
107
Stone::setOwnerPos(po);
108
108
if (subShogun != NULL)
109
109
subShogun->setOwnerPos(po);
112
112
void ShogunStone::on_creation(GridPos p) {
113
113
Stone::on_creation(p);
114
114
if (subShogun != NULL)
164
164
fitsNeighborShogun = (nss->getHoles() & (2*ownHole() -1)) == 0;
167
167
if ((subShogun == NULL) && ((st == NULL) || fitsNeighborShogun)) { // can we move?
168
168
// first remove from current position
169
169
if (!yieldShogun())
170
170
return; // being swapped or pulled
172
172
sound_event("movesmall");
174
174
// then put to new position
175
175
if (st == NULL) {
176
176
SetStone(newPos, this);
185
185
s->subShogun = this;
188
nss->init_model(); // display new hole
188
nss->init_model(); // display new hole
189
189
setOwnerPos(newPos); // the stone is owned at the new position
190
190
TouchStone(newPos);
193
193
server::IncMoveCounter();
194
194
ShatterActorsInsideField(newPos);
195
195
if (server::GameCompatibility != GAMET_ENIGMA) {
196
196
if (Item *it = GetItem(newPos)) {
197
ItemID id = get_id(it);
197
ItemID theid = get_id(it);
198
198
if ((server::GameCompatibility != GAMET_OXYD1 && server::GameCompatibility != GAMET_OXYDMAGNUM) ||
199
(id != it_cherry && id != it_bomb))
199
(theid != it_cherry && theid != it_bomb))
200
200
it->on_stonehit(this);
204
204
propagateImpulse(impulse);
207
207
int ShogunStone::getHoles() const {
208
208
return (objFlags & OBJBIT_HOLES) >> 24;
211
211
int ShogunStone::ownHole() const {
212
212
int holes = getHoles();
213
213
for (int check = ShogunStone::U; check > 0; check = check >> 1)
214
214
if (holes & check)
216
ASSERT(false, XLevelRuntime, "ShogunStone: internal error - no holes");
216
throw XLevelRuntime("ShogunStone: internal error - no holes");
219
219
void ShogunStone::addSubHoles(int holes) {
220
220
objFlags |= holes <<24;
223
223
void ShogunStone::removeSubHoles(int holes) {
224
224
objFlags &= ~(holes <<24);
227
227
void ShogunStone::removeAllSubHoles() {
228
228
int hole = ownHole();
229
229
objFlags &= ~OBJBIT_HOLES;
230
230
objFlags |= hole <<24;
233
233
bool ShogunStone::yieldShogun() {
234
234
if (isDisplayable() && subShogun == NULL) {
235
235
YieldStone(get_pos());
236
236
} else if (isDisplayable()) {
237
237
// top most shogun moved by wire or killed
238
GridPos oldPos = get_pos();
238
GridPos oldPos = get_pos();
239
239
YieldStone(oldPos);
240
240
subShogun->superShogun = NULL;
241
241
SetStone(oldPos, subShogun);
246
246
ShogunStone *oss = dynamic_cast<ShogunStone *>(GetStone(getOwnerPos()));
247
247
if (oss == NULL) // we are swapped or pulled and impulsed by wire
248
248
return false; // forget impulse
250
250
ASSERT(superShogun != NULL, XLevelRuntime, "Shogun: missing super shogun");
251
251
superShogun->subShogun = subShogun;
252
252
superShogun->removeSubHoles(ownHole());
268
268
FreezeStatusBits ShogunStone::get_freeze_bits() {
269
269
return (getHoles() == S) ? FREEZEBIT_STANDARD : FREEZEBIT_NO_STONE;
272
272
DEF_TRAITSM(ShogunStone, "st_shogun", st_shogun, MOVABLE_IRREGULAR);
274
274
BOOT_REGISTER_START
275
275
BootRegister(new ShogunStone(4), "st_shogun");
276
276
BootRegister(new ShogunStone(4), "st_shogun_s");