mad_flow MADStream::ms_error(void* user, mad_stream* stream, mad_frame* frame) { RW_UNUSED(user); RW_UNUSED(frame); std::cerr << "libmad error: " << mad_stream_errorstr(stream) << std::endl; return MAD_FLOW_BREAK; }
void Garage::doOnStartClosingEvent() { auto player = engine->getPlayer(); auto plyChar = player->getCharacter(); auto playerPosition = plyChar->getPosition(); auto playerVehicle = plyChar->getCurrentVehicle(); bool playerIsInVehicle = playerVehicle != nullptr; RW_UNUSED(playerPosition); RW_UNUSED(playerIsInVehicle); switch (type) { case Type::Mission: case Type::CollectCars1: case Type::CollectCars2: { player->setInputEnabled(false); break; } case Type::BombShop1: case Type::BombShop2: case Type::BombShop3: case Type::Respray: { player->setInputEnabled(false); playerVehicle->setHandbraking(true); break; } case Type::MissionForCarToComeOut: { break; } case Type::Crusher: { break; } case Type::MissionKeepCar: { break; } case Type::MissionToOpenAndClose: { break; } case Type::MissionForSpecificCar: { break; } case Type::MissionKeepCarAndRemainClosed: { break; } default: { break; } } }
bool game_character_in_area_on_foot(const ScriptArguments& args) { RW_UNIMPLEMENTED("game_character_in_area_on_foot"); RW_UNUSED(args); /// @todo return false; }
bool game_is_vehicle_in_water(const ScriptArguments& args) { RW_UNIMPLEMENTED("game_is_vehicle_in_water"); RW_UNUSED(args); /// @todo return false; }
mad_flow MADStream::ms_output(void* user, mad_header const* header, mad_pcm* pcm) { RW_UNUSED(header); MADStream* self = static_cast<MADStream*>(user); if (self->stopped) { return MAD_FLOW_STOP; } if (!self->numFreeBuffers) { ALint buffersProcessed; do { /** * Sleep a bit while waiting for OpenAL buffers to become available. * The number is arbitrary and depends on the size of the * buffer/audio samples, * as well as how quickly the computer can feed more buffers into * OpenAL. */ std::this_thread::sleep_for(std::chrono::milliseconds(20)); alGetSourcei(self->alSource, AL_BUFFERS_PROCESSED, &buffersProcessed); } while (buffersProcessed <= 0); alCheck(alSourceUnqueueBuffers(self->alSource, buffersProcessed, self->unqueuedBuffers)); self->numFreeBuffers += buffersProcessed; } int nsamples = pcm->length; mad_fixed_t const *left, *right; left = pcm->samples[0]; right = pcm->samples[1]; int s = 0; while (nsamples--) { signed int sample = *left++; self->mCurrentSamples.push_back(scale(sample)); sample = *right++; self->mCurrentSamples.push_back(scale(sample)); s++; } alCheck(alBufferData(self->buffers[self->currentBuffer], AL_FORMAT_STEREO16, self->mCurrentSamples.data(), self->mCurrentSamples.size() * sizeof(uint16_t), pcm->samplerate)); alCheck(alSourceQueueBuffers(self->alSource, 1, self->buffers + self->currentBuffer)); self->mCurrentSamples.clear(); self->currentBuffer++; self->currentBuffer %= numALbuffers; self->numFreeBuffers--; return MAD_FLOW_CONTINUE; }
void game_create_character_as_passenger(const ScriptArguments& args) { auto vehicle = static_cast<VehicleObject*>(args.getObject<VehicleObject>(0)); auto type = args[1].integerValue(); RW_UNUSED(type); RW_UNIMPLEMENTED("game_create_character_as_passenger(): character type"); auto id = args[2].integerValue(); auto seat = args[3].integerValue(); auto character = args.getWorld()->createPedestrian(id, vehicle->getPosition() + spawnMagic); new DefaultAIController(character); if (seat <= -1) { for (seat = 0; seat < static_cast<int>(vehicle->info->seats.size()); seat++) { if (vehicle->getOccupant(seat) == nullptr && !vehicle->isOccupantDriver(seat)) { break; } } } else { /// @todo 0 - passenger seat (or back seat of bike); 1 - left rear seat; 2 - right rear seat seat++; } RW_CHECK(seat < static_cast<int>(vehicle->info->seats.size()), "Seat index too high"); RW_CHECK(vehicle->getOccupant(seat) == nullptr, "Seat is not free"); RW_CHECK(vehicle->isOccupantDriver(seat) == false, "Seat is not a passenger seat"); character->setCurrentVehicle(vehicle, seat); vehicle->setOccupant(seat, character); *args[4].globalInteger = character->getGameObjectID(); }
bool game_vehicle_in_air(const ScriptArguments& args) { /// @todo IS vehicle in air. auto vehicle = static_cast<VehicleObject*>(args.getObject<VehicleObject>(0)); RW_UNUSED(vehicle); RW_UNIMPLEMENTED("game_vehicle_in_air()"); return false; }
Clump *LoaderDFF::loadFromMemory(FileHandle file) { auto model = new Clump; RWBStream rootStream(file->data, file->length); auto rootID = rootStream.getNextChunk(); if (rootID != CHUNK_CLUMP) { throw DFFLoaderException("Invalid root section ID " + std::to_string(rootID)); } RWBStream modelStream = rootStream.getInnerStream(); auto rootStructID = modelStream.getNextChunk(); if (rootStructID != CHUNK_STRUCT) { throw DFFLoaderException("Clump missing struct chunk"); } // There is only one value in the struct section. auto numAtomics = *(std::uint32_t *)rootStream.getCursor(); RW_UNUSED(numAtomics); GeometryList geometrylist; FrameList framelist; // Process everything inside the clump stream. RWBStream::ChunkID chunkID; while ((chunkID = modelStream.getNextChunk())) { switch (chunkID) { case CHUNK_FRAMELIST: framelist = readFrameList(modelStream); break; case CHUNK_GEOMETRYLIST: geometrylist = readGeometryList(modelStream); break; case CHUNK_ATOMIC: { auto atomic = readAtomic(framelist, geometrylist, modelStream); RW_CHECK(atomic, "Failed to read atomic"); if (!atomic) { // Abort reading the rest of the clump return nullptr; } model->addAtomic(atomic); } break; default: break; } } if (!framelist.empty()) { model->setFrame(framelist[0]); } // Ensure the model has cached metrics model->recalculateMetrics(); return model; }
bool game_objects_in_volume(const ScriptArguments& args) { glm::vec3 vec1(args[0].real, args[1].real, args[2].real); glm::vec3 vec2(args[3].real, args[4].real, args[5].real); glm::vec3 min = glm::min(vec1, vec2); glm::vec3 max = glm::max(vec1, vec2); bool solids = args[6].integer; bool cars = args[7].integer; bool actors = args[8].integer; bool objects = args[9].integer; bool particles = args[10].integer; RW_UNUSED(objects); RW_UNUSED(particles); for(auto& object : args.getWorld()->allObjects) { switch( object->type() ) { case GameObject::Instance: if( !solids ) continue; break; case GameObject::Character: if( !actors ) continue; break; case GameObject::Vehicle: if( !cars ) continue; break; default: continue; } // Maybe consider object bounds? auto pp = object->getPosition(); if( pp.x >= min.x && pp.y >= min.y && pp.z >= min.z && pp.x <= max.x && pp.y <= max.y && pp.z <= max.z ) { return true; } } return false; }
bool game_is_boat(const ScriptArguments& args) { RW_UNUSED(args); RW_UNIMPLEMENTED("game_is_boat()"); /*auto vehicle = (VehicleObject*)(*args[0].handle); * if( vehicle ) * { * return vehicle->vehicle->type == VehicleData::BOAT; }*/ return false; }
void game_create_weapon_pickup(const ScriptArguments& args) { glm::vec3 pos (args[3].real, args[4].real, args[5].real); int id = args.getModel(0); int type = args[1].integer; int ammo = args[2].integer; RW_UNUSED(ammo); RW_UNIMPLEMENTED("game_create_weapon_pickup(): ammo count"); PickupObject* pickup = args.getWorld()->createPickup(pos, id, type); *args[6].globalInteger = pickup->getGameObjectID(); }
bool Activities::Jump::update(CharacterObject *character, CharacterController *controller) { RW_UNUSED(controller); if (character->physCharacter == nullptr) return true; if (!jumped) { character->jump(); jumped = true; } else if (character->physCharacter->canJump()) { return true; } return false; }
bool game_rotate_object(const ScriptArguments& args) { auto object = args.getObject<InstanceObject>(0); if( object ) { float start = args[2].real; float finish = args[1].real; RW_UNUSED(start); // @todo INTERPOLATE instead of just setting the heading. object->setHeading(finish); } return true; }
void game_create_character_in_vehicle(const ScriptArguments& args) { auto vehicle = static_cast<VehicleObject*>(args.getObject<VehicleObject>(0)); auto type = args[1].integer; RW_UNUSED(type); RW_UNIMPLEMENTED("game_create_character_in_vehicle(): character type"); auto id = args[2].integer; auto character = args.getWorld()->createPedestrian(id, vehicle->getPosition() + spawnMagic); new DefaultAIController(character); character->setCurrentVehicle(vehicle, 0); vehicle->setOccupant(0, character); *args[3].globalInteger = character->getGameObjectID(); }
bool game_player_near_point_in_vehicle_3D(const ScriptArguments& args) { auto character = static_cast<CharacterObject*>(args.getPlayerCharacter(0)); glm::vec3 center(args[1].real, args[2].real, args[3].real); glm::vec3 size(args[4].real, args[5].real, args[6].real); bool unkown = !!args[7].integer; RW_UNUSED(unkown); auto vehicle = character->getCurrentVehicle(); if( vehicle ) { auto distance = center - character->getPosition(); distance /= size; if( glm::length( distance ) < 1.f ) return true; } return false; }
// Set state void setBlend(bool enable) { RW_UNUSED(enable); /// @todo set blendEnabled, currently not possible because other functions keep trashing the state #if 0 if (enable && !blendEnabled) { glEnable(GL_BLEND); blendEnabled = enable; } else if(!enable && blendEnabled) { glDisable(GL_BLEND); blendEnabled = enable; } #else glEnable(GL_BLEND); #endif }
bool game_character_in_area_or_cylinder(const ScriptArguments& args) { auto character = args.getPlayerCharacter(0); glm::vec2 min(args[1].real, args[2].real); glm::vec2 max(args[3].real, args[4].real); bool isCylinder = !!args[5].integerValue(); RW_UNIMPLEMENTED("game_character_in_area_or_cylinder: should use cylinder if requested?"); RW_UNUSED(isCylinder); /// @todo auto player = character->getPosition(); if( player.x > min.x && player.y > min.y && player.x < max.x && player.y < max.y ) { return true; } return false; }
bool game_character_near_point_on_foot_2D(const ScriptArguments& args) { auto character = static_cast<CharacterObject*>(args.getObject<CharacterObject>(0)); glm::vec2 center(args[1].real, args[2].real); glm::vec2 size(args[3].real, args[4].real); bool unkown = !!args[5].integer; RW_UNUSED(unkown); auto vehicle = character->getCurrentVehicle(); if( !vehicle ) { auto distance = center - glm::vec2(character->getPosition()); distance /= size; if( glm::length( distance ) < 1.f ) return true; } return false; }
bool Activities::ExitVehicle::update(CharacterObject *character, CharacterController *controller) { RW_UNUSED(controller); if( character->getCurrentVehicle() == nullptr ) return true; auto vehicle = character->getCurrentVehicle(); auto seat = character->getCurrentSeat(); auto door = vehicle->getSeatEntryDoor(seat); auto anm_exit = character->animations.car_getout_lhs; if( door->dummy->getDefaultTranslation().x > 0.f ) { anm_exit = character->animations.car_getout_rhs; } if( vehicle->vehicle->type == VehicleData::BOAT ) { auto ppos = character->getPosition(); character->enterVehicle(nullptr, seat); character->setPosition(ppos); return true; } if( character->animator->getAnimation(AnimIndexAction) == anm_exit ) { if( character->animator->isCompleted(AnimIndexAction) ) { auto exitpos = vehicle->getSeatEntryPosition(seat); character->enterVehicle(nullptr, seat); character->setPosition(exitpos); return true; } } else { character->playActivityAnimation(anm_exit, false, true); if( door ) { vehicle->setPartTarget(door, true, door->openAngle); } } return false; }
void OpenGLRenderer::pushDebugGroup(const std::string& title) { #ifdef RW_GRAPHICS_STATS if (ogl_ext_KHR_debug) { glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, title.c_str()); ProfileInfo& prof = profileInfo[currentDebugDepth]; prof.buffers = prof.draws = prof.textures = prof.uploads = prof.primitives = 0; glQueryCounter(debugQuery, GL_TIMESTAMP); glGetQueryObjectui64v(debugQuery, GL_QUERY_RESULT, &prof.timerStart); currentDebugDepth++; RW_ASSERT(currentDebugDepth < MAX_DEBUG_DEPTH); } #else RW_UNUSED(title); #endif }
bool game_character_near_character_2D(const ScriptArguments& args) { auto character = static_cast<CharacterObject*>(args.getObject<CharacterObject>(0)); RW_CHECK(character != nullptr, "character is null"); auto target = args.getObject<CharacterObject>(1); RW_CHECK(target != nullptr, "target is null"); if (character == nullptr || target == nullptr) return false; glm::vec2 center(target->getPosition()); glm::vec2 size(args[2].real, args[3].real); bool unkown = !!args[4].integer; RW_UNUSED(unkown); auto distance = center - glm::vec2(character->getPosition()); distance /= size; return glm::length( distance ) < 1.f; return false; }
bool game_character_near_car_2d(const ScriptArguments& args) { auto character = static_cast<CharacterObject*>(args.getObject<CharacterObject>(0)); auto vehicle = static_cast<VehicleObject*>(args.getObject<VehicleObject>(1)); glm::vec2 radius(args[2].real, args[3].real); bool drawMarker = !!args[4].integer; RW_UNUSED(drawMarker); RW_UNIMPLEMENTED("Draw marker in game_character_near_car_2D"); auto charVehicle = character->getCurrentVehicle(); if( charVehicle ) { auto dist = charVehicle->getPosition() - vehicle->getPosition(); if( dist.x <= radius.x && dist.y <= radius.y ) { return true; } } return false; }
bool game_character_in_area_9(const ScriptArguments& args) { RW_UNUSED(args); RW_UNIMPLEMENTED("game_character_in_area_9"); return false; }
void Garage::doOnOpenEvent() { auto player = engine->getPlayer(); auto plyChar = player->getCharacter(); auto playerPosition = plyChar->getPosition(); auto playerVehicle = plyChar->getCurrentVehicle(); bool playerIsInVehicle = playerVehicle != nullptr; RW_UNUSED(playerPosition); RW_UNUSED(playerIsInVehicle); switch (type) { case Type::Mission: { break; } case Type::BombShop1: { break; } case Type::BombShop2: { break; } case Type::BombShop3: { break; } case Type::Respray: { break; } case Type::CollectCars1: case Type::CollectCars2: { break; } case Type::MissionForCarToComeOut: { break; } case Type::Crusher: { break; } case Type::MissionKeepCar: { break; } case Type::Hideout1: case Type::Hideout2: case Type::Hideout3: { break; } case Type::MissionToOpenAndClose: { break; } case Type::MissionForSpecificCar: { break; } case Type::MissionKeepCarAndRemainClosed: { break; } default: { break; } } }
void Garage::doOnCloseEvent() { auto player = engine->getPlayer(); auto plyChar = player->getCharacter(); auto playerPosition = plyChar->getPosition(); auto playerVehicle = plyChar->getCurrentVehicle(); bool playerIsInVehicle = playerVehicle != nullptr; RW_UNUSED(playerPosition); RW_UNUSED(playerIsInVehicle); switch (type) { case Type::Mission: { player->setInputEnabled(true); break; } case Type::BombShop1: case Type::BombShop2: case Type::BombShop3: { // Find out real value garageTimer = engine->getGameTime() + 1.5f; break; } case Type::Respray: { // Find out real value garageTimer = engine->getGameTime() + 2.f; playerVehicle->setHealth(1000.f); break; } case Type::CollectCars1: case Type::CollectCars2: { break; } case Type::MissionForCarToComeOut: { break; } case Type::Crusher: { break; } case Type::MissionKeepCar: { break; } case Type::Hideout1: case Type::Hideout2: case Type::Hideout3: { break; } case Type::MissionToOpenAndClose: { break; } case Type::MissionForSpecificCar: { break; } case Type::MissionKeepCarAndRemainClosed: { break; } default: { break; } } }
void activate(float clickX, float clickY) { RW_UNUSED(clickX); RW_UNUSED(clickY); callback(); }
bool Activities::ShootWeapon::update(CharacterObject *character, CharacterController *controller) { RW_UNUSED(controller); auto& wepdata = _item->getWeaponData(); // Instant hit weapons loop their anim // Thrown projectiles have lob / throw. if( wepdata->fireType == WeaponData::INSTANT_HIT ) { if( _item->isFiring(character) ) { auto shootanim = character->engine->data->animations[wepdata->animation1]; if( shootanim ) { if( character->animator->getAnimation(AnimIndexAction) != shootanim ) { character->playActivityAnimation(shootanim, false, false); } auto loopstart = wepdata->animLoopStart / 100.f; auto loopend = wepdata->animLoopEnd / 100.f; auto firetime = wepdata->animFirePoint / 100.f; auto currID = character->animator->getAnimationTime(AnimIndexAction); if( currID >= firetime && ! _fired ) { _item->fire(character); _fired = true; } if( currID > loopend ) { character->animator->setAnimationTime( AnimIndexAction, loopstart ); _fired = false; } } } else { if( character->animator->isCompleted(AnimIndexAction) ) { return true; } } } /// @todo Use Thrown flag instead of project (RPG isn't thrown eg.) else if( wepdata->fireType == WeaponData::PROJECTILE ) { auto shootanim = character->engine->data->animations[wepdata->animation1]; auto throwanim = character->engine->data->animations[wepdata->animation2]; if( character->animator->getAnimation(AnimIndexAction) == shootanim ) { if( character->animator->isCompleted(AnimIndexAction) ) { character->playActivityAnimation(throwanim, false, false); } } else if( character->animator->getAnimation(AnimIndexAction) == throwanim ) { auto firetime = wepdata->animCrouchFirePoint / 100.f; auto currID = character->animator->getAnimationTime(AnimIndexAction); if( currID >= firetime && !_fired ) { _item->fire(character); _fired = true; } if( character->animator->isCompleted(AnimIndexAction) ) { return true; } } else { character->playActivityAnimation(throwanim, false, true); } } else if( wepdata->fireType == WeaponData::MELEE ) { RW_CHECK(wepdata->fireType != WeaponData::MELEE, "Melee attacks not implemented"); return true; } return false; }
bool game_character_in_range(const ScriptArguments& args) { RW_UNUSED(args); RW_UNIMPLEMENTED("game_character_in_range()"); return true; }
bool Activities::EnterVehicle::update(CharacterObject *character, CharacterController *controller) { RW_UNUSED(controller); // Boats don't have any kind of entry animation unless you're onboard. if( vehicle->vehicle->type == VehicleData::BOAT ) { character->enterVehicle(vehicle, seat); return true; } if( seat == ANY_SEAT ) { // Determine which seat to take. float nearest = std::numeric_limits<float>::max(); for(unsigned int s = 1; s < vehicle->info->seats.size(); ++s) { auto entry = vehicle->getSeatEntryPosition(s); float dist = glm::distance(entry, character->getPosition()); if( dist < nearest ) { seat = s; nearest = dist; } } } auto entryDoor = vehicle->getSeatEntryDoor(seat); auto anm_open = character->animations.car_open_lhs; auto anm_enter = character->animations.car_getin_lhs; if( entryDoor->dummy->getDefaultTranslation().x > 0.f ) { anm_open = character->animations.car_open_rhs; anm_enter = character->animations.car_getin_rhs; } if( entering ) { if( character->animator->getAnimation(AnimIndexAction) == anm_open ) { if( character->animator->isCompleted(AnimIndexAction) ) { character->playActivityAnimation(anm_enter, false, true); character->enterVehicle(vehicle, seat); } else if( entryDoor && character->animator->getAnimationTime(AnimIndexAction) >= 0.5f ) { vehicle->setPartTarget(entryDoor, true, entryDoor->openAngle); } else { //character->setPosition(vehicle->getSeatEntryPosition(seat)); character->rotation = vehicle->getRotation(); } } else if( character->animator->getAnimation(AnimIndexAction) == anm_enter ) { if( character->animator->isCompleted(AnimIndexAction) ) { // VehicleGetIn is over, finish activity return true; } } } else { glm::vec3 target = vehicle->getSeatEntryPosition(seat); glm::vec3 targetDirection = target - character->getPosition(); targetDirection.z = 0.f; float targetDistance = glm::length(targetDirection); if( targetDistance <= 0.4f ) { entering = true; // Warp character to vehicle orientation character->controller->setMoveDirection({0.f, 0.f, 0.f}); character->controller->setRunning(false); character->rotation = vehicle->getRotation(); // Determine if the door open animation should be skipped. if( entryDoor == nullptr || (entryDoor->constraint != nullptr && glm::abs(entryDoor->constraint->getHingeAngle()) >= 0.6f ) ) { character->playActivityAnimation(anm_enter, false, true); character->enterVehicle(vehicle, seat); } else { character->playActivityAnimation(anm_open, false, true); } } else { if( targetDistance > 5.f ) { character->controller->setRunning(true); } glm::quat r( glm::vec3{ 0.f, 0.f, atan2(targetDirection.y, targetDirection.x) - glm::half_pi<float>() } ); character->rotation = r; character->controller->setMoveDirection({1.f, 0.f, 0.f}); } } return false; }
void MenuState::tick(float dt) { RW_UNUSED(dt); }