Пример #1
0
void ObjectController::_handleDismissGroupMember(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // make sure its a fully grouped player
    if(player->getGroupId() == 0)
    {
        return;
    }

    // lets get the target player
    message->setIndex(32);
    PlayerObject* targetPlayer = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(message->getUint64()));


    // if  target is valid
    if(targetPlayer == NULL || targetPlayer->getGroupId() != player->getGroupId())
    {
        gMessageLib->sendSystemMessage(player,L"Invalid Target.");
        return;
    }

    // we advise the chat server about it
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupDismissGroupMember);
    gMessageFactory->addUint32(targetPlayer->getAccountId());
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #2
0
bool WorldManager::_handleDisconnectUpdate(uint64 callTime,void* ref)
{
    PlayerList::iterator it = mPlayersToRemove.begin();

    while(it != mPlayersToRemove.end())
    {
        PlayerObject* playerObject = (*it);

        // we timed out, so save + remove it
        if(--*(playerObject->getDisconnectTime()) <= 0 && playerObject->isLinkDead())
        {
            // reset link dead state
            playerObject->togglePlayerFlagOff(PlayerFlag_LinkDead);
            playerObject->setConnectionState(PlayerConnState_Destroying);

			//remove the player out of his group - if any
			GroupObject* group = gGroupManager->getGroupObject(playerObject->getGroupId());
			if(group)
			{
				group->removePlayer(playerObject->getId());
			}

            //asynch save
            savePlayer(playerObject->getAccountId(),true,WMLogOut_LogOut);

            it = mPlayersToRemove.erase(it);
        }
        else
            ++it;

    }

    return(true);
}
Пример #3
0
void ObjectController::_handleTeach(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
	
	// check if our attribute targetplayer exists
	// check if our target is a player
	// parse the string if a known skill was selected
	// check what skills we can teach
	// check which of these skills the target might learn
	
	PlayerObject*	teacherObject	= dynamic_cast<PlayerObject*>(mObject);
	PlayerObject*	pupilObject	= dynamic_cast<PlayerObject*> (teacherObject->getTarget());

	// check if we have a target
	if(!pupilObject	)
	{
		gMessageLib->sendSystemMessage(teacherObject,L"","teaching","no_target");
		return;
	}

	if(pupilObject == teacherObject)
	{
		// target self:(
		gMessageLib->sendSystemMessage(teacherObject,L"","teaching","no_teach_self");
		return;
	}

	if((teacherObject->getGroupId() == 0)||(teacherObject->getGroupId() != pupilObject	->getGroupId()))
	{
		gMessageLib->sendSystemMessage(teacherObject,L"","teaching","not_in_same_group","","",L"",0,"","",L"",pupilObject->getId());
		return;
	}


	//check if our pupil already gets taught
	if (!pupilObject->getTrade()->getTeacher())
	{
		pupilObject->getTrade()->setTeacher(teacherObject);
		gSkillManager->teach(pupilObject,teacherObject,"");
	}
	else
	{
		gMessageLib->sendSystemMessage(teacherObject,L"","teaching","student_has_offer_to_learn","","",L"",0,"","",L"",pupilObject->getId());
	}

}
Пример #4
0
void ObjectController::_handleGroupChat(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    string msgText;

    msgText.setType(BSTRType_Unicode16);
    msgText.setLength(512);

    //Honey bunnies!
    //this is like all handled by the Objectcontroller???
    //we just have to look at the Message here !!!!!!!!

    //gLogger->hexDump always shows the complete Message!!!!! the Objectcontroller however sets the Index to the first data
    //byte AFTER the Objectcontroller header has been dealt with !

    /*
    data32 = message->getUint32();	// object controller opcode
    data32 = message->getUint32();	// Unknown
    data32 = message->getUint32();	// command enqueue
    playerId = message->getUint64();// player id
    data32 = message->getUint32();	// Unknown
    uint32 requestId = message->getUint32();	// RequestID
    // data32 = message->getUint32();	// Unknown RequestID?????
    data32 = message->getUint32();	// command crc (crc of "groupchat")
    data64 = message->getUint64();	// empty id field
    */
    message->getStringUnicode16(msgText);	// unicode string

    // make sure its a fully grouped player
    if (!player)
    {
        gLogger->logMsg("ObjectController::_handleGroupChat NO PLAYER\n");
    }

    if(!player->getGroupId())
    {

        gLogger->logMsg("ObjectController::_handleGroupChat NO GROUP");
    }

    // let the chatserver handle this.
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupSay);
    gMessageFactory->addUint32(0);
    gMessageFactory->addString(msgText);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
    //this should be fastpath as not being Mission critical and we want to prevent the communication protocol overhead with Acks and resends

    // Convert since we are going to print it.
    // msgText.convert(BSTRType_ANSI);
}
Пример #5
0
void ObjectController::_handleLeaveGroup(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    if(player->getGroupId() == 0)
    {
        return;
    }

    // we advise the chat server about it
    gMessageLib->sendIsmGroupLeave(player);
}
Пример #6
0
void ObjectController::_handleDisband(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    if(player->getGroupId() == 0)
    {
        return;
    }

    // we advise the chat server about the disband
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupDisband);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
void WorldManager::savePlayerSync(uint32 accId,bool remove)
{
    PlayerObject* playerObject = getPlayerByAccId(accId);
    Ham* ham = playerObject->getHam();

    mDatabase->destroyResult(mDatabase->executeSynchSql("UPDATE characters SET parent_id=%"PRIu64",oX=%f,oY=%f,oZ=%f,oW=%f,x=%f,y=%f,z=%f,planet_id=%u WHERE id=%"PRIu64"",playerObject->getParentId()
                             ,playerObject->mDirection.x,playerObject->mDirection.y,playerObject->mDirection.z,playerObject->mDirection.w
                             ,playerObject->mPosition.x,playerObject->mPosition.y,playerObject->mPosition.z
                             ,mZoneId,playerObject->getId()));
   

    mDatabase->destroyResult(mDatabase->executeSynchSql("UPDATE character_attributes SET health_current=%u,action_current=%u,mind_current=%u"
                             ",health_wounds=%u,strength_wounds=%u,constitution_wounds=%u,action_wounds=%u,quickness_wounds=%u"
                             ",stamina_wounds=%u,mind_wounds=%u,focus_wounds=%u,willpower_wounds=%u,battlefatigue=%u,posture=%u,moodId=%u,title=\'%s\'"
                             ",character_flags=%u,states=%"PRIu64",language=%u, group_id=%"PRIu64" WHERE character_id=%"PRIu64"",
                             ham->mHealth.getCurrentHitPoints() - ham->mHealth.getModifier(), //Llloydyboy Added the -Modifier so that when buffs are reinitialised, it doesn't screw up HAM
                             ham->mAction.getCurrentHitPoints() - ham->mAction.getModifier(), //Llloydyboy Added the -Modifier so that when buffs are reinitialised, it doesn't screw up HAM
                             ham->mMind.getCurrentHitPoints() - ham->mMind.getModifier(),	 //Llloydyboy Added the -Modifier so that when buffs are reinitialised, it doesn't screw up HAM
                             ham->mHealth.getWounds(),
                             ham->mStrength.getWounds(),
                             ham->mConstitution.getWounds(),
                             ham->mAction.getWounds(),
                             ham->mQuickness.getWounds(),
                             ham->mStamina.getWounds(),
                             ham->mMind.getWounds(),
                             ham->mFocus.getWounds(),
                             ham->mWillpower.getWounds(),
                             ham->getBattleFatigue(),
                             playerObject->states.getPosture(),
                             playerObject->getMoodId(),
                             playerObject->getTitle().getAnsi(),
                             playerObject->getPlayerFlags(),
							 playerObject->states.getAction(),
                             playerObject->getLanguage(),
                             playerObject->getGroupId(),
                             playerObject->getId()));

    gBuffManager->SaveBuffs(playerObject, GetCurrentGlobalTick());
    if(remove)
        destroyObject(playerObject);
}
Пример #8
0
void ObjectController::_handleGroupLootMode(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    // disabled for now
    //return;

    gLogger->logMsg("_handleGroupLootMode");
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // make sure its a fully grouped player
    if(player->getGroupId() == 0)
    {
        return;
    }

    // we advise the chat server about it
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupLootModeRequest);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #9
0
uint8 CombatManager::_executeAttack(CreatureObject* attacker,CreatureObject* defender,ObjectControllerCmdProperties *cmdProperties,Weapon* weapon)
{
	uint8	randomHitPool			= 100;
	//uint8	randomPoolHitChance		= 100;
	uint8	stateApplied			= 0;
	int32	multipliedDamage		= 0;
	BString	combatSpam				= "melee";

	// first see if we actually hit our target
	uint8 attackResult = _hitCheck(attacker,defender,cmdProperties,weapon);

	// only proceed, if so
	if(!attackResult)
	{
		// TODO: retrieve from weapon
		int32 baseMinDamage	= 50;
		int32 baseMaxDamage	= 100;

		// NOTE: Some weapon data just for tesing and to give the npc a fair chance...

		if (weapon->hasAttribute("cat_wpn_damage.wpn_damage_min"))
		{
			baseMinDamage = weapon->getAttribute<int32>("cat_wpn_damage.wpn_damage_min");
		}
		if (weapon->hasAttribute("cat_wpn_damage.wpn_damage_max"))
		{
			baseMaxDamage = weapon->getAttribute<int32>("cat_wpn_damage.wpn_damage_max");
		}


		//Sanity checks of db data
		if (baseMinDamage < 1)
			baseMinDamage = 1;

		if (baseMaxDamage < 1)
			baseMaxDamage = 1;

		if(baseMaxDamage <= baseMinDamage)
		{
			baseMaxDamage = baseMinDamage +1;
		}

		int32 baseDamage	= -((gRandom->getRand()%(baseMaxDamage - baseMinDamage)) + baseMinDamage);

		// apply damage multiplier
		if(cmdProperties->mDamageMultiplier)
		{
			multipliedDamage = static_cast<uint32>(static_cast<float>(baseDamage) * cmdProperties->mDamageMultiplier);
		}
		else
		{
			multipliedDamage = baseDamage;
		}

		// mitigation
		multipliedDamage = _mitigateDamage(attacker,defender,cmdProperties,multipliedDamage,weapon);

		// state effects
		stateApplied = _tryStateEffects(attacker,defender,cmdProperties,weapon);


		// Here is the deal. When a player makes damage to a npc, we have to register the player, its group, damage done and what (kind of) weapon used.
		NPCObject* npc = dynamic_cast<NPCObject*>(defender);
		if (!defender->isDead() && npc)
		{
			PlayerObject* player = dynamic_cast<PlayerObject*>(attacker);
			if (player)
			{
                npc->updateDamage(player->getId(), player->getGroupId(), weapon->getGroup(), -multipliedDamage, player->GetPosture(), glm::distance(defender->mPosition, player->mPosition));
			}
		}

		// ham damage
		// if no target pool set, pick a random one
		if(!cmdProperties->mHealthHitChance && !cmdProperties->mActionHitChance && !cmdProperties->mMindHitChance)
		{
			switch(gRandom->getRand()%3)
			{
				case 0: randomHitPool = HamBar_Health;	break;
				case 1: randomHitPool = HamBar_Action;	break;
				case 2: randomHitPool = HamBar_Mind;	break;

				default: randomHitPool = 0;				break;
			}
		}

		auto ham = gWorldManager->getKernel()->GetServiceManager()->GetService<swganh::ham::HamService>("HamService");

		//this is pure idiocy in my eyes. Why for gods sake should an object be a creature ?
		// is there precedent through SOE???????????
		if (defender->getCreoGroup() != CreoGroup_AttackableObject)
		{
			// random pool attack
			if(randomHitPool != 100)
			{
				ham->UpdateCurrentHitpoints(defender,randomHitPool,multipliedDamage);
				//defender->getHam()->updatePropertyValue(randomHitPool,HamProperty_CurrentHitpoints,multipliedDamage,true);
			}
			// direct pool attack
			else
			{
				// health hit
				if(cmdProperties->mHealthHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Health,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Health,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
				// action hit
				else if(cmdProperties->mActionHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Action,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Action,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
				// mind hit
				else if(cmdProperties->mMindHitChance)
				{
					ham->UpdateCurrentHitpoints(defender,HamBar_Mind,multipliedDamage);
					//defender->getHam()->updatePropertyValue(HamBar_Mind,HamProperty_CurrentHitpoints,multipliedDamage,true);
				}
			}
		}
		else
		{
			ham->UpdateCurrentHitpoints(defender,HamBar_Health,multipliedDamage);
			//defender->getHam()->updateSingleHam(multipliedDamage, true);
		}
		if (defender->isIncapacitated())
		{
			PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker);
			if (playerAttacker && playerAttacker->isConnected())
			{
                gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "prose_target_incap", 0, defender->getId(), 0), playerAttacker);
            }
        }
        if (defender->isDead())
        {
            PlayerObject* playerAttacker = dynamic_cast<PlayerObject*>(attacker);
            if (playerAttacker && playerAttacker->isConnected())
            {
                gMessageLib->SendSystemMessage(::common::OutOfBand("base_player", "killer_target_dead"), playerAttacker, true);
            }
        }
    }


    // fly text and animations
    // default attack(s)
    if(cmdProperties->mCmdCrc == 0xa8fef90a)
    {
        uint32 animCrc = getDefaultAttackAnimation(weapon->getGroup());

        switch(attackResult)
        {
            // hit
        case 0:
        case 2:
        case 3:
        case 4:
        {
            gMessageLib->sendCombatAction(attacker,defender,animCrc,0,0,1);
        }
        break;

        // miss
        case 1:
        {
            gMessageLib->sendCombatAction(attacker,defender,animCrc);
        }
        break;
        }
    }
    // special attack
    else
    {
        switch(attackResult)
        {
            // hit
        case 0:
        case 2:
        case 3:
        case 4:
        {
            gMessageLib->sendCombatAction(attacker,defender,cmdProperties->mAnimationCrc,cmdProperties->mTrail1,cmdProperties->mTrail2,1);
        }
        break;

        //miss
        case 1:
        {
            gMessageLib->sendCombatAction(attacker,defender,cmdProperties->mAnimationCrc,cmdProperties->mTrail1,cmdProperties->mTrail2);
        }
        break;
        }
    }

    switch(attackResult)
    {
    case 0:
    {
        // Defender got hit.
    }
    break;

    case 1:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","miss",255,255,255);
    }
    break;

    case 2:
        // We cant block yet, can we?
    {
        gMessageLib->sendFlyText(defender,"combat_effects","block",0,255,0);
        gMessageLib->sendCombatAction(defender,attacker,0xe430ff04);
    }
    break;

    case 3:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","dodge",0,255,0);
        gMessageLib->sendCombatAction(defender,attacker,0xe430ff04);	// Dodge
    }
    break;

    case 4:
    {
        gMessageLib->sendFlyText(defender,"combat_effects","counterattack",0,255,0);	// I can's see this effect working?
    }
    break;
    }

    // send combat spam
    // default attack
    if(cmdProperties->mCmdCrc == 0xa8fef90a)
    {
        combatSpam = getDefaultSpam(weapon->getGroup());
    }
    // special attack
    else
    {
        if(cmdProperties->mCbtSpam.getLength())
        {
            combatSpam = cmdProperties->mCbtSpam.getAnsi();
        }
    }

    switch(attackResult)
    {
    case 0:
        combatSpam << "_hit";
        break;
    case 1:
        combatSpam << "_miss";
        break;
    case 2:
        combatSpam << "_block";
        break;
    case 3:
        combatSpam << "_evade";
        break;
    case 4:
        combatSpam << "_counter";
        break;

    default:
        break;
    }
    gMessageLib->sendCombatSpam(attacker,defender,-multipliedDamage,"cbt_spam",combatSpam);


    return(0);
}