예제 #1
0
bool Character::AlterBalance(double balanceChange) {
    if(balanceChange == 0)
        return true;

    double result = balance() + balanceChange;

    //remember, this can take a negative amount...
    if(result < 0)
        return false;

    m_balance = result;

    //TODO: save some info to journal.
    SaveCharacter();

    return true;
}
예제 #2
0
void SellConfirmMenu_handler(edict_t *ent, int option)
{
	if (option - 777 > 0)
	{
		int i;
		item_t *slot = &ent->myskills.items[option - 778];
		int value = GetSellValue(slot);

		//log the sale
		WriteToLogfile(ent, va("Selling rune for %d credits. [%s]", value, slot->id));

		//Copy item to armory
		GiveRuneToArmory(slot);

		//Delete item
		memset(slot, 0, sizeof(item_t));
		gi.cprintf(ent, PRINT_HIGH, "Item Sold for %d credits.\n", value);

		//Re-apply equipment
		V_ResetAllStats(ent);
		for (i = 0; i < 3; ++i)
			V_ApplyRune(ent, &ent->myskills.items[i]);

		//refund some credits
		ent->myskills.credits += value;
		gi.cprintf(ent, PRINT_HIGH, "You now have %d credits.\n", ent->myskills.credits);
		gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/gold.wav"), 1, ATTN_NORM, 0);

		//save the player file
		SaveCharacter(ent);

	}
	else if (option - 666 > 0)
	{
		//Back to select sell item
		OpenSellMenu(ent, option - 666);
		return;
	}
	else
	{
		//Closing menu
		closemenu(ent);
		return;
	}
}
예제 #3
0
void Character::UpdateSkillQueue()
{
    Client *c = m_factory.entity_list.FindCharacter( itemID() );

    SkillRef currentTraining = GetSkillInTraining();
    if( currentTraining )
    {
        if( m_skillQueue.empty()
            || currentTraining->typeID() != m_skillQueue.front().typeID )
        {
            // either queue is empty or skill with different typeID is in training ...
            // stop training:
            _log( ITEM__ERROR, "%s (%u): Stopping training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() );

            /*
            uint64 timeEndTrain = currentTraining->expiryTime();
            if(timeEndTrain != 0)
            {
                double nextLevelSP = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 );
                double SPPerMinute = GetSPPerMin( currentTraining );
                double minRemaining = (double)(timeEndTrain - Win32TimeNow()) / (double)Win32Time_Minute;

                currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) );
            }

            currentTraining->Clear_expiryTime();
            */

            EvilNumber timeEndTrain = currentTraining->GetAttribute(AttrExpiryTime);
            if (timeEndTrain != 0) {
                EvilNumber nextLevelSP = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1 );
                EvilNumber SPPerMinute = GetSPPerMin( currentTraining );
                EvilNumber minRemaining = (timeEndTrain - EvilNumber(Win32TimeNow())) / (double)Win32Time_Minute;

                //currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) );
                EvilNumber skillPointsTrained = nextLevelSP - (minRemaining * SPPerMinute);
                currentTraining->SetAttribute(AttrSkillPoints, skillPointsTrained);
                sLog.Debug( "", "Skill %s (%u) trained %u skill points before termination from training queue", currentTraining->itemName().c_str(), currentTraining->itemID(), skillPointsTrained.get_float() );
            }

            currentTraining->SetAttribute(AttrExpiryTime, 0);

            currentTraining->MoveInto( *this, flagSkill, true );

            if( c != NULL )
            {
                OnSkillTrainingStopped osst;
                osst.itemID = currentTraining->itemID();
                osst.endOfTraining = 0;

                PyTuple* tmp = osst.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }

            // nothing currently in training
            currentTraining = SkillRef();
        }
    }

    EvilNumber nextStartTime = EvilTimeNow();
    
    while( !m_skillQueue.empty() )
    {
        if( !currentTraining )
        {
            // something should be trained, get desired skill
            uint32 skillTypeID = m_skillQueue.front().typeID;

            currentTraining = GetSkill( skillTypeID );
            if( !currentTraining )
            {
                _log( ITEM__ERROR, "%s (%u): Skill %u to train was not found.", itemName().c_str(), itemID(), skillTypeID );
                break;
            }

            sLog.Debug( "Character::UpdateSkillQueue()", "%s (%u): Starting training of skill %s (%u)",  m_itemName.c_str(), m_itemID, currentTraining->itemName().c_str(), currentTraining->itemID() );

            EvilNumber SPPerMinute = GetSPPerMin( currentTraining );
            EvilNumber NextLevel = currentTraining->GetAttribute(AttrSkillLevel) + 1;
            EvilNumber SPToNextLevel = currentTraining->GetSPForLevel( NextLevel ) - currentTraining->GetAttribute(AttrSkillPoints);
            sLog.Debug( "    ", "Training skill at %f SP/min", SPPerMinute.get_float() );
            sLog.Debug( "    ", "%f SP to next Level of %d", SPToNextLevel.get_float(), NextLevel.get_int() );

            SPPerMinute.to_float();
            SPToNextLevel.to_float();
            nextStartTime.to_float();
            EvilNumber timeTraining = nextStartTime + EvilTime_Minute * SPToNextLevel / SPPerMinute;

            currentTraining->MoveInto( *this, flagSkillInTraining );
            double dbl_timeTraining = timeTraining.get_float() + (double)(Win32Time_Second * 10);
            currentTraining->SetAttribute(AttrExpiryTime, dbl_timeTraining);    // Set server-side
                                                                                // skill expiry + 10 sec

            sLog.Debug( "    ", "Calculated time to complete training = %s", Win32TimeToString((uint64)dbl_timeTraining).c_str() );

            if( c != NULL )
            {
                OnSkillStartTraining osst;
                osst.itemID = currentTraining->itemID();
                osst.endOfTraining = timeTraining.get_float();

                PyTuple* tmp = osst.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }
        }

        if( currentTraining->GetAttribute(AttrExpiryTime) <= EvilTimeNow() ) {
            // training has been finished:
            sLog.Debug( "Character::UpdateSkillQueue()", "%s (%u): Finishing training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() );

            currentTraining->SetAttribute(AttrSkillLevel, currentTraining->GetAttribute(AttrSkillLevel) + 1 );
            currentTraining->SetAttribute(AttrSkillPoints, currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) ), true);

            nextStartTime = currentTraining->GetAttribute(AttrExpiryTime);
            currentTraining->SetAttribute(AttrExpiryTime, 0);

            currentTraining->MoveInto( *this, flagSkill, true );

            if( c != NULL )
            {
                OnSkillTrained ost;
                ost.itemID = currentTraining->itemID();

                PyTuple* tmp = ost.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }

            // erase first element in skill queue
            m_skillQueue.erase( m_skillQueue.begin() );

            // nothing currently in training
            currentTraining = SkillRef();
        }
        // else the skill is in training ...
        else
            break;
    }

    // Re-Calculate total SP trained and store in internal variable:
    _CalculateTotalSPTrained();

    // Save character and skill data:
    SaveCharacter();
    SaveSkillQueue();
}
예제 #4
0
void Character::SetDescription(const char *newDescription) {
    m_description = newDescription;

    SaveCharacter();
}
예제 #5
0
void Character::UpdateSkillQueue()
{
    Client *c = m_factory.entity_list.FindCharacter( itemID() );

    SkillRef currentTraining = GetSkillInTraining();
    if( currentTraining )
    {
        if( m_skillQueue.empty()
            || currentTraining->typeID() != m_skillQueue.front().typeID )
        {
            // either queue is empty or skill with different typeID is in training ...
            // stop training:
            _log( ITEM__ERROR, "%s (%u): Stopping training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() );

            /*
            uint64 timeEndTrain = currentTraining->expiryTime();
            if(timeEndTrain != 0)
            {
                double nextLevelSP = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 );
                double SPPerMinute = GetSPPerMin( currentTraining );
                double minRemaining = (double)(timeEndTrain - Win32TimeNow()) / (double)Win32Time_Minute;

                currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) );
            }

            currentTraining->Clear_expiryTime();
            */

            EvilNumber timeEndTrain = currentTraining->GetAttribute(AttrExpiryTime);
            if (timeEndTrain != 0) {
                EvilNumber nextLevelSP = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1 );
                EvilNumber SPPerMinute = GetSPPerMin( currentTraining );
                EvilNumber minRemaining = (timeEndTrain - EvilNumber(Win32TimeNow())) / (double)Win32Time_Minute;

                //currentTraining->Set_skillPoints( nextLevelSP - (minRemaining * SPPerMinute) );
                currentTraining->SetAttribute(AttrSkillPoints, nextLevelSP - (minRemaining * SPPerMinute));
            }

            currentTraining->SetAttribute(AttrExpiryTime, 0);

            currentTraining->MoveInto( *this, flagSkill, true );

            if( c != NULL )
            {
                OnSkillTrainingStopped osst;
                osst.itemID = currentTraining->itemID();
                osst.endOfTraining = 0;

                PyTuple* tmp = osst.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }

            // nothing currently in training
            currentTraining = SkillRef();
        }
    }

    EvilNumber nextStartTime = EvilTimeNow();
    
    while( !m_skillQueue.empty() )
    {
        if( !currentTraining )
        {
            // something should be trained, get desired skill
            uint32 skillTypeID = m_skillQueue.front().typeID;

            currentTraining = GetSkill( skillTypeID );
            if( !currentTraining )
            {
                _log( ITEM__ERROR, "%s (%u): Skill %u to train was not found.", itemName().c_str(), itemID(), skillTypeID );
                break;
            }

            _log( ITEM__TRACE, "%s (%u): Starting training of skill %s (%u).", m_itemName.c_str(), m_itemID, currentTraining->itemName().c_str(), currentTraining->itemID() );

            EvilNumber SPPerMinute = GetSPPerMin( currentTraining );
            //  double SPToNextLevel = currentTraining->GetSPForLevel( currentTraining->skillLevel() + 1 ) - currentTraining->skillPoints();
            EvilNumber SPToNextLevel = currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) + 1) - currentTraining->GetAttribute(AttrSkillPoints);

            //uint64 timeTraining = nextStartTime + Win32Time_Minute * SPToNextLevel / SPPerMinute;
            EvilNumber timeTraining = nextStartTime + EvilTime_Minute * SPToNextLevel / SPPerMinute;

            currentTraining->MoveInto( *this, flagSkillInTraining );
            //currentTraining->Set_expiryTime( timeTraining );
            currentTraining->SetAttribute(AttrExpiryTime, timeTraining);

            if( c != NULL )
            {
                OnSkillStartTraining osst;
                osst.itemID = currentTraining->itemID();
                osst.endOfTraining = timeTraining.get_int();

                PyTuple* tmp = osst.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }
        }

        //if( currentTraining->expiryTime() <= Win32TimeNow() )
        if( currentTraining->GetAttribute(AttrExpiryTime) <= EvilTimeNow() ) {
            // training has been finished:
            _log( ITEM__ERROR, "%s (%u): Finishing training of skill %s (%u).", itemName().c_str(), itemID(), currentTraining->itemName().c_str(), currentTraining->itemID() );

            //currentTraining->Set_skillLevel( currentTraining->skillLevel() + 1 );
            //currentTraining->Set_skillPoints( currentTraining->GetSPForLevel( currentTraining->skillLevel() ) );

            //nextStartTime = currentTraining->expiryTime();
            //currentTraining->Clear_expiryTime();

            currentTraining->SetAttribute(AttrSkillLevel, currentTraining->GetAttribute(AttrSkillLevel) + 1 );
            currentTraining->SetAttribute(AttrSkillPoints,  currentTraining->GetSPForLevel( currentTraining->GetAttribute(AttrSkillLevel) ) );

            nextStartTime = currentTraining->GetAttribute(AttrExpiryTime);
            currentTraining->SetAttribute(AttrExpiryTime, 0);

            currentTraining->MoveInto( *this, flagSkill, true );

            if( c != NULL )
            {
                OnSkillTrained ost;
                ost.itemID = currentTraining->itemID();

                PyTuple* tmp = ost.Encode();
                c->QueueDestinyEvent( &tmp );
                PySafeDecRef( tmp );

                c->UpdateSkillTraining();
            }

            // erase first element in skill queue
            m_skillQueue.erase( m_skillQueue.begin() );

            // nothing currently in training
            currentTraining = SkillRef();
        }
        // else the skill is in training ...
        else
            break;
    }

    // Re-Calculate total SP trained and store in internal variable:
    _CalculateTotalSPTrained();

    // Save character and skill data:
    SaveCharacter();
    SaveSkillQueue();
}
예제 #6
0
파일: v_items.c 프로젝트: mylemans/vrxcl
void PurchaseRandomRune(edict_t *ent, int runetype)
{
	int	cost;
	edict_t *rune;
	item_t *slot;
	char buf[64];

	cost = RUNE_COST_BASE + RUNE_COST_ADDON * ent->myskills.level;
	if (ent->myskills.credits < cost)
	{
		safe_cprintf(ent, PRINT_HIGH, "You need %d credits to purchase a rune.\n", cost);
		return;
	}

	slot = V_FindFreeItemSlot(ent);
	if (!slot)
	{
		safe_cprintf(ent, PRINT_HIGH, "Not enough inventory space!\n");
		return;
	}

	// rune pick-up delay
	if (ent->client->rune_delay > level.time)
		return;

	rune = G_Spawn();				// create a rune
	V_ItemClear(&rune->vrxitem);	// initialize the rune

	ent->myskills.credits -= cost;
	
	if (runetype)
	{
		spawnNorm(rune, ent->myskills.level, runetype);
	}
	else if (random() > 0.5)
	{
		spawnNorm(rune, ent->myskills.level, ITEM_WEAPON);
	}
	else
	{
		spawnNorm(rune, ent->myskills.level, ITEM_ABILITY);
	}
    
	if (Pickup_Rune(rune, ent) == false)
	{
		G_FreeEdict(rune);
		//gi.dprintf("WARNING: PurchaseRandomRune() was unable to spawn a rune\n");
		return;
	}
	G_FreeEdict(rune);

	//Find out what the player bought
	strcpy(buf, GetRuneValString(slot));
	switch(slot->itemtype)
	{
	case ITEM_WEAPON:	strcat(buf, va(" weapon rune (%d mods)", slot->numMods));	break;
	case ITEM_ABILITY:	strcat(buf, va(" ability rune (%d mods)", slot->numMods));	break;
	case ITEM_COMBO:	strcat(buf, va(" combo rune (%d mods)", slot->numMods));	break;
	}

	//send the message to the player
	safe_cprintf(ent, PRINT_HIGH, "You bought a %s.\n", buf);
	safe_cprintf(ent, PRINT_HIGH, "You now have %d credits left. \n", ent->myskills.credits);
	gi.sound(ent, CHAN_ITEM, gi.soundindex("misc/gold.wav"), 1, ATTN_NORM, 0);

	//Save the player
	if (savemethod->value == 1)
		SaveCharacter(ent);
	else if (savemethod->value == 0)
	{
		char path[MAX_QPATH];
		memset(path, 0, MAX_QPATH);
		VRXGetPath(path, ent);
		VSF_SaveRunes(ent, path);
	}else if (savemethod->value == 3)
	{
		VSFU_SaveRunes(ent);
	}

	//write to the log
	gi.dprintf("INFO: %s purchased a level %d rune (%s).\n", 
		ent->client->pers.netname, slot->itemLevel, slot->id);
	WriteToLogfile(ent, va("Purchased a level %d rune (%s) for %d credits. Player has %d credits left.\n",
		slot->itemLevel, slot->id, cost, ent->myskills.credits));
}