Beispiel #1
0
void game_create_object_world(const ScriptArguments& args)
{
	int id = 0;
	switch(args[0].type) {
		case TInt8:
			id = (std::int8_t)args[0].integer;
			break;
		case TInt16:
			id = (std::int16_t)args[0].integer;
			break;
		default:
			RW_ERROR("Unhandled integer type");
			break;
	}
	
	if( id < 0 ) {
		auto& modelname = args.getVM()->getFile()->getModels()[-id];
		id = args.getWorld()->data->findModelObject(modelname);
		if( id == (uint16_t)-1 ) {
			args.getWorld()->logger->error("SCM", "Failed to find model " + modelname);
		}
	}

	glm::vec3 position(args[1].real, args[2].real, args[3].real);

	auto inst = args.getWorld()->createInstance(id, position);

	*args[4].globalInteger = inst->getGameObjectID();
}
Beispiel #2
0
std::string GameConfig::getDefaultConfigPath()
{
#if defined(RW_LINUX) || defined(RW_FREEBSD)
	char* config_home = getenv("XDG_CONFIG_HOME");
	if (config_home != nullptr) {
		return std::string(config_home) + "/" + kConfigDirectoryName;
	}
	char* home = getenv("HOME");
	if (home != nullptr) {
		return std::string(home) + "/.config/" + kConfigDirectoryName;
	}

#elif defined(RW_OSX)
	char* home = getenv("HOME");
	if (home)
		return std::string(home) + "/Library/Preferences/" + kConfigDirectoryName;

#else
	return ".";
#endif

	// Well now we're stuck.
	RW_ERROR("No default config path found.");
	return ".";
}
Beispiel #3
0
void ViewerWindow::switchView(int mode)
{
	if( mode < int(m_views.size()) )
	{
		m_views[mode]->setViewerWidget( viewerWidget );
	}
	else
	{
		RW_ERROR("Unhandled view mode" << mode);
	}
}
Beispiel #4
0
GLuint compileShader(GLenum type, const char* source) {
    GLuint shader = glCreateShader(type);

    if (shader == 0) {
        RW_ERROR("[OGL] Failed to create shader object");
        throw std::runtime_error("Compiling shader failed");
    }

    glShaderSource(shader, 1, &source, nullptr);
    glCompileShader(shader);

    GLint status;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);

    if (status != GL_TRUE) {
        RW_ERROR("[OGL] Shader Compilation Failed");
    }

    GLint len;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
    if (len > 1) {
        auto buffer = std::make_unique<GLchar[]>(len);
        glGetShaderInfoLog(shader, len, nullptr, buffer.get());

        GLint sourceLen;
        glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceLen);
        auto sourceBuff = std::make_unique<GLchar[]>(sourceLen);
        glGetShaderSource(shader, sourceLen, nullptr, sourceBuff.get());

        RW_ERROR("[OGL] Shader InfoLog(" << shader << "):\n"
                  << buffer.get() << "\nSource:\n"
                  << sourceBuff.get());
    }

    if (status != GL_TRUE) {
        throw std::runtime_error("Compiling shader failed");
    }

    return shader;
}
Beispiel #5
0
GLuint compileProgram(const char* vertex, const char* fragment) {
    GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertex);
    GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragment);

    GLuint prog = glCreateProgram();

    glAttachShader(prog, vertexShader);
    glAttachShader(prog, fragmentShader);
    glLinkProgram(prog);

    glDetachShader(prog, vertexShader);
    glDetachShader(prog, fragmentShader);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    GLint status;
    glGetProgramiv(prog, GL_LINK_STATUS, &status);

    if (status != GL_TRUE) {
        RW_ERROR("[OGL] Program Link Failed");
    }

    GLint len;
    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len);
    if (len > 1) {
        auto buffer = std::make_unique<GLchar[]>(len);
        glGetProgramInfoLog(prog, len, nullptr, buffer.get());

        RW_ERROR("[OGL] Program InfoLog(" << prog << "):\n"
                  << buffer.get());
    }

    if (status != GL_TRUE) {
        throw std::runtime_error("Linking shaders failed");
    }

    return prog;
}
Beispiel #6
0
void game_set_close_object_visible(const ScriptArguments& args)
{
	glm::vec3 position(args[0].real, args[1].real, args[2].real);
	float radius = args[3].real;
	int modelid = 0;
	
	/// @todo fix this being a problem.
	switch(args[4].type) {
		case TInt8:
			modelid = (std::int8_t)args[4].integer;
			break;
		case TInt16:
			modelid = (std::int16_t)args[4].integer;
			break;
		default:
			RW_ERROR("Unhandled integer type");
			break;
	}
	
	if( std::abs(modelid) > 178 ) {
		/// @todo implement this path,
		return;
	}
	
	std::string model;
	
	if(modelid < 0) modelid = -modelid;
	
	model = args.getVM()->getFile()->getModels()[modelid];
	
	std::transform(model.begin(), model.end(), model.begin(), ::tolower);
	
	for(auto& p : args.getWorld()->instancePool.objects) {
		auto o = p.second;
		if( !o->model ) continue;
		if( o->model->name != model ) continue;
		float d = glm::distance(position, o->getPosition());
		if( d < radius ) {
			o->visible = !!args[5].integer;
		}
	}
}
Beispiel #7
0
void game_change_nearest_model(const ScriptArguments& args)
{
	glm::vec3 position(args[0].real, args[1].real, args[2].real);
	float radius = args[3].real;
	int newid = 0, oldid = 0;
	
	/// @todo fix this being a problem.
	switch(args[4].type) {
		case TInt8:
			oldid = (std::int8_t)args[4].integer;
			break;
		case TInt16:
			oldid = (std::int16_t)args[4].integer;
			break;
		default:
			RW_ERROR("Unhandled integer type");
			break;
	}
	
	switch(args[5].type) {
		case TInt8:
			newid = (std::int8_t)args[5].integer;
			break;
		case TInt16:
			newid = (std::int16_t)args[5].integer;
			break;
		default:
			RW_ERROR("Unhandled integer type");
			break;
	}
	
	if( std::abs(newid) > 178 || std::abs(oldid) > 178 ) {
		/// @todo implement this path,
		return;
	}
	
	std::string newmodel;
	std::string oldmodel;
	
	if(newid < 0) newid = -newid;
	if(oldid < 0) oldid = -oldid;
	
	newmodel = args.getVM()->getFile()->getModels()[newid];
	oldmodel = args.getVM()->getFile()->getModels()[oldid];
	std::transform(newmodel.begin(), newmodel.end(), newmodel.begin(), ::tolower);
	std::transform(oldmodel.begin(), oldmodel.end(), oldmodel.begin(), ::tolower);
	
	auto newobjectid = args.getWorld()->data->findModelObject(newmodel);
	auto nobj = args.getWorld()->data->findObjectType<ObjectData>(newobjectid);
	
	/// @todo Objects need to adopt the new object ID, not just the model.
	for(auto p : args.getWorld()->instancePool.objects) {
		auto o = p.second;
		if( !o->model ) continue;
		if( o->model->name != oldmodel ) continue;
		float d = glm::distance(position, o->getPosition());
		if( d < radius ) {
			args.getWorld()->data->loadDFF(newmodel + ".dff", false);
			InstanceObject* inst = static_cast<InstanceObject*>(o);
			inst->changeModel(nobj);
			inst->model = args.getWorld()->data->models[newmodel];
		}
	}
}
Beispiel #8
0
void game_create_pickup(const ScriptArguments& args)
{
	glm::vec3 pos (args[2].real, args[3].real, args[4].real);
	int id;
	int type = args[1].integer;
	
	switch(args[0].type) {
		case TInt8:
			id = (std::int8_t)args[0].integer;
			break;
		case TInt16:
			id = (std::int16_t)args[0].integer;
			break;
		default:
			RW_ERROR("Unhandled integer type");
			*args[5].globalInteger = 0;
			return;
	}
	
	if ( id < 0 )
	{
		id = -id;
		
		auto model = args.getVM()->getFile()->getModels()[id];
		std::transform(model.begin(), model.end(), model.begin(), ::tolower);
	
		id = args.getWorld()->data->findModelObject(model);
		args.getWorld()->data->loadDFF(model+".dff");
		args.getWorld()->data->loadTXD("icons.txd");
	}
	else
	{
		auto data = args.getWorld()->data->findObjectType<ObjectData>(id);
		
		if ( ! ( id >= 170 && id <= 184 ) )
		{
			args.getWorld()->data->loadDFF(data->modelName+".dff");
		}
		args.getWorld()->data->loadTXD(data->textureName+".txd");
	}
	
	PickupObject* pickup = nullptr;

	if ( id >= 170 && id <= 184 )
	{
		// Find the item for this model ID
		auto world = args.getWorld();
		InventoryItem *item = nullptr;
		for (auto i = 0; i < maxInventorySlots; ++i)
		{
			item = world->getInventoryItem(i);
			if (item->getModelID() == id) {
				auto pickuptype = (PickupObject::PickupType)type;
				pickup = new ItemPickup(args.getWorld(), pos, pickuptype, item);
				world->pickupPool.insert( pickup );
				world->allObjects.push_back(pickup);
				*args[5].globalInteger = pickup->getGameObjectID();
			}
		}
	}
	else
	{
		RW_UNIMPLEMENTED("non-item pickups");
		*args[5].globalInteger = 0;
	}
	
}
bool Activities::UseItem::update(CharacterObject *character,
                                 CharacterController *controller) {
    RW_UNUSED(controller);

    if (itemslot >= kMaxInventorySlots) {
        return true;
    }

    // Finds the cycle associated with an anim from the AnimGroup
    /// @todo doesn't need to happen every update..
    auto find_cycle = [&](const std::string &name) {
        if (name == "null") {
            return AnimCycle::Idle;
        }
        for (auto &i : character->animations->animations_) {
            if (i.name == name) return i.id;
        }
        return AnimCycle::Idle;
    };

    auto world = character->engine;
    auto weapon = &world->data->weaponData.at(itemslot);
    auto &state = character->getCurrentState().weapons[itemslot];
    auto &animator = character->animator;
    auto shootcycle = find_cycle(weapon->animation1);
    auto throwcycle = find_cycle(weapon->animation2);

    // No weapon except for Uzi can be used while in a vehicle
    if (character->getCurrentVehicle() && weapon->name != "uzi") {
        return false;
    }

    // Instant hit weapons loop their anim
    // Thrown projectiles have lob / throw.

    // Update player direction
    character->setRotation(
        glm::angleAxis(character->getLook().x, glm::vec3{0.f, 0.f, 1.f}));

    if (state.bulletsClip == 0 && state.bulletsTotal > 0) {
        state.bulletsClip +=
            std::min(static_cast<int>(state.bulletsTotal), weapon->clipSize);
        state.bulletsTotal -= state.bulletsClip;
    }
    bool hasammo = state.bulletsClip > 0;

    if (weapon->fireType == WeaponData::INSTANT_HIT) {
        if (!character->getCurrentState().primaryActive) {
            // Character is no longer firing
            return true;
        }
        if (hasammo) {
            if (character->getCurrentCycle() != shootcycle) {
                character->playCycle(shootcycle);
            }

            auto loopstart = weapon->animLoopStart / 100.f;
            auto loopend = weapon->animLoopEnd / 100.f;
            auto firetime = weapon->animFirePoint / 100.f;

            auto currenttime = animator->getAnimationTime(AnimIndexAction);

            if (currenttime >= firetime && !fired) {
                state.bulletsClip--;
                Weapon::fireHitscan(weapon, character);
                fired = true;
            }
            if (currenttime > loopend) {
                animator->setAnimationTime(AnimIndexAction, loopstart);
                fired = false;
            }
        } else if (animator->isCompleted(AnimIndexAction)) {
            // Should we exit this state when out of ammo?
            return true;
        }
    }
    /// @todo Use Thrown flag instead of project (RPG isn't thrown eg.)
    else if (weapon->fireType == WeaponData::PROJECTILE && hasammo) {
        if (character->getCurrentCycle() == shootcycle) {
            if (character->getCurrentState().primaryActive) {
                power = animator->getAnimationTime(AnimIndexAction) / 0.5f;
            }
            if (animator->isCompleted(AnimIndexAction)) {
                character->playCycle(throwcycle);
            }
        } else if (character->getCurrentCycle() == throwcycle) {
            auto firetime = weapon->animCrouchFirePoint / 100.f;
            auto currID = animator->getAnimationTime(AnimIndexAction);

            if (currID >= firetime && !fired) {
                state.bulletsClip--;
                Weapon::fireProjectile(weapon, character, power);
                fired = true;
            }
            if (animator->isCompleted(AnimIndexAction)) {
                return true;
            }
        } else {
            character->playCycle(shootcycle);
        }
    } else if (weapon->fireType == WeaponData::MELEE) {
        auto currentAnim = character->getCurrentCycle();
        if (currentAnim == shootcycle || currentAnim == throwcycle) {
            auto fireTime = weapon->animFirePoint / 100.f;
            auto loopStart = weapon->animLoopStart / 100.f;
            auto currentTime = animator->getAnimationTime(AnimIndexAction);

            if (currentTime >= fireTime && !fired) {
                Weapon::meleeHit(weapon, character);
                fired = true;
            }

            if (animator->isCompleted(AnimIndexAction)) {
                if (character->getCurrentState().primaryActive) {
                    animator->setAnimationTime(AnimIndexAction, loopStart);
                    fired = false;
                }
                else {
                    return true;
                }
            }
        }
        else {
            const auto onGround = Weapon::targetOnGround(weapon, character);
            if (onGround) {
                character->playCycle(throwcycle);
            }
            else {
                character->playCycle(shootcycle);
            }
        }

    } else {
        RW_ERROR("Unrecognized fireType: " << weapon->fireType);
        return true;
    }

    return false;
}