Пример #1
0
bool Parallaction::checkZoneType(ZonePtr z, uint32 type) {
	if (_gameType == GType_Nippon) {
		if ((type == 0) && (ITEMTYPE(z) == 0))
			return true;
	}

	if (_gameType == GType_BRA) {
		if (type == 0) {
			if (ITEMTYPE(z) == 0) {
				if (ACTIONTYPE(z) != kZonePath) {
					return true;
				}
			}
			if (ACTIONTYPE(z) == kZoneDoor) {
				return true;
			}
		}
	}

	if (z->_type == type)
		return true;
	if (ITEMTYPE(z) == type)
		return true;

	return false;
}
Пример #2
0
void Parallaction_br::runPendingZones() {
	ZonePtr z;

	_cmdExec->runSuspended();

	if (_activeZone) {
		z = _activeZone;	// speak Zone or sound
		_activeZone.reset();
		if (ACTIONTYPE(z) == kZoneSpeak && z->u._speakDialogue) {
			enterDialogueMode(z);
		} else {
			runZone(z);			// FIXME: BRA doesn't handle sound yet
		}
	}

	if (_activeZone2) {
		z = _activeZone2;	// speak Zone or sound
		_activeZone2.reset();
		if (ACTIONTYPE(z) == kZoneSpeak && z->u._speakDialogue) {
			enterDialogueMode(z);
		} else {
			runZone(z);			// FIXME: BRA doesn't handle sound yet
		}
	}
}
Пример #3
0
void Parallaction::drawZone(ZonePtr zone) {
    if (!zone) {
        return;
    }

    GfxObj *obj = 0;
    if (ACTIONTYPE(zone) == kZoneGet) {
        obj = zone->u._gfxobj;
    } else if (ACTIONTYPE(zone) == kZoneDoor) {
        obj = zone->u._gfxobj;
    }

    if (!obj) {
        return;
    }

    obj->x = zone->getX();
    obj->y = zone->getY();
    _gfx->addObjectToScene(obj);
}
Пример #4
0
void LocationParser_ns::parseZoneTypeBlock(ZonePtr z) {
	debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);

	ZoneTypeParser p = parsers[ACTIONTYPE(z)];
	do {
		if (p) {
			(this->*p)(z);
		}
		_script->readLineToken(true);
	} while (scumm_stricmp(_tokens[0], "endzone") && scumm_stricmp(_tokens[0], "endanimation"));
	debugC(7, kDebugParser, "parseZoneTypeBlock() done");
}
Пример #5
0
bool Parallaction::checkSpecialZoneBox(ZonePtr z, uint32 type, uint x, uint y) {
	// check if really a special zone
	if (_gameType == GType_Nippon) {
		// so-called special zones in NS have special x coordinates
		if ((z->getX() != -2) && (z->getX() != -3)) {
			return false;
		}
	}
	if (_gameType == GType_BRA) {
		// so far, special zones in BRA are only merge zones
		if (ACTIONTYPE(z) != kZoneMerge) {
			return false;
		}
	}

	// WORKAROUND: this huge condition is needed because we made TypeData a collection of structs
	// instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine,
	// but we need to check it separately here. The same workaround is applied in freeZones.
	if (((ACTIONTYPE(z) == kZoneMerge) && (((x == z->u._mergeObj1) && (y == z->u._mergeObj2)) || ((x == z->u._mergeObj2) && (y == z->u._mergeObj1)))) ||
		((ACTIONTYPE(z) == kZoneGet) && ((x == z->u._getIcon) || (y == z->u._getIcon)))) {

		// WORKAROUND for bug 2070751: special zones are only used in NS, to allow the
		// the EXAMINE/USE action to be applied on some particular item in the inventory.
		// The usage a verb requires at least an item match, so type can't be 0, as it
		// was in the original code. This bug has been here since the beginning, and was
		// hidden by label code, which filtered the bogus matches produced here.

		// look for action + item match
		if (z->_type == type)
			return true;
		// look for item match, but don't accept 0 types
		if ((ITEMTYPE(z) == type) && (type))
			return true;
	}

	return false;
}
Пример #6
0
void Parallaction::showZone(ZonePtr z, bool visible) {
	if (!z) {
		return;
	}

	if (visible) {
		z->_flags &= ~kFlagsRemove;
		z->_flags |= kFlagsActive;
	} else {
		z->_flags |= kFlagsRemove;
	}

	if (ACTIONTYPE(z) == kZoneGet) {
		_gfx->showGfxObj(z->u._gfxobj, visible);
	}
}
Пример #7
0
void Parallaction::runZone(ZonePtr z) {
	debugC(3, kDebugExec, "runZone (%s)", z->_name);

	uint16 actionType = ACTIONTYPE(z);

	debugC(3, kDebugExec, "actionType = %x, itemType = %x", actionType, ITEMTYPE(z));
	switch (actionType) {

	case kZoneExamine:
		enterCommentMode(z);
		return;

	case kZoneGet:
		pickupItem(z);
		break;

	case kZoneDoor:
		if (z->_flags & kFlagsLocked) break;
		updateDoor(z, !(z->_flags & kFlagsClosed));
		break;

	case kZoneHear:
		if (z->u._hearChannel == MUSIC_HEAR_CHANNEL) {
			_soundMan->execute(SC_SETMUSICFILE, z->u._filename.c_str());
			_soundMan->execute(SC_PLAYMUSIC);
		} else {
			_soundMan->execute(SC_SETSFXCHANNEL, z->u._hearChannel);
			_soundMan->execute(SC_SETSFXLOOPING, (int)((z->_flags & kFlagsLooping) == kFlagsLooping));
			_soundMan->execute(SC_SETSFXVOLUME, 60);
			_soundMan->execute(SC_PLAYSFX, z->u._filename.c_str());
		}
		break;

	case kZoneSpeak:
		if (z->u._speakDialogue) {
			enterDialogueMode(z);
			return;
		}
		break;
	}

	debugC(3, kDebugExec, "runZone completed");

	_cmdExec->run(z->_commands, z);

	return;
}
Пример #8
0
// NOTE: hitZone needs to be passed absolute game coordinates to work.
//
// When type is kZoneMerge, then x and y are the identifiers of the objects to merge,
// and the above requirement does not apply.
ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) {
	uint16 _di = y;
	uint16 _si = x;

	for (ZoneList::iterator it = _location._zones.begin(); it != _location._zones.end(); ++it) {
		if (checkLinkedAnimBox(*it, type, x, y)) {
			return *it;
		}
		if (checkZoneBox(*it, type, x, y)) {
			return *it;
		}
	}

	int16 _a, _b, _c, _d;
	bool _ef;
	for (AnimationList::iterator ait = _location._animations.begin(); ait != _location._animations.end(); ++ait) {

		AnimationPtr a = *ait;

		_a = (a->_flags & kFlagsActive) ? 1 : 0;	// _a: active Animation

		if (!_a) {
			if (_gameType == GType_BRA && ACTIONTYPE(a) != kZoneTrap) {
				continue;
			}
		}

		_ef = a->hitFrameRect(_si, _di);

		_b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1;										 // _b: (no type specified) AND (Animation is not the character)
		_c = ITEMTYPE(a) ? 0 : 1;															// _c: Animation is not an object
		_d = (ITEMTYPE(a) != type) ? 0 : 1;													// _d: Animation is an object of the same type

		if ((_a != 0 && _ef) && ((_b != 0 && _c != 0) || (a->_type == type) || (_d != 0))) {
			return a;
		}
	}

	return ZonePtr();
}
Пример #9
0
bool Location::keepZone_br(ZonePtr z) {
	return (z->_flags & kFlagsSelfuse) || (ACTIONTYPE(z) == kZoneMerge);
}
Пример #10
0
bool Input::translateGameInput() {

	if (_engineFlags & kEnginePauseJobs) {
		return false;
	}

	if (_hasDelayedAction) {
		// if walking is over, then take programmed action
		takeAction(_delayedActionZone);
		_hasDelayedAction = false;
		_delayedActionZone.reset();
		return true;
	}

	if (_mouseButtons == kMouseRightDown) {
		// right button down shows inventory
		enterInventoryMode();
		return true;
	}

	Common::Point mousePos;
	getAbsoluteCursorPos(mousePos);
	// test if mouse is hovering on an interactive zone for the currently selected inventory item
	ZonePtr z = _vm->hitZone(_activeItem._id, mousePos.x, mousePos.y);

	if (((_mouseButtons == kMouseLeftUp) && (_activeItem._id == 0) && ((_engineFlags & kEngineWalking) == 0)) && ((!z) || (ACTIONTYPE(z) != kZoneCommand))) {
		walkTo(mousePos);
		return true;
	}

	trackMouse(z);
	if (!z) {
		return true;
	}

	if ((_mouseButtons == kMouseLeftUp) && ((_activeItem._id != 0) || (ACTIONTYPE(z) == kZoneCommand))) {

		bool noWalk = z->_flags & kFlagsNoWalk;	// check the explicit no-walk flag
		if (_gameType == GType_BRA) {
			// action performed on object marked for self-use do not need walk in BRA
			noWalk |= ((z->_flags & kFlagsYourself) != 0);
		}

		if (noWalk) {
			takeAction(z);
		} else {
			// action delayed: if Zone defined a moveto position the character is programmed to move there,
			// else it will move to the mouse position
			_delayedActionZone = z;
			_hasDelayedAction = true;
			if (z->_moveTo.y != 0) {
				mousePos = z->_moveTo;
			}

			walkTo(mousePos);
		}

		_vm->beep();
		setArrowCursor();
		return true;
	}

	return true;
}