Example #1
0
void Object::RandomSpawn(bool send_packet) {
	if(!m_ground_spawn)
		return;

	m_data.x = MakeRandomFloat(m_min_x, m_max_x);
	m_data.y = MakeRandomFloat(m_min_y, m_max_y);
	respawn_timer.Disable();

	if(send_packet) {
		EQApplicationPacket app;
		CreateSpawnPacket(&app);
		entity_list.QueueClients(nullptr, &app, true);
	}
}
Example #2
0
void Client::CheckIncreaseTradeskill(int16 bonusstat, int16 stat_modifier, float skillup_modifier, uint16 success_modifier, SkillType tradeskill)
{
	uint16 current_raw_skill = GetRawSkill(tradeskill);

	if(!CanIncreaseTradeskill(tradeskill))
		return;	//not allowed to go higher.

	float chance_stage2 = 0;

	//A successfull combine doubles the stage1 chance for an skillup
	//Some tradeskill are harder than others. See above for more.
	float chance_stage1 = (bonusstat - stat_modifier) / (skillup_modifier * success_modifier);

	//In stage2 the only thing that matters is your current unmodified skill.
	//If you want to customize here you probbably need to implement your own
	//formula instead of tweaking the below one.
	if (chance_stage1 > MakeRandomFloat(0, 99)) {
		if (current_raw_skill < 15) {
			//Always succeed
			chance_stage2 = 100;
		} else if (current_raw_skill < 175) {
			//From skill 16 to 174 your chance of success falls linearly from 92% to 13%.
			chance_stage2 = (200 - current_raw_skill) / 2;
		} else {
			//At skill 175, your chance of success falls linearly from 12.5% to 2.5% at skill 300.
			chance_stage2 = 12.5 - (.08 * (current_raw_skill - 175));
		}
	}
	   
	if (chance_stage2 > MakeRandomFloat(0, 99)) {
		//Only if stage1 and stage2 succeeded you get a skillup.
		SetSkill(tradeskill, current_raw_skill + 1);

		if(title_manager.IsNewTradeSkillTitleAvailable(tradeskill, current_raw_skill + 1))
			NotifyNewTitlesAvailable();
	}

	_log(TRADESKILLS__TRACE, "...skillup_modifier: %f , success_modifier: %d , stat modifier: %d", skillup_modifier , success_modifier , stat_modifier);
	_log(TRADESKILLS__TRACE, "...Stage1 chance was: %f percent",  chance_stage1);
	_log(TRADESKILLS__TRACE, "...Stage2 chance was: %f percent. 0 percent means stage1 failed",  chance_stage2);
}
PyResult Command_spawnbelt( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args )
{
	if( !who->IsInSpace() )
		throw PyException( MakeCustomError( "You must be in space to spawn things." ) );

    const double beltradius = 100000.0;
	const double beltdistance = 25000.0;
	const double roidradius = MakeRandomFloat( 100.0, 1000.0 );
	const double beltangle = M_PI * 2.0 / 3.0;
	const uint32 pcs = 20 + MakeRandomInt( -10, 10 );   // reduced from 160 + MakeRandomInt( -10, 10 )

	const GPoint position( who->GetPosition() );

	const double R = sqrt( position.x * position.x + position.z * position.z );
	const GPoint r = position * ( R + beltdistance - beltradius ) / R;

	double phi = atan( position.x / position.z );
	if( position.z < 0 )
		phi += M_PI;

	SystemManager* sys = who->System();
	std::map<double, uint32> roidDist;
	if( !db->GetRoidDist( sys->GetSystemSecurity(), roidDist ) )
    {
        sLog.Error( "Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity() );

		throw PyException( MakeCustomError( "Couldn't get roid list for system security %s", sys->GetSystemSecurity() ) );
	}

    //double distanceToMe;
	double alpha;
    GPoint mposition;

	for( uint32 i = 0; i < pcs; ++i )
    {
		alpha = beltangle * MakeRandomFloat( -0.5, 0.5 );

		mposition.x = beltradius * sin( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
		mposition.z = beltradius * cos( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
		mposition.y = position.y - r.y + roidradius * MakeRandomFloat( 0, 15 );
        //distanceToMe = (r + mposition - position).length();
        SpawnAsteroid( who->System(), GetAsteroidType( MakeRandomFloat(), roidDist ), roidradius, r + mposition );
	}

	return new PyString( "Spawn successsfull." );
}
Example #4
0
int32 Client::GetActSpellCost(uint16 spell_id, int32 cost)
{
    // Formula = Unknown exact, based off a random percent chance up to mana cost(after focuses) of the cast spell
    if(this->itembonuses.Clairvoyance && spells[spell_id].classes[(GetClass()%16) - 1] >= GetLevel() - 5)
    {
        int16 mana_back = this->itembonuses.Clairvoyance * MakeRandomInt(1, 100) / 100;
        // Doesnt generate mana, so best case is a free spell
        if(mana_back > cost)
            mana_back = cost;

        cost -= mana_back;
    }

    // This formula was derived from the following resource:
    // http://www.eqsummoners.com/eq1/specialization-library.html
    // WildcardX
    float PercentManaReduction = 0;
    float SpecializeSkill = GetSpecializeSkillValue(spell_id);
    int SuccessChance = MakeRandomInt(0, 100);

    float bonus = 1.0;
    switch(GetAA(aaSpellCastingMastery))
    {
    case 1:
        bonus += 0.05;
        break;
    case 2:
        bonus += 0.15;
        break;
    case 3:
        bonus += 0.30;
        break;
    }

    bonus += 0.05 * GetAA(aaAdvancedSpellCastingMastery);

    if(SuccessChance <= (SpecializeSkill * 0.3 * bonus))
    {
        PercentManaReduction = 1 + 0.05 * SpecializeSkill;
        switch(GetAA(aaSpellCastingMastery))
        {
        case 1:
            PercentManaReduction += 2.5;
            break;
        case 2:
            PercentManaReduction += 5.0;
            break;
        case 3:
            PercentManaReduction += 10.0;
            break;
        }

        switch(GetAA(aaAdvancedSpellCastingMastery))
        {
        case 1:
            PercentManaReduction += 2.5;
            break;
        case 2:
            PercentManaReduction += 5.0;
            break;
        case 3:
            PercentManaReduction += 10.0;
            break;
        }
    }

    int16 focus_redux = GetFocusEffect(focusManaCost, spell_id);

    if(focus_redux > 0)
    {
        PercentManaReduction += MakeRandomFloat(1, (double)focus_redux);
    }

    cost -= (cost * (PercentManaReduction / 100));

    // Gift of Mana - reduces spell cost to 1 mana
    if(focus_redux >= 100) {
        uint32 buff_max = GetMaxTotalSlots();
        for (int buffSlot = 0; buffSlot < buff_max; buffSlot++) {
            if (buffs[buffSlot].spellid == 0 || buffs[buffSlot].spellid >= SPDAT_RECORDS)
                continue;

            if(IsEffectInSpell(buffs[buffSlot].spellid, SE_ReduceManaCost)) {
                if(CalcFocusEffect(focusManaCost, buffs[buffSlot].spellid, spell_id) == 100)
                    cost = 1;
            }
        }
    }

    if(cost < 0)
        cost = 0;

    return cost;
}
Example #5
0
//Random formulas for certain calculations to be added in the next few days. -Wizzel
int MakeRandomInt(int low, int high)
{
	if(low == high)
		return(low);
	return (int)MakeRandomFloat((double)low, (double)high + 0.999);
}
Example #6
0
void Client::ProcessOP_Beg(APPLAYER* pApp)
{
/*	if(pApp->size != sizeof(Beg_Struct))
	{
		cout << "Wrong size on OP_Beg. Got: " << pApp->size << ", Expected: " << sizeof(Beg_Struct) << endl;
		return;
	}*/
	if(pApp->size = sizeof(Beg_Struct))
	{
		Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer;
		Message(BLACK,"Begging makes zone a sad panda :( (Our struct is wrong)");
		beg_info->success = 0;
		QueuePacket(pApp);
	}
	else 
	{
	//Yeahlight: Purge client's invisibility
	CancelAllInvisibility();
	
	Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer;
	
	Mob* target = entity_list.GetMob(beg_info->target);
	Mob* player = entity_list.GetMob(beg_info->begger);
	
	//Beg_Struct* beg_info = (Beg_Struct*)pApp->pBuffer;
	// Validate Player
	// Added this check to keep people from fudging packets to make
	// mobs attack other through begging.  Flag as a hack also.
	if(this->GetID() != player->GetID())
	{
		cout << "[ hack ]" << this->GetName() << " is begging for another player: ";
		cout << player->GetName() << endl;
		
		// This will make the client not able to beg anymore.
		// Could we send qa packet back with 'beg_info->success = 0?
		// Nah, I'd rather just leave the hackers with a broken client. -neorab

		return;
	}

	// Validate Time
	// Should not be able to send two beg requests within 10 seconds.
	// Flag beg spammers as hackers.  Drop the packet and move on.
	int32 time_to_beg = beg_timer->GetRemainingTime();
	if(time_to_beg != 0) 
	{
		cout << "[ hack ]" << player->GetName() << " is begging to fast. ";
		cout << 10000 - time_to_beg << "ms since last beg." << endl;
		
		// This will make the client not able to beg anymore.
		return;
	}
	beg_timer->Start(10000);

	// Validate Target
	// Should not be able to beg from other players, corpses or pets.
	// Basiclly, the client will have to have the same thing targeted
	// as the packet says they do.  If they target a pet and send a beg
	// packet with the pet as the target, this won't catch it.  But it'll
	// stop the average dumbass forging packets.
	Mob* tmptar = this->GetTarget();
	if((tmptar->GetID() != target->GetID()) || target->IsNPC() != true)
	{
		cout << "[ hack ]" << player->GetName() << " is begging from: " << target->GetName();
		cout << "but has [" << tmptar->GetName() << "] targeted." << endl;
		
		// This will make the client not able to beg anymore.
		return;
	}
	
	// Validate Skill
	// Look the skill up, flag the account for hacks if they don't match.
	int8 beg_skill = this->GetSkill(BEGGING);
	if(beg_skill != beg_info->skill)
	{
		cout << "[ hack ]" << player->GetName() << " is trying to beg at " << beg_info->skill;
		cout << "but is [" << beg_skill << "] skill." << endl;
		
		// This will make the client not able to beg anymore.
		return;
	}


	// Pets.
	// You cannot succeed or crit fail on pets.
	if(target->CastToNPC()->GetOwner() == 0)
	{

		// Roll The Dice for Success
		// the threshold is the number you have to be under to have begged successfully
		//   skill level / 8000 (0 - 4% liner based on skill)
		// + Charisma Modifier (same as skill level) *  active charisma % (20% for ever 51 levels)
		double success_threshold = ((double)beg_skill / 8000) 
			+ (( (int)((double)beg_skill / 51) * 0.20) * ((double)player->GetCHA() / 8500));
		double the_dice = MakeRandomFloat(0.000, 1.000);
		
		if(the_dice <= success_threshold)
		{
			char message[255];
			sprintf(message, "%s says, \"Here %s, take this and LEAVE ME ALONE!\"", target->GetName(), player->GetName());
			Message(WHITE, message);
			beg_info->success = 4;
			if(the_dice == success_threshold)
			{
				beg_info->coins = 2;
			}
			else
			{
				beg_info->coins = 1;
			}
		}

		// Critical Failure =)
		else
		{
			beg_info->success = 0;
			// Random Attack (5% @ 0skill 1% @ 200 skill)
			the_dice = MakeRandomFloat(0.000, 1.000);
			if(the_dice <= (0.05 - (int)((double)beg_skill / 50) * 0.01))
			{
				char message[255];
				sprintf(message, "%s says, \"Beggers like you always bring out the worst in me.\"", target->GetName());
				target->CastToNPC()->AddToHateList(player);
				Message(DARK_RED, message);
			}
		}
	}

	// This is a pet, never allow them to succeed.
	else
	{
		beg_info->success = 0;
	}
	

	// Random Skill-Up
	// This was a bitch skill to learn.  Let's do ~1/2% change to skill up.
	// I'm not using the CheckAddSkill function here because that does not
	// let us control it quite like this.  I really don't believe every
	// skill uses the same formula. -neorab
	int dice = MakeRandomInt(0, 200);
	if(dice <= 1)
	{
		if(GetSkill(BEGGING) < CheckMaxSkill(BEGGING, this->race, this->class_, this->level))
		{
			SetSkill(BEGGING, GetSkill(BEGGING)+1);
		}
	}


	// Save Player Profile
	// The return told the client they got more money, we should save that
	// server side to reflect the extra cash.
	if(beg_info->success != 0)
	{
		AddMoneyToPP(beg_info->coins, 0, 0, 0, false);
	}
	
	QueuePacket(pApp);
}
}
Example #7
0
//returns true on success
bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
 	if(spec == NULL)
		return(false);
	
	uint16 user_skill = GetSkill(spec->tradeskill);
	float chance = 0.0;
	float skillup_modifier = 0.0;
	int16 thirdstat = 0;
	int16 stat_modifier = 15;
	uint16 success_modifier = 0;

	// Rework based on the info on eqtraders.com
	// http://mboards.eqtraders.com/eq/showthread.php?t=22246
	// 09/10/2006 v0.1 (eq4me)
	// 09/11/2006 v0.2 (eq4me)
	// Todo:
	//     Implementing AAs
	//     Success modifiers based on recipes
	//     Skillup modifiers based on the rarity of the ingredients

	// Some tradeskills are more eqal then others. ;-)
	// If you want to customize the stage1 success rate do it here.
    // Remember: skillup_modifier is (float). Lower is better
	switch(spec->tradeskill) {
	case FLETCHING:
	case ALCHEMY:
	case JEWELRY_MAKING:
	case POTTERY:
		skillup_modifier = 4;
		break;
	case BAKING:
	case BREWING:
		skillup_modifier = 3;
		break;
	case RESEARCH:
		skillup_modifier = 1;
		break;
	default:
		skillup_modifier = 2;
		break;
	}

	// Some tradeskills take the higher of one additional stat beside INT and WIS
	// to determine the skillup rate. Additionally these tradeskills do not have an
	// -15 modifier on their statbonus.
	if (spec->tradeskill ==  FLETCHING || spec->tradeskill == MAKE_POISON) {
		thirdstat = GetDEX();
		stat_modifier = 0;
	} else if (spec->tradeskill == BLACKSMITHING) {
		thirdstat = GetSTR();
		stat_modifier = 0;
	}
	
	int16 higher_from_int_wis = (GetINT() > GetWIS()) ? GetINT() : GetWIS();
	int16 bonusstat = (higher_from_int_wis > thirdstat) ? higher_from_int_wis : thirdstat;
	
	vector< pair<uint32,uint8> >::iterator itr;


    //calculate the base success chance
	// For trivials over 68 the chance is (skill - 0.75*trivial) +51.5
    // For trivial up to 68 the chance is (skill - trivial) + 66
	if (spec->trivial >= 68) {
		chance = (user_skill - (0.75*spec->trivial)) + 51.5;
	} else {
		chance = (user_skill - spec->trivial) + 66;
	}
	
	int16 over_trivial = (int16)GetRawSkill(spec->tradeskill) - (int16)spec->trivial;

	//handle caps
	if(spec->nofail) {
		chance = 100;	//cannot fail.
		_log(TRADESKILLS__TRACE, "...This combine cannot fail.");
	} else if(over_trivial >= 0) {
		// At reaching trivial the chance goes to 95% going up an additional
		// percent for every 40 skillpoints above the trivial.
		// The success rate is not modified through stats.
		// Mastery AAs are unaccounted for so far.
		// chance_AA = chance + ((100 - chance) * mastery_modifier)
		// But the 95% limit with an additional 1% for every 40 skill points
		// above critical still stands.
		// Mastery modifier is: 10%/25%/50% for rank one/two/three
		chance = 95.0f + (float(user_skill - spec->trivial) / 40.0f);
		Message_StringID(MT_Emote, TRADESKILL_TRIVIAL);
	} else if(chance < 5) {
		// Minimum chance is always 5
		chance = 5;
	} else if(chance > 95) {
		//cap is 95, shouldent reach this before trivial, but just in case.
		chance = 95;
	}
	
	_log(TRADESKILLS__TRACE, "...Current skill: %d , Trivial: %d , Success chance: %f percent", user_skill , spec->trivial , chance);
	_log(TRADESKILLS__TRACE, "...Bonusstat: %d , INT: %d , WIS: %d , DEX: %d , STR: %d", bonusstat , GetINT() , GetWIS() , GetDEX() , GetSTR());
	
	float res = MakeRandomFloat(0, 99);
	int AAChance = 0;

	//AA modifiers
	//can we do this with nested switches?
	if(spec->tradeskill == ALCHEMY){
		switch(GetAA(aaAlchemyMastery)){
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if(spec->tradeskill == JEWELRY_MAKING){
		switch(GetAA(aaJewelCraftMastery)){
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}
      const Item_Struct* item = NULL;

	if (spec->tradeskill == BLACKSMITHING) {
		switch(GetAA(aaBlacksmithingMastery)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (spec->tradeskill == BAKING) {
		switch(GetAA(aaBakingMastery)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (spec->tradeskill == BREWING) {
		switch(GetAA(aaBrewingMastery)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (spec->tradeskill == FLETCHING) {
		switch(GetAA(aaFletchingMastery2)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (spec->tradeskill == POTTERY) {
		switch(GetAA(aaPotteryMastery)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (spec->tradeskill == TAILORING) {
		switch(GetAA(aaTailoringMastery)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}
	
	if (spec->tradeskill == RESEARCH) {
		switch(GetAA(aaArcaneTongues)) {
		case 1:
			AAChance = 10;
			break;
		case 2:
			AAChance = 25;
			break;
		case 3:
			AAChance = 50;
			break;
		}
	}

	if (((spec->tradeskill==75) || GetGM() || (chance > res)) || MakeRandomInt(0, 99) < AAChance){
		success_modifier = 1;
		
		if(over_trivial < 0)
			CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
		
		Message_StringID(4,TRADESKILL_SUCCEED,spec->name.c_str());

		_log(TRADESKILLS__TRACE, "Tradeskill success");

		itr = spec->onsuccess.begin();
		while(itr != spec->onsuccess.end() && !spec->quest) {
			//should we check this crap?
			SummonItem(itr->first, itr->second);
                  item = database.GetItem(itr->first);
			if (this->GetGroup())
			{
				entity_list.MessageGroup(this,true,MT_Skills,"%s has successfully fashioned %s!",GetName(),item->Name);
			}
			if(RuleB(TaskSystem, EnableTaskSystem))
				UpdateTasksForItem(ActivityTradeSkill, itr->first, itr->second);
			itr++;
		}
		return(true);
	} else {
		success_modifier = 2; // Halves the chance
		
		if(over_trivial < 0)
			CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
		
		Message_StringID(MT_Emote,TRADESKILL_FAILED);

		_log(TRADESKILLS__TRACE, "Tradeskill failed");
            if (this->GetGroup())
		{
			entity_list.MessageGroup(this,true,MT_Skills,"%s was unsuccessful in %s tradeskill attempt.",GetName(),this->GetGender() == 0 ? "his" : this->GetGender() == 1 ? "her" : "its");
		}
		
		itr = spec->onfail.begin();
		while(itr != spec->onfail.end()) {
			//should we check these arguments?
			SummonItem(itr->first, itr->second);
			itr++;
		}

        // Rolls on each item, is possible to return everything
        int SalvageChance = aabonuses.SalvageChance + itembonuses.SalvageChance + spellbonuses.SalvageChance;
        // Skip check if not a normal TS or if a quest recipe these should be nofail, but check amyways
        if(SalvageChance && spec->tradeskill != 75 && !spec->quest) {
            itr = spec->salvage.begin();
            uint8 sc = 0;
            while(itr != spec->salvage.end()) {
                for(sc = 0; sc < itr->second; sc++)
                    if(MakeRandomInt(0,99) < SalvageChance)
                        SummonItem(itr->first, 1);
                itr++;
            }
        }

	}
	return(false);
}
Example #8
0
PyResult Command_spawnbelt( Client* who, CommandDB* db, PyServiceMgr* services, const Seperator& args )
{
    if( !who->IsInSpace() )
        throw PyException( MakeCustomError( "You must be in space to spawn things." ) );

	bool makeIceBelt = false;
	bool makeRareIce = false;
	uint32 customCount = 0;
    if( args.argCount() >= 2 )
	{
        if( !args.isNumber( 1 ) )
		{
			if( args.arg( 1 ) == "ice" )
				makeIceBelt = true;
		}
		else
		{
			if( atoi(args.arg( 1 ).c_str()) > 15 )
				customCount = atoi(args.arg( 1 ).c_str());
			else
				PyException( MakeCustomError( "Argument 1 should be at least 15!" ) );
		}
	}

	if( args.argCount() >= 3 )
	{
		if( args.isNumber( 2 ) )
		{
			if( atoi(args.arg( 2 ).c_str()) > 15 )
				customCount = atoi(args.arg(2).c_str());
			else
				PyException( MakeCustomError( "Argument 2 should be at least 15!" ) );
		}
		else
			if( args.arg( 2 ) == "ice" )
				makeIceBelt = true;
			if( args.arg( 2 ) == "rareice" )
			{
				makeIceBelt = true;
				makeRareIce = true;
			}
	}

    const double beltradius = 100000.0;
    const double beltdistance = 25000.0;
    double roidradius;
    const double beltangle = M_PI * 2.0 / 3.0;
    uint32 pcs = 0;
	
	if( customCount > 15 )
		pcs = customCount + static_cast<uint32>(MakeRandomInt( -10, 10 ));
	else
		pcs = 30 + static_cast<uint32>(MakeRandomInt( -10, 10 ));

    const GPoint position( who->GetPosition() );

    const double R = sqrt( position.x * position.x + position.z * position.z );
    const GPoint r = position * ( R + beltdistance - beltradius ) / R;

    double phi = atan( position.x / position.z );
    if( position.z < 0 )
        phi += M_PI;

    SystemManager* sys = who->System();
    std::map<double, uint32> roidDist;
	if( makeIceBelt )
	{
		std::string securityStatus = sys->GetSystemSecurity();
		if( !makeRareIce )
		{
			roidDist.insert(std::pair<double,uint32>(0.60,16264));		// Blue Ice
			roidDist.insert(std::pair<double,uint32>(0.45,17975));		// Thick Blue Ice
			roidDist.insert(std::pair<double,uint32>(0.30,28627));		// Azure Ice
			roidDist.insert(std::pair<double,uint32>(0.20,16262));		// Clear Icicle
			roidDist.insert(std::pair<double,uint32>(0.10,16267));		// Dark Glitter
		}
		if( makeRareIce )
		{
			roidDist.insert(std::pair<double,uint32>(0.90,16263));		// Glacial Mass
			roidDist.insert(std::pair<double,uint32>(0.80,16265));		// White Glaze
			roidDist.insert(std::pair<double,uint32>(0.70,16266));		// Glare Crust
			roidDist.insert(std::pair<double,uint32>(0.60,16268));		// Gelidus
			roidDist.insert(std::pair<double,uint32>(0.50,16269));		// Krystallos
			roidDist.insert(std::pair<double,uint32>(0.40,17976));		// Pristine White Glaze
			roidDist.insert(std::pair<double,uint32>(0.30,17977));		// Smooth Glacial Mass
			roidDist.insert(std::pair<double,uint32>(0.20,17978));		// Enriched Clear Icicle
			roidDist.insert(std::pair<double,uint32>(0.10,28628));		// Crystalline Icicle
		}
	}
	else
	{
		if( !db->GetRoidDist( sys->GetSystemSecurity(), roidDist ) )
		{
			sLog.Error( "Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity() );

			throw PyException( MakeCustomError( "Couldn't get roid list for system security %s", sys->GetSystemSecurity() ) );
		}
	}

    double distanceToMe;
    double alpha;
    GPoint mposition;

	if( makeIceBelt )
		pcs *= 2;

    for( uint32 i = 0; i < pcs; ++i )
    {
        alpha = beltangle * MakeRandomFloat( -0.5, 0.5 );

		if( makeIceBelt )
			roidradius = MakeRandomFloat( 1000.0, 10000.0 );
		else
			roidradius = MakeRandomFloat( 100.0, 1000.0 );
        mposition.x = beltradius * sin( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
        mposition.z = beltradius * cos( phi + alpha ) + roidradius * MakeRandomFloat( 0, 15 );
        mposition.y = position.y - r.y + roidradius * MakeRandomFloat( 0, 15 );
        distanceToMe = (r + mposition - position).length();
        SpawnAsteroid( who->System(), GetAsteroidType( MakeRandomFloat(), roidDist ), roidradius, r + mposition );
    }

    return new PyString( "Spawn successsfull." );
}
Example #9
0
// Queries the loottable: adds item & coin to the npc
void ZoneDatabase::AddLootTableToNPC(NPC* npc,uint32 loottable_id, ItemList* itemlist, uint32* copper, uint32* silver, uint32* gold, uint32* plat) {
	_ZP(Database_AddLootTableToNPC);
//if (loottable_id == 178190)
//DebugBreak();
	const LootTable_Struct* lts = 0;
	*copper = 0;
	*silver = 0;
	*gold = 0;
	*plat = 0;

	lts = database.GetLootTable(loottable_id);
	if (!lts)
		return;

	// do coin
	if (lts->mincash > lts->maxcash) {
		std::cerr << "Error in loottable #" << loottable_id << ": mincash > maxcash" << std::endl;
	}
	else if (lts->maxcash != 0) {
		uint32 cash = 0;
		if (lts->mincash == lts->maxcash)
			cash = lts->mincash;
		else
			cash = MakeRandomInt(lts->mincash, lts->maxcash);
		if (cash != 0) {
			if (lts->avgcoin != 0) {
				//this is some crazy ass stuff... and makes very little sense... dont use it, k?
				uint32 mincoin = (uint32) (lts->avgcoin * 0.75 + 1);
				uint32 maxcoin = (uint32) (lts->avgcoin * 1.25 + 1);
				*copper = MakeRandomInt(mincoin, maxcoin);
				*silver = MakeRandomInt(mincoin, maxcoin);
				*gold = MakeRandomInt(mincoin, maxcoin);
				if(*copper > cash) { *copper = cash; }
					cash -= *copper;
				if(*silver>(cash/10)) { *silver = (cash/10); }
					cash -= *silver*10;
				if(*gold > (cash/100)) { *gold = (cash/100); }
					cash -= *gold*100;
			}
			if (cash < 0) {
				cash = 0;
			}
			*plat = cash / 1000;
			cash -= *plat * 1000;
			uint32 gold2 = cash / 100;
			cash -= gold2 * 100;
			uint32 silver2 = cash / 10;
			cash -= silver2 * 10;
			*gold += gold2;
			*silver += silver2;
			*copper += cash;
		}
	}

	// Do items
	for (uint32 i=0; i<lts->NumEntries; i++) {
		for (uint32 k = 1; k <= lts->Entries[i].multiplier; k++) {
			uint8 droplimit = lts->Entries[i].droplimit;
			uint8 mindrop = lts->Entries[i].mindrop;

			//LootTable Entry probability
			float ltchance = 0.0f;
			ltchance = lts->Entries[i].probability;

			float drop_chance = 0.0f;
			if(ltchance > 0.0 && ltchance < 100.0) {
				drop_chance = MakeRandomFloat(0.0, 100.0);
			}

			if (ltchance != 0.0 && (ltchance == 100.0 || drop_chance < ltchance)) {
				AddLootDropToNPC(npc,lts->Entries[i].lootdrop_id, itemlist, droplimit, mindrop);
			}
		}
	}
}
Example #10
0
// Called by AddLootTableToNPC
// maxdrops = size of the array npcd
void ZoneDatabase::AddLootDropToNPC(NPC* npc,uint32 lootdrop_id, ItemList* itemlist, uint8 droplimit, uint8 mindrop) {
	const LootDrop_Struct* lds = GetLootDrop(lootdrop_id);
	if (!lds) {
		return;
	}
	if(lds->NumEntries == 0)	//nothing possible to add
		return;

	// Too long a list needs to be limited.
	if(lds->NumEntries > 99 && droplimit < 1)
		droplimit = lds->NumEntries/100;

	uint8 limit = 0;
	// Start at a random point in itemlist.
	uint32 item = MakeRandomInt(0, lds->NumEntries-1);
	// Main loop.
	for (uint32 i=0; i<lds->NumEntries;)
	{
		//Force the itemlist back to beginning.
		if (item > (lds->NumEntries-1))
			item = 0;

		uint8 charges = lds->Entries[item].multiplier;
		uint8 pickedcharges = 0;
		// Loop to check multipliers.
		for (uint32 x=1; x<=charges; x++)
		{
			// Actual roll.
			float thischance = 0.0;
			thischance = lds->Entries[item].chance;

			float drop_chance = 0.0;
			if(thischance != 100.0)
				drop_chance = MakeRandomFloat(0.0, 100.0);

#if EQDEBUG>=11
			LogFile->write(EQEMuLog::Debug, "Drop chance for npc: %s, this chance:%f, drop roll:%f", npc->GetName(), thischance, drop_chance);
#endif
			if (thischance == 100.0 || drop_chance < thischance)
			{
				uint32 itemid = lds->Entries[item].item_id;

				const Item_Struct* dbitem = GetItem(itemid);
				npc->AddLootDrop(dbitem, itemlist, lds->Entries[item].item_charges, lds->Entries[item].minlevel, lds->Entries[item].maxlevel, lds->Entries[item].equip_item, false);
				pickedcharges++;
			}
		}
		// Items with multipliers only count as 1 towards the limit.
		if(pickedcharges > 0)
			limit++;

		// If true, limit reached.
		if(limit >= droplimit && droplimit > 0)
			break;

		item++;
		i++;

		// We didn't reach our minimium, run loop again.
		if(i == lds->NumEntries){
			if(limit < mindrop){
				i = 0;
			}
		}
	} // We either ran out of items or reached our limit.
}
Example #11
0
void SpawnEntry::_DoSpawn(SystemManager &mgr, PyServiceMgr &svc) {
	_log(SPAWN__POP, "Spawning spawn entry %u with group %u", m_id, m_group.id);
	
	//pick our spawn point...
	GPoint spawn_point;
	switch(m_boundsType) {	//safe to assume `bounds` are correct.
	
	case boundsPoint: {
		spawn_point = bounds[0];
	} break;
	
	case boundsLine: {
		GVector vec(bounds[0], bounds[1]);
		double len = vec.length();
		
		spawn_point = GPoint(bounds[0] + Ga::GaFloat(MakeRandomFloat(0, len))*Ga::GaVec3(vec));
	} break;
	
	default:
		_log(SPAWN__ERROR, "Invalid bounds type %u on spawn entry %u when spawning...", m_boundsType, GetID());
		return;
	}
	_log(SPAWN__POP, "    selected point (%.1f, %.1f, %.1f)", spawn_point.x, spawn_point.y, spawn_point.z);

	std::vector<NPC *> spawned;
	
	//now see what is gunna spawn...
	std::vector<SpawnGroup::Entry>::const_iterator cur, end;
	cur = m_group.entries.begin();
	end = m_group.entries.end();
	for(; cur != end; cur++) {
		_log(SPAWN__POP, "    Evaluating spawn entry for NPC type %u in group %u", cur->npcTypeID, cur->spawnGroupID);
		int r;
		for(r = 0; r < cur->quantity; r++) {
			if(cur->probability < 1.0f) {
				if(MakeRandomFloat(0, 1.0f) > cur->probability) {
					_log(SPAWN__POP, "        [%d] not spawning, p=%.4f failed.", r, cur->probability);
					continue;
				}
				_log(SPAWN__POP, "        [%d] passed proability check of p=%.4f", r, cur->probability);
			}

			//NOTE: this is currently creating an entry in the DB...
			//which is terrible... we need to make an "in-memory only"
			// item concept.
			ItemData idata(
				cur->npcTypeID,
				cur->ownerID,	//owner
				mgr.GetID(),
				flagAutoFit
			);

			InventoryItemRef i = svc.item_factory.SpawnItem(idata);
			if( !i ) {
				_log(SPAWN__ERROR, "Failed to spawn item with type %u for group %u.", cur->npcTypeID, cur->spawnGroupID);
				continue;
			}
			
			_log(SPAWN__POP, "        [%d] spawning NPC id %u", r, i->itemID());
			
			//create them all at the same point to start with...
			//we will move them before they get added to the system
			NPC *npc = new NPC(&mgr, svc,
				i, cur->corporationID, 0, spawn_point, this);	//TODO: add allianceID
			spawned.push_back(npc);
		}
	}
	
	if(spawned.empty()) {
		int timer = MakeRandomInt(m_timerMin, m_timerMax);
		_log(SPAWN__POP, "No NPCs produced by spawn entry %u. Resetting spawn timer to %d s.", m_id, timer);
		m_timer.Start(timer*1000);
		return;
	}
	
	//TODO: apply formation..
	//hacking it for now...
	std::vector<NPC *>::iterator curn, endn;
	curn = spawned.begin();
	endn = spawned.end();
	for(; curn != endn; curn++) {
		_log(SPAWN__POP, "Moving NPC %u to (%.1f, %.1f, %.1f) due to formation.", (*curn)->GetID(), spawn_point.x, spawn_point.y, spawn_point.z);
		(*curn)->ForcedSetPosition(spawn_point);
		spawn_point.y += 1000.0f;
	}
	
	
	//now the NPCs are all set up, lets drop them into the system.
	curn = spawned.begin();
	endn = spawned.end();
	for(; curn != endn; curn++) {
		//load up any NPC attributes...
		if(!(*curn)->Load(svc.serviceDB())) {
			_log(SPAWN__POP, "Failed to load NPC data for NPC %u with type %u, depoping.", (*curn)->GetID(), (*curn)->Item()->typeID());
			delete *curn;
			continue;
		}
		
		//record this NPC as something we spawned.
		m_spawnedIDs.insert((*curn)->GetID());
		
		mgr.AddNPC(*curn);
	}
	
	//timer is disabled while the spawn is up.
	m_timer.Disable();
}
Example #12
0
/*
 * SQL to remove all asteroids from space in ALL systems.
 * Important, run in this order or the attributes will not be deleted!
 * 
DELETE FROM srvEntity_default_attributes WHERE attributeID > 0 and itemID in
(SELECT itemID from srvEntity where ownerID=1 AND typeID in
(SELECT typeID from invTypes where groupID in
(select groupID FROM invGroups where categoryID=25) or groupID=711));
DELETE FROM srvEntity_attributes WHERE attributeID > 0 and itemID in
(SELECT itemID from srvEntity where ownerID=1 AND typeID in
(SELECT typeID from invTypes where groupID in
(select groupID FROM invGroups where categoryID=25) or groupID=711));
DELETE FROM srvEntity WHERE itemID>=140000000 AND ownerID=1 AND typeID in
(SELECT typeID from invTypes where groupID in
(select groupID FROM invGroups where categoryID=25) or groupID=711);
 * 
 */
PyResult Command_spawnbelt( Client* who, const Seperator& args )
{
    if (!who->IsInSpace())
    {
        throw PyException(MakeCustomError("You must be in space to spawn things."));
    }

	bool makeIceBelt = false;
	bool makeRareIce = false;
	uint32 customCount = 0;
    if( args.argCount() >= 2 )
	{
        if( !args.isNumber( 1 ) )
		{
			if( args.arg( 1 ) == "ice" )
				makeIceBelt = true;
		}
		else
		{
			if( atoi(args.arg( 1 ).c_str()) > 15 )
				customCount = atoi(args.arg( 1 ).c_str());
			else
				PyException( MakeCustomError( "Argument 1 should be at least 15!" ) );
		}
	}

	if( args.argCount() >= 3 )
	{
		if( args.isNumber( 2 ) )
		{
			if( atoi(args.arg( 2 ).c_str()) > 15 )
				customCount = atoi(args.arg(2).c_str());
			else
				PyException( MakeCustomError( "Argument 2 should be at least 15!" ) );
		}
		else
			if( args.arg( 2 ) == "ice" )
				makeIceBelt = true;
			if( args.arg( 2 ) == "rareice" )
			{
				makeIceBelt = true;
				makeRareIce = true;
			}
    }

    double beltradius = 25000.0; // 25 KM
    if(makeIceBelt)
    {
        beltradius = 100000.0; // 100 KM
    }
    uint32 pcs = 0;

    if (customCount > 15)
    {
        pcs = customCount + static_cast<uint32> (MakeRandomInt(-10, 10));
    }
    else
    {
        pcs = 200 + static_cast<uint32> (MakeRandomInt(-10, 10));
    }

    SystemManager* sys = who->System();
    std::map<double, uint32> roidDist;
    if (makeIceBelt)
    {
        pcs /= 8;
        std::string securityStatus = sys->GetSystemSecurity();
        if (!makeRareIce)
        {
            roidDist.insert(std::pair<double, uint32>(0.60, 16264)); // Blue Ice
            roidDist.insert(std::pair<double, uint32>(0.45, 17975)); // Thick Blue Ice
            roidDist.insert(std::pair<double, uint32>(0.30, 28627)); // Azure Ice
            roidDist.insert(std::pair<double, uint32>(0.20, 16262)); // Clear Icicle
            roidDist.insert(std::pair<double, uint32>(0.10, 16267)); // Dark Glitter
        }
        if (makeRareIce)
        {
            roidDist.insert(std::pair<double, uint32>(0.90, 16263)); // Glacial Mass
            roidDist.insert(std::pair<double, uint32>(0.80, 16265)); // White Glaze
            roidDist.insert(std::pair<double, uint32>(0.70, 16266)); // Glare Crust
            roidDist.insert(std::pair<double, uint32>(0.60, 16268)); // Gelidus
            roidDist.insert(std::pair<double, uint32>(0.50, 16269)); // Krystallos
            roidDist.insert(std::pair<double, uint32>(0.40, 17976)); // Pristine White Glaze
            roidDist.insert(std::pair<double, uint32>(0.30, 17977)); // Smooth Glacial Mass
            roidDist.insert(std::pair<double, uint32>(0.20, 17978)); // Enriched Clear Icicle
            roidDist.insert(std::pair<double, uint32>(0.10, 28628)); // Crystalline Icicle
        }
    }
    else
    {
        if (!CommandDB::GetRoidDist(sys->GetSystemSecurity(), roidDist))
        {
            SysLog::Error("Command", "Couldn't get roid list for system security %s", sys->GetSystemSecurity());

            throw PyException(MakeCustomError("Couldn't get roid list for system security %s", sys->GetSystemSecurity()));
        }
    }

    const GPoint position(who->GetPosition());
    double phi = atan(position.x / position.z);
    if (position.z == 0)
    {
        phi = M_PI / 2;
    }
    if (position.z < 0)
    {
        phi += M_PI;
    }
    GPoint beltOffset;
    if (makeIceBelt)
    {
        beltOffset.x = (beltradius * 0.75) * sin(phi);
        beltOffset.z = (beltradius * 0.75) * cos(phi);
    }
    double alpha;
    GPoint mposition;
    double beltThickness = 3000;
    double height;
    double roidradius;
    const double beltangle = M_PI * 2.0 / 3.0;
    int triesLeft = pcs * 25;
    int pcsLeft = pcs;
    std::vector<std::pair<GPoint, double>> spawned;
    while (triesLeft-- && pcsLeft)
    {
        uint32 typeID = GetAsteroidType(MakeRandomFloat(), roidDist);
        // Generate asteroid parameters.
		if( makeIceBelt)
        {
            height = MakeRandomFloat(-0.2, 1.8);
            alpha = beltangle * ((M_PI / 8) * height);
            roidradius = MakeRandomFloat(4000.0, 10000.0);
            height *= 8;
        }
        else
        {
            alpha = beltangle * MakeRandomFloat(-M_PI / 4, M_PI / 4);
			roidradius = MakeRandomFloat( 100.0, 1000.0 );
            height = MakeRandomFloat(-1, 1);
            const ItemType *type = ItemFactory::GetType(typeID);
            if (type->groupID() == EVEDB::invGroups::Veldspar)
            {
                roidradius *= 2;
            }
        }
        // Calculate new position.
        mposition.y = beltThickness * height;
        mposition.x = beltradius * sin(phi + alpha) + beltThickness * MakeRandomFloat(-1, 1);
        mposition.z = beltradius * cos(phi + alpha) + beltThickness * MakeRandomFloat(-1, 1);
        // Check for collision.
        bool collision = false;
        for (auto pair : spawned)
        {
            GPoint point = pair.first;
            double dist = (mposition - point).length();
            double radii = (roidradius + pair.second);
            if ((dist - radii) < 0)
            {
                collision = true;
                continue;
            }
        }
        if (collision)
        {
            // There was a collision, try again.
            continue;
        }
        // Were good, add the asteroid.
        pcsLeft--;
        SpawnAsteroid(who->System(), typeID, roidradius, mposition + position - beltOffset);
        // Save the location for collision checks.
        spawned.push_back(std::pair<GPoint, double>(mposition, roidradius));
    }

    return new PyString( "Spawn successsfull." );
}
Example #13
0
void Adventure::MoveCorpsesToGraveyard()
{
	if(GetTemplate()->graveyard_zone_id == 0)
	{
		return;
	}

	list<uint32> dbid_list;
	list<uint32> charid_list;
	char errbuf[MYSQL_ERRMSG_SIZE];
	char* query = 0;
	MYSQL_RES *result;
	MYSQL_ROW row;

	if(database.RunQuery(query,MakeAnyLenString(&query,"SELECT id, charid FROM player_corpses WHERE instanceid=%d", GetInstanceID()), errbuf, &result)) 
	{
		while((row = mysql_fetch_row(result))) 
		{
			dbid_list.push_back(atoi(row[0]));
			charid_list.push_back(atoi(row[1]));
		}
		mysql_free_result(result);
		safe_delete_array(query);
	}
	else
	{
		LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
		safe_delete_array(query);
	}

	list<uint32>::iterator iter = dbid_list.begin();
	while(iter != dbid_list.end())
	{
		float x = GetTemplate()->graveyard_x + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
		float y = GetTemplate()->graveyard_y + MakeRandomFloat(-GetTemplate()->graveyard_radius, GetTemplate()->graveyard_radius);
		float z = GetTemplate()->graveyard_z;
		if(database.RunQuery(query,MakeAnyLenString(&query, "UPDATE player_corpses SET zoneid=%d, instanceid=0, x=%f, y=%f, z=%f WHERE instanceid=%d", 
			GetTemplate()->graveyard_zone_id, x, y, z, GetInstanceID()), errbuf)) 
		{
			safe_delete_array(query);
		}
		else
		{
			LogFile->write(EQEMuLog::Error, "Error in AdventureManager:::MoveCorpsesToGraveyard: %s (%s)", query, errbuf);
			safe_delete_array(query);
		}
		iter++;
	}

	iter = dbid_list.begin();
	list<uint32>::iterator c_iter = charid_list.begin();
	while(iter != dbid_list.end())
	{
		ServerPacket* pack = new ServerPacket(ServerOP_DepopAllPlayersCorpses, sizeof(ServerDepopAllPlayersCorpses_Struct));
		ServerDepopAllPlayersCorpses_Struct *dpc = (ServerDepopAllPlayersCorpses_Struct*)pack->pBuffer;
		dpc->CharacterID = (*c_iter);
		dpc->InstanceID = 0;
		dpc->ZoneID = GetTemplate()->graveyard_zone_id;
		zoneserver_list.SendPacket(0, GetInstanceID(), pack);
		delete pack;

		pack = new ServerPacket(ServerOP_SpawnPlayerCorpse, sizeof(SpawnPlayerCorpse_Struct));
		SpawnPlayerCorpse_Struct* spc = (SpawnPlayerCorpse_Struct*)pack->pBuffer;
		spc->player_corpse_id = (*iter);
		spc->zone_id = GetTemplate()->graveyard_zone_id;

		zoneserver_list.SendPacket(spc->zone_id, 0, pack);
		delete pack;
		iter++;
		c_iter++;
	}
}