diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/destroy_item.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/destroy_item.html
index 366a02977..9eaf62bfd 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/destroy_item.html
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/destroy_item.html
@@ -253,6 +253,14 @@ NPC tag name. Used to write in the sys info who destroyed the items
item description. See item_guidelines
for the formatting requirements.
+
+
+guild (Boolean) : This parameter is only for guild missions. If it is set to true the action is done for the guild (not for the players that completed the mission).
+
+
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/do_mission.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/do_mission.html
index 0c516a984..4a480e1b8 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/do_mission.html
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/do_mission.html
@@ -160,7 +160,8 @@ mso-ansi-language:EN-US'>
mission_names : Mission names with the specific mission
-objective texts.
+objective texts. The name can be followed by a space and a number representing the number of
+times this mission needs to be done (useful for guild missions to specify the number of members needed to complete the mission)
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_fame.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_fame.html
index 391814c2b..1921ec67b 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_fame.html
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_fame.html
@@ -166,6 +166,13 @@ reduce fame, use a negative figure.
+guild (Boolean) : This parameter is only for guild missions. If it is set to true the action is done for the guild (not for the players that completed the mission).
+
+
+
Default
variables :
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_item.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_item.html
index 96b454cd2..aa4ba81f3 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_item.html
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_item.html
@@ -178,11 +178,20 @@ lang=EN-US style='mso-ansi-language:EN-US'>: Array containing given item
description. See item_guidelines for the
formatting requirements.
+
+
+guild (Boolean) : This parameter is only for guild missions. If it is set to true the action is done for the guild (not for the players that completed the mission).
+
+
+
Default
variables:
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_money.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_money.html
index 88030c8d1..7de97c411 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_money.html
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/recv_money.html
@@ -169,6 +169,14 @@ lang=EN-US style='mso-ansi-language:EN-US'>amount: Amount of money to add to the
player’s funds. To withdraw money, use a negative figure.
+
+
+guild (Boolean) : This parameter is only for guild missions. If it is set to true the action is done for the guild (not for the players that completed the mission).
+
+
Default
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/spawn_mission.html b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/spawn_mission.html
new file mode 100644
index 000000000..53b4f4cc9
--- /dev/null
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/class_doc/spawn_mission.html
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
spawn_mission
+
+
+
+
Properties:
+
+
+
+
name : Action name, only used by the
+mission designer.
+
+
+
+
giver_name : The NPC that gives the mission.
+
+
+
+
guild (Boolean) : This parameter is only for guild missions. .
+
+
+
+
+
mission_name : The name of the mission to spawn.
+
+
+
+
+
+
+
+
+
diff --git a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml
index 1e4f9d723..5426361fa 100644
--- a/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml
+++ b/code/ryzom/common/data_leveldesign/leveldesign/world_editor_files/world_editor_classes.xml
@@ -688,8 +688,6 @@
-
-
@@ -709,6 +707,7 @@
+
@@ -838,14 +837,6 @@
-
-
-
-
-
-
-
-
@@ -1108,8 +1099,6 @@
-
-
@@ -1122,10 +1111,6 @@
-
-
-
-
@@ -1135,45 +1120,28 @@
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
@@ -1182,27 +1150,18 @@
-
-
-
-
-
-
-
-
-
@@ -1212,9 +1171,6 @@
-
-
-
@@ -1223,9 +1179,6 @@
-
-
-
@@ -1233,9 +1186,6 @@
-
-
-
@@ -1243,35 +1193,23 @@
-
-
-
-
-
-
-
-
-
-
-
-
@@ -1304,18 +1242,12 @@
-
-
-
-
-
-
diff --git a/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive b/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive
new file mode 100644
index 000000000..568d89398
--- /dev/null
+++ b/code/ryzom/common/data_leveldesign/primitives/newbieland/guild_missions.primitive
@@ -0,0 +1,448 @@
+
+
+
+
+
+
+ class
+ missions_editor
+
+
+ name
+ guild_missions
+
+
+
+ audience
+ guild
+
+
+ auto_remove_from_journal
+ false
+
+
+ automatic
+ false
+
+
+ class
+ mission_tree
+
+
+ fail_if_inventory_is_full
+ false
+
+
+ giver_primitive
+ urban_newbieland.primitive
+
+
+ mission_category
+ Killing
+
+
+ mission_description
+ GUILD_MISSION_DESC
+
+
+ mission_giver
+ $givervar@fullname$
+
+
+ mission_title
+ GUILD_MISSION_TITLE
+
+
+ mono_instance
+ false
+
+
+ name
+ GUILD_MISSION
+
+
+ need_validation
+ false
+
+
+ non_abandonnable
+ false
+
+
+ not_in_journal
+ false
+
+
+ not_proposed
+ false
+
+
+ replayable
+ true
+
+
+ run_only_once
+ false
+
+
+
+ class
+ variables
+
+
+ name
+ variables
+
+
+
+ class
+ var_npc
+
+
+ npc_function
+ fct_ranger_leader
+
+
+ npc_name
+ chiang_the_strong
+
+
+ var_name
+ givervar
+
+
+
+
+
+ class
+ pre_requisite
+
+
+ name
+ pre_requisite
+
+
+ require_guild_grade
+ Leader
+
+
+ require_guild_membership
+ true
+
+
+
+
+
+ class
+ alias
+
+
+ name
+ alias
+
+
+
+
+ class
+ step
+
+
+ name
+ step
+
+
+
+ class
+ actions
+
+
+ name
+ pre_actions
+
+
+
+ class
+ spawn_mission
+
+
+ giver_name
+ chiang_the_strong
+
+
+ guild
+ true
+
+
+ mission_name
+ SOLO_GUILD_MISSION
+
+
+
+
+
+ class
+ mission_objectives
+
+
+ name
+ objectives
+
+
+
+ class
+ do_mission
+
+
+ mission_names
+ SOLO_GUILD_MISSION 2
+
+
+ overload_objective
+ MIS_DO_MISSION
+
+
+
+
+ class
+ kill
+
+
+ fauna/quantity
+ chdfa1 2
+
+
+ name
+ kill chdfa1 2
+
+
+
+
+
+ class
+ actions
+
+
+ name
+ post_actions
+
+
+
+ amount
+ 100
+
+
+ class
+ recv_money
+
+
+ guild
+ true
+
+
+ name
+ recv_money 100 guild
+
+
+
+
+ amount
+ 50
+
+
+ class
+ recv_money
+
+
+
+
+
+
+
+ audience
+ solo
+
+
+ auto_remove_from_journal
+ false
+
+
+ automatic
+ false
+
+
+ class
+ mission_tree
+
+
+ fail_if_inventory_is_full
+ false
+
+
+ giver_primitive
+ urban_newbieland.primitive
+
+
+ mission_category
+ Killing
+
+
+ mission_description
+ SOLO_GUILD_MISSION_DESC
+
+
+ mission_giver
+ $givervar@fullname$
+
+
+ mission_title
+ SOLO_GUILD_MISSION_TITLE
+
+
+ mono_instance
+ false
+
+
+ name
+ SOLO_GUILD_MISSION
+
+
+ need_validation
+ false
+
+
+ non_abandonnable
+ false
+
+
+ not_in_journal
+ false
+
+
+ not_proposed
+ true
+
+
+ replayable
+ true
+
+
+ run_only_once
+ false
+
+
+
+ class
+ variables
+
+
+ name
+ variables
+
+
+
+ class
+ var_npc
+
+
+ npc_function
+ fct_ranger_leader
+
+
+ npc_name
+ chiang_the_strong
+
+
+ var_name
+ givervar
+
+
+
+
+
+ class
+ pre_requisite
+
+
+ name
+ pre_requisite
+
+
+
+
+
+ class
+ alias
+
+
+ name
+ alias
+
+
+
+
+ class
+ step
+
+
+ name
+ step
+
+
+
+ class
+ actions
+
+
+ name
+ pre_actions
+
+
+
+
+ class
+ mission_objectives
+
+
+ name
+ objectives
+
+
+
+ class
+ kill
+
+
+ fauna/quantity
+ chdfa1 1
+
+
+ name
+ kill chdfa1 1
+
+
+
+
+
+ class
+ actions
+
+
+ name
+ post_actions
+
+
+
+ amount
+ 20
+
+
+ class
+ recv_money
+
+
+
+
+
+
+
+
diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp
index 56a2606dd..a93bdaeb1 100644
--- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp
+++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.cpp
@@ -34,6 +34,8 @@
#include "outpost_manager/outpost_manager.h"
#include "primitives_parser.h"
#include "modules/shard_unifier_client.h"
+#include "mission_manager/mission_manager.h"
+#include "phrase_manager/phrase_utilities_functions.h"
/// todo guild remove entity id translator
#include "nel/misc/eid_translator.h"
@@ -686,23 +688,193 @@ void CGuild::unregisterGuild()
//
//}
-
//----------------------------------------------------------------------------
-void CGuild::removeMission(CMissionGuild * mission, TMissionResult result)
+void CGuild::removeMission( uint idx, TMissionResult result)
{
- /// todo guild mission
+ if ( idx >= _Missions.size() )
+ return;
+
+ /// if the mission was finished, the result is success
+ if ( _Missions[idx]->getFinished() )
+ {
+ if ( _Missions[idx]->getMissionSuccess() )
+ result = mr_success;
+ else
+ result = mr_fail;
+ }
+
+ CMissionTemplate *tpl = CMissionManager::getInstance()->getTemplate(_Missions[idx]->getTemplateId());
+
+ updateMissionHistories( _Missions[idx]->getTemplateId(), result);
+
+ if ( tpl && !tpl->Tags.NoList )
+ {
+ _Missions[idx]->clearUsersJournalEntry();
+ }
+
+ CMissionManager::getInstance()->deInstanciateMission(_Missions[idx]);
+ delete _Missions[idx];
+ _Missions.erase(_Missions.begin() + idx) ;
}
//----------------------------------------------------------------------------
void CGuild::addSuccessfulMission(CMissionTemplate * templ)
{
- /// todo guild mission
+ TMissionHistory &mh = _MissionHistories[templ->Alias];
+ mh.Successfull = true;
}
//----------------------------------------------------------------------------
-bool CGuild::processMissionEvent( CMissionEvent & event, TAIAlias alias )
+void CGuild::clearSuccessfulMissions()
{
- /// todo guild mission
+ _MissionHistories.clear();
+}
+
+//----------------------------------------------------------------------------
+void CGuild::updateMissionHistories(TAIAlias missionAlias, uint32 result)
+{
+ TMissionHistory &mh = _MissionHistories[missionAlias];
+
+ switch(result)
+ {
+ case mr_success:
+ case mr_forced:
+ mh.Successfull = true;
+ // validate last try date
+ _MissionHistories[missionAlias].LastSuccessDate = CTickEventHandler::getGameCycle();
+ break;
+ }
+}
+
+//----------------------------------------------------------------------------
+void CGuild::sendDynamicMessageToMembers(const string &msgName, const TVectorParamCheck ¶ms, const set &excluded) const
+{
+ for ( std::map::const_iterator it = getMembersBegin();
+ it != getMembersEnd();++it )
+ {
+ CCharacter * user = PlayerManager.getChar( it->first );
+
+ if ( excluded.find(it->first) == excluded.end())
+ {
+ const uint32 stringId = STRING_MANAGER::sendStringToClient(TheDataset.getDataSetRow(it->first), msgName, params );
+ PHRASE_UTILITIES::sendDynamicSystemMessage(TheDataset.getDataSetRow(it->first), stringId);
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool CGuild::processMissionEvent( CMissionEvent & event, TAIAlias alias)
+{
+ std::list listEvents;
+ listEvents.push_back(&event);
+ return processGuildMissionEvent(listEvents, alias);
+}
+
+//----------------------------------------------------------------------------
+bool CGuild::processGuildMissionEvent(std::list< CMissionEvent *> & eventList, TAIAlias missionAlias)
+{
+ for (uint i = 0; i < _Missions.size(); i++ )
+ {
+ nlassert( _Missions[i] );
+ if ( missionAlias == CAIAliasTranslator::Invalid || _Missions[i]->getTemplateId() == missionAlias )
+ {
+ if ( processGuildMissionStepEvent( eventList, _Missions[i]->getTemplateId() ,0xFFFFFFFF) )
+ return true;
+ }
+ }
+ return false;
+}
+
+//----------------------------------------------------------------------------
+bool CGuild::processGuildMissionStepEvent(std::list< CMissionEvent*> & eventList, TAIAlias missionAlias, uint32 stepIndex)
+{
+ CMissionGuild * mission = getMissionByAlias( missionAlias );
+ if (!mission )
+ {
+ nlwarning("invalid missionAlias");
+ return false;
+ }
+ // I don't know if i should pass _EId to this function
+ CMissionEvent::TResult result = mission->processEvent(TheDataset.getDataSetRow(getHighestGradeOnlineUser()) /*TheDataset.getDataSetRow( _EId)*/ ,eventList,stepIndex );
+ if ( result == CMissionEvent::Nothing )
+ return false;
+ else if ( result == CMissionEvent::MissionFailed )
+ return true;
+
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() );
+ nlassert( templ );
+ if ( result == CMissionEvent::MissionEnds )
+ {
+ CMissionEventMissionDone * event = new CMissionEventMissionDone(templ->Alias);
+ eventList.push_back(event);
+
+ addSuccessfulMission(templ);
+
+ for ( std::map::iterator it = getMembersBegin();
+ it != getMembersEnd();++it )
+ {
+ CCharacter * user = PlayerManager.getChar( it->first );
+ if ( user )
+ {
+ if ( templ->Tags.NoList == false )
+ CCharacter::sendDynamicSystemMessage( user->getEntityRowId(),"EGS_MISSION_SUCCESS");
+ }
+ }
+
+ CMissionManager::getInstance()->missionDoneOnce(templ);
+ mission->stopChildren();
+
+ // only remove no list missions, other must be manually removed by user
+ if ( templ->Tags.NoList || mission->isChained() || templ->Tags.AutoRemove )
+ {
+ mission->updateEncyclopedia();
+ removeMission(mission, mr_success);
+ }
+ else
+ {
+ mission->setSuccessFlag();
+ mission->updateUsersJournalEntry();
+ }
+ return true;
+ }
+ else if ( result == CMissionEvent::StepEnds )
+ {
+ if ( templ->Tags.NoList == false )
+ {
+ for ( std::map::iterator it = getMembersBegin();
+ it != getMembersEnd();++it )
+ {
+ CCharacter * user = PlayerManager.getChar( it->first );
+ if ( user )
+ {
+ if ( templ->Tags.NoList == false )
+ CCharacter::sendDynamicSystemMessage( user->getEntityRowId(),"EGS_MISSION_STEP_SUCCESS");
+ }
+ }
+ }
+ }
+ mission->updateUsersJournalEntry();
+ return true;
+}
+
+//----------------------------------------------------------------------------
+CMissionGuild* CGuild::getMissionByAlias( TAIAlias missionAlias )
+{
+ const uint size = (uint)_Missions.size();
+ for ( uint i = 0; i < size; i++ )
+ {
+ if ( _Missions[i] && _Missions[i]->getTemplateId() == missionAlias )
+ return _Missions[i];
+ }
+ return NULL;
+}
+
+//----------------------------------------------------------------------------
+bool CGuild::isMissionSuccessfull(TAIAlias alias)
+{
+ std::map::iterator it(_MissionHistories.find(alias));
+ if (it != _MissionHistories.end())
+ return it->second.Successfull;
return false;
}
@@ -732,10 +904,12 @@ bool CGuild::canAccessToGuildInventory( CCharacter * user )
}
//----------------------------------------------------------------------------
-void CGuild::putItem( CGameItemPtr item )
+bool CGuild::putItem( CGameItemPtr item )
{
- if (_Inventory->insertItem(item, INVENTORIES::INSERT_IN_FIRST_FREE_SLOT, true) != CInventoryBase::ior_ok)
+ CInventoryBase::TInventoryOpResult res = _Inventory->insertItem(item, INVENTORIES::INSERT_IN_FIRST_FREE_SLOT, true);
+ if (res != CInventoryBase::ior_ok)
item.deleteItem();
+ return res == CInventoryBase::ior_ok;
}
//----------------------------------------------------------------------------
@@ -856,6 +1030,88 @@ void CGuild::takeItem( CCharacter * user, uint32 slot, uint32 quantity, uint16 s
}
}
+//----------------------------------------------------------------------------
+uint CGuild::selectItems(NLMISC::CSheetId itemSheetId, uint32 quality, std::vector *itemList)
+{
+ // For all items
+ uint quantitySelected= 0;
+ for (uint32 i = 0; i < _Inventory->getSlotCount(); i++)
+ {
+ CGameItemPtr item = _Inventory->getItem(i);
+ if (item == NULL)
+ continue;
+
+ // if match, append to the list
+ if (item->getSheetId()==itemSheetId && item->quality()>=quality)
+ {
+ quantitySelected+= item->getStackSize();
+ if(itemList)
+ {
+ CItemSlotId entry;
+ entry.Slot= i;
+ entry.Quality= item->quality();
+ itemList->push_back(entry);
+ }
+ }
+ }
+
+ return quantitySelected;
+}
+
+//----------------------------------------------------------------------------
+uint CGuild::destroyItems(const std::vector &itemSlotIns, uint32 maxQuantity)
+{
+ // none to destroy actually?
+ if(maxQuantity==0 || itemSlotIns.empty())
+ return 0;
+
+ // If has to destroy only some of them, must sort to take first the ones of lowest quality
+ const std::vector *itemSlots= NULL;
+ std::vector itemSlotSorted;
+ if(maxQuantity!=uint32(-1))
+ {
+ itemSlotSorted= itemSlotIns;
+ std::sort(itemSlotSorted.begin(), itemSlotSorted.end());
+ itemSlots= &itemSlotSorted;
+ }
+ else
+ {
+ // just point to the original one
+ itemSlots= &itemSlotIns;
+ }
+
+ // destroy items up to the maxquantity wanted
+ uint index= 0;
+ uint totalDestroyed= 0;
+ while(maxQuantity>0 && indexgetStackSize());
+
+ CGameItemPtr item = _Inventory->removeItem(itemSlot.Slot, quantityToDestroy);
+ item.deleteItem();
+
+ // decrease if not infinity
+ if(maxQuantity!=-1)
+ maxQuantity-= quantityToDestroy;
+
+ // increase count
+ totalDestroyed+= quantityToDestroy;
+ }
+
+ // next slot to destroy
+ index++;
+ }
+
+ return totalDestroyed;
+}
+
//----------------------------------------------------------------------------
void CGuild::takeMoney( CCharacter * user, uint64 money, uint16 session )
{
diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild.h
index e740540ca..671f7c17b 100644
--- a/code/ryzom/server/src/entities_game_service/guild_manager/guild.h
+++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild.h
@@ -27,10 +27,15 @@
#include "outpost_manager/outpost_guild_db_updater.h"
#include "guild_interface.h"
#include "database_guild.h"
+#include "mission_manager/mission_guild.h"
class CMissionGuild;
class CGuildMember;
+/* Storage class for mission history data.
+*/
+struct TMissionHistory;
+
/**
* A guild in ryzom
@@ -176,9 +181,36 @@ public:
///\name Mission management
//@{
- void removeMission(CMissionGuild * mission, TMissionResult result);
+ void removeMission(CMissionGuild * mission, TMissionResult result)
+ {
+ for (uint i = 0; i < _Missions.size(); i++)
+ {
+ if ( _Missions[i] == mission )
+ {
+ removeMission(i, result);
+ }
+ }
+ }
+ void removeMission( uint idx, TMissionResult result);
void addSuccessfulMission(CMissionTemplate * templ);
+ void clearSuccessfulMissions();
+ void updateMissionHistories(TAIAlias missionAlias, uint32 result);
bool processMissionEvent( CMissionEvent & event, TAIAlias alias = CAIAliasTranslator::Invalid);
+ bool processGuildMissionEvent(std::list< CMissionEvent * > & eventList, TAIAlias missionAlias );
+ bool processGuildMissionStepEvent(std::list< CMissionEvent* > & eventList, TAIAlias missionAlias, uint32 stepIndex);
+ CMissionGuild* getMissionByAlias( TAIAlias missionAlias );
+ bool isMissionSuccessfull(TAIAlias alias);
+ void sendDynamicMessageToMembers(const std::string &msgName, const TVectorParamCheck ¶ms, const std::set &excluded) const;
+ ///\return the mission
+ inline std::vector & getMissions()
+ {
+ return _Missions;
+ }
+ void addMission(CMissionGuild* guildMission)
+ {
+ _Missions.push_back(guildMission);
+ guildMission->updateUsersJournalEntry();
+ }
//@}
/// inventory management
@@ -203,7 +235,23 @@ public:
return _Inventory->getItem(slot);
}
/// add an item in the guild inventory (item can be deleted if not inserted : do not use it anymore in any case!)
- void putItem( CGameItemPtr item );
+ bool putItem( CGameItemPtr item );
+
+ class CItemSlotId
+ {
+ public:
+ uint32 Slot;
+ uint32 Quality;
+ bool operator<(const CItemSlotId &o) const
+ {
+ return Quality *itemList= NULL);
+ /// destroy a list of items (up to maxQuantity to destroy)
+ uint destroyItems(const std::vector &itemSlots, uint32 maxQuantity=-1);
/// return the inventory (const)
const NLMISC::CSmartPtr& getInventory() const { return _Inventory; }
@@ -351,6 +399,11 @@ private:
/// list of outposts challenged by guild
std::vector _ChallengedOutposts;
+ ///the missions took by the guild
+ std::vector _Missions;
+ /// Successful missions
+ std::map _MissionHistories;
+
NLMISC_COMMAND_FRIEND( guildDB );
};
#endif // RY_GUILD_H
diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.h
index 4447e356f..46dee0f96 100644
--- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.h
+++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_member_module.h
@@ -99,6 +99,12 @@ public:
/// user wanna pick a mission
CMissionGuild * pickMission( TAIAlias alias );
+ // Function to check if the member can pick a mission. By default only Officer and above can pick a guild mission
+ virtual bool canPickMission(TAIAlias alias)
+ {
+ return false;
+ }
+
/// set the version of last sent info of items in guild inventory
void setLastSentInfoVersion(uint32 slot, uint8 infoVersion)
{
diff --git a/code/ryzom/server/src/entities_game_service/guild_manager/guild_officer_module.h b/code/ryzom/server/src/entities_game_service/guild_manager/guild_officer_module.h
index 7d6f49096..e31885300 100644
--- a/code/ryzom/server/src/entities_game_service/guild_manager/guild_officer_module.h
+++ b/code/ryzom/server/src/entities_game_service/guild_manager/guild_officer_module.h
@@ -34,6 +34,14 @@ public:
:CGuildMemberModule(proxy,guildMember){}
virtual bool canAffectGrade(EGSPD::CGuildGrade::TGuildGrade grade)const;
virtual bool canInvite()const;
+
+ // Function to check if the member can pick a mission.
+ // By default only Officers and above can pick a guild mission.
+ // So we don't need to implement this function for the other grades
+ virtual bool canPickMission(TAIAlias alias)
+ {
+ return true;
+ }
};
;
diff --git a/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp b/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp
index f0205ed95..52fd214f9 100644
--- a/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_client_callbacks.cpp
@@ -26,6 +26,9 @@
#include "team_manager/team_manager.h"
#include "mission_manager/mission_team.h"
#include "mission_manager/mission_log.h"
+#include "guild_manager/guild_manager.h"
+#include "guild_manager/guild.h"
+#include "guild_manager/guild_member.h"
using namespace std;
@@ -222,50 +225,108 @@ void cbClientGroupAbandonMission( NLNET::CMessage& msgin, const std::string &ser
CCharacter * user = PlayerManager.getChar( userId );
user->setAfkState(false);
- CTeam * team = TeamManager.getRealTeam( user->getTeamId() );
- if ( !team )
- {
- MISLOG("user:%s cbClientGroupAbandonMission : Invalid team", userId.toString().c_str());
- return;
- }
- if ( team->getLeader() != userId )
- {
- CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), "REQ_LEADER_TO_ABANDON_MISSION" );
- return;
- }
- if ( index >= team->getMissions().size() )
+ // We check if it's a guild or team mission
+ if (index < MaxGroupMissionCount)
{
- MISLOG("user:%s cbClientGroupAbandonMission : Invalid group mission %u ( count %u )",
- userId.toString().c_str(), index, team->getMissions().size());
- return;
- }
-
+ // Team
- CMissionTeam* mission = team->getMissions()[index];
- nlassert(mission);
-
- if ( mission->getFinished() == false )
- {
- CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() );
- if ( !templ )
+ CTeam * team = TeamManager.getRealTeam( user->getTeamId() );
+ if ( !team )
{
- MISLOG("user:%s cbClientGroupAbandonMission : invalid group mission alias %u",
- userId.toString().c_str(), mission->getTemplateId());
+ MISLOG("user:%s cbClientGroupAbandonMission : Invalid team", userId.toString().c_str());
return;
}
- if ( templ->Tags.NonAbandonnable )
+ if ( team->getLeader() != userId )
{
- MISLOG("user:%s cbClientGroupAbandonMission : group mission alias %u is not abandonnable but user tries to abandon it",
- userId.toString().c_str(), mission->getTemplateId());
+ CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), "REQ_LEADER_TO_ABANDON_MISSION" );
+ return;
+ }
+
+ if ( index >= team->getMissions().size() )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : Invalid group mission %u ( count %u )",
+ userId.toString().c_str(), index, team->getMissions().size());
return;
}
- set excluded;
- excluded.insert( userId );
- team->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded );
+
+ CMissionTeam* mission = team->getMissions()[index];
+ nlassert(mission);
+
+ if ( mission->getFinished() == false )
+ {
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() );
+ if ( !templ )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : invalid group mission alias %u",
+ userId.toString().c_str(), mission->getTemplateId());
+ return;
+ }
+ if ( templ->Tags.NonAbandonnable )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : group mission alias %u is not abandonnable but user tries to abandon it",
+ userId.toString().c_str(), mission->getTemplateId());
+ return;
+ }
+ set excluded;
+ excluded.insert( userId );
+
+ team->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded );
+ }
+ team->removeMission( index, mr_abandon );
+ }
+ else
+ {
+ // Guild
+ // We set the correct index
+ index = MaxGroupMissionCount - index;
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
+ if ( !guild )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : Invalid team", userId.toString().c_str());
+ return;
+ }
+ if ( guild->getLeader()->getIngameEId() != userId )
+ {
+ CCharacter::sendDynamicSystemMessage( user->getEntityRowId(), "REQ_LEADER_TO_ABANDON_MISSION" );
+ return;
+ }
+
+ if ( index >= guild->getMissions().size() )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : Invalid group mission %u ( count %u )",
+ userId.toString().c_str(), index, guild->getMissions().size());
+ return;
+ }
+
+
+ CMissionGuild* mission = guild->getMissions()[index];
+ nlassert(mission);
+
+ if ( mission->getFinished() == false )
+ {
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( mission->getTemplateId() );
+ if ( !templ )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : invalid group mission alias %u",
+ userId.toString().c_str(), mission->getTemplateId());
+ return;
+ }
+ if ( templ->Tags.NonAbandonnable )
+ {
+ MISLOG("user:%s cbClientGroupAbandonMission : group mission alias %u is not abandonnable but user tries to abandon it",
+ userId.toString().c_str(), mission->getTemplateId());
+ return;
+ }
+ set excluded;
+ excluded.insert( userId );
+
+ guild->sendDynamicMessageToMembers( "ABANDON_GROUP_MISSION",TVectorParamCheck(), excluded );
+ }
+ guild->removeMission( index, mr_abandon );
}
- team->removeMission( index, mr_abandon );
}
//----------------------------------------------------------------------------
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp
index eb627551d..31cf1ff0f 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_action.cpp
@@ -511,9 +511,9 @@ class CMissionActionRecvItem : public IMissionAction
{
_SourceLine = line;
bool ret = true;
- if ( script.size() != 2 && script.size() != 3 )
+ if ( script.size() != 2 && script.size() != 3 && script.size() != 4)
{
- MISLOGSYNTAXERROR("- [
] [][:npc_name][:group]");
+ MISLOGSYNTAXERROR("- [
] [][:npc_name][:group][:guild]");
return false;
}
vector args;
@@ -569,6 +569,17 @@ class CMissionActionRecvItem : public IMissionAction
_Group = true;
}
+ // We check for the guild option
+ _Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ _Guild = true;
+ break;
+ }
+ }
+
if ( _Quantity == 0 )
{
@@ -606,7 +617,7 @@ class CMissionActionRecvItem : public IMissionAction
}
}
}
- else if ( !_Group )
+ else if ( !_Group && !_Guild)
{
CCharacter * user = PlayerManager.getChar( entities[0] );
CTeam * team = TeamManager.getRealTeam(user->getTeamId());
@@ -617,141 +628,245 @@ class CMissionActionRecvItem : public IMissionAction
}
}
-
- // check free room space in inventory
- // NB : in case of group, fail happens only if none in the group have enough free space
- sint16 neededSlotCount = 0;
- uint32 neededBulk = 0;
- CSheetId sheet = ( _SheetId != CSheetId::Unknown )?_SheetId:_Item.getSheetId();
- CGameItemPtr itemTmp = GameItemManager.createItem(sheet, _Quality, true, true);
- if (itemTmp != NULL)
+ // If the case we want to give the item to the guild
+ if (_Guild)
{
- neededSlotCount = (sint16) ceil( (float)_Quantity / itemTmp->getMaxStackSize() );
- neededBulk = _Quantity * itemTmp->getStackBulk();
- itemTmp.deleteItem();
+ if (entities.size() == 0)
+ return;
+
+ CCharacter * user = PlayerManager.getChar( entities[0] );
+ if (!user)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid user");
+ return;
+ }
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId());
+ if (!guild)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'");
+ return;
+ }
+
+ SM_STATIC_PARAMS_3(params, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
+ if ( _SheetId != CSheetId::Unknown )
+ {
+ const CStaticItem * form = CSheets::getForm( _SheetId );
+ if ( !form )
+ {
+ LOGMISSIONACTION("sheetId '" + _SheetId.toString() + "' is unknown");
+ return;
+ }
+ if (form->Family != ITEMFAMILY::MISSION_ITEM)
+ return;
+
+ uint quantity = _Quantity;
+ while (quantity > 0)
+ {
+ CGameItemPtr item = user->createItem(_Quality, quantity, _SheetId);
+ if (item == NULL)
+ break;
+ const uint32 stackSize = item->getStackSize();
+
+ if (!guild->putItem(item))
+ {
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
+ if ( templ )
+ {
+ if ( templ->Tags.FailIfInventoryIsFull )
+ {
+ instance->setProcessingState(CMission::ActionFailed);
+ return;
+ }
+ }
+ }
+ // from here item maybe NULL (because of autostack)
+
+ quantity -= stackSize;
+ }
+ params[2].Int = _Quality;
+ }
+ else
+ {
+ const CStaticItem * form = CSheets::getForm( _Item.getSheetId() );
+ if ( !form )
+ {
+ LOGMISSIONACTION("sheetId '" + _Item.getSheetId().toString() + "' is unknown");
+ return;
+ }
+ uint quantity = _Quantity;
+ while (quantity > 0)
+ {
+ CGameItemPtr item = _Item.createItem(quantity);
+ if (item == NULL)
+ break;
+
+ const uint32 stackSize = item->getStackSize();
+ if (!guild->putItem(item))
+ {
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
+ if ( templ )
+ {
+ if ( templ->Tags.FailIfInventoryIsFull )
+ {
+ instance->setProcessingState(CMission::ActionFailed);
+ return;
+ }
+ }
+ }
+ // from here item maybe NULL (because of autostack)
+
+ quantity -= stackSize;
+ }
+ params[2].Int = _Item.getQuality();
+ }
+
+ params[0].SheetId = _SheetId;
+ params[1].Int = _Quantity;
+
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_GUILD_RECV_ITEM", params);
+ }
}
else
{
- LOGMISSIONACTION("can't get static item from sheet " + sheet.toString());
- return;
- }
-
-
- bool fail = true;
- for ( uint i = 0; i < entities.size(); i++ )
- {
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
+ // check free room space in inventory
+ // NB : in case of group, fail happens only if none in the group have enough free space
+ sint16 neededSlotCount = 0;
+ uint32 neededBulk = 0;
+ CSheetId sheet = ( _SheetId != CSheetId::Unknown )?_SheetId:_Item.getSheetId();
+ CGameItemPtr itemTmp = GameItemManager.createItem(sheet, _Quality, true, true);
+ if (itemTmp != NULL)
{
- CInventoryPtr invBag = user->getInventory( INVENTORIES::bag );
- sint16 freeSlotcount = invBag->getFreeSlotCount();
- uint32 maxBulk = invBag->getMaxBulk();
-
- CInventoryPtr invTemp = user->getInventory( INVENTORIES::temporary );
- if( invTemp )
- {
- freeSlotcount -= invTemp->getUsedSlotCount();
- maxBulk -= invTemp->getInventoryBulk();
- }
-
- if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) )
- {
- fail = false;
- break;
- }
+ neededSlotCount = (sint16) ceil( (float)_Quantity / itemTmp->getMaxStackSize() );
+ neededBulk = _Quantity * itemTmp->getStackBulk();
+ itemTmp.deleteItem();
}
- }
- if( fail )
- {
- CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
- if ( templ )
+ else
{
- if ( templ->Tags.FailIfInventoryIsFull )
- {
- instance->setProcessingState(CMission::ActionFailed);
- return;
- }
+ LOGMISSIONACTION("can't get static item from sheet " + sheet.toString());
+ return;
}
- }
- for ( uint i = 0; i < entities.size(); i++ )
- {
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
+ bool fail = true;
+ for ( uint i = 0; i < entities.size(); i++ )
{
- SM_STATIC_PARAMS_3(params, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
- if ( _SheetId != CSheetId::Unknown )
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
{
- const CStaticItem * form = CSheets::getForm( _SheetId );
- if ( !form )
+ CInventoryPtr invBag = user->getInventory( INVENTORIES::bag );
+ sint16 freeSlotcount = invBag->getFreeSlotCount();
+ uint32 maxBulk = invBag->getMaxBulk();
+
+ CInventoryPtr invTemp = user->getInventory( INVENTORIES::temporary );
+ if( invTemp )
{
- LOGMISSIONACTION("sheetId '" + _SheetId.toString() + "' is unknown");
+ freeSlotcount -= invTemp->getUsedSlotCount();
+ maxBulk -= invTemp->getInventoryBulk();
+ }
+
+ if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) )
+ {
+ fail = false;
+ break;
+ }
+ }
+ }
+ if( fail )
+ {
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
+ if ( templ )
+ {
+ if ( templ->Tags.FailIfInventoryIsFull )
+ {
+ instance->setProcessingState(CMission::ActionFailed);
return;
}
- if (form->Family != ITEMFAMILY::MISSION_ITEM && !user->enterTempInventoryMode(TEMP_INV_MODE::MissionReward))
- continue;
+ }
+ }
- uint quantity = _Quantity;
- while (quantity > 0)
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ SM_STATIC_PARAMS_3(params, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
+ if ( _SheetId != CSheetId::Unknown )
{
- CGameItemPtr item = user->createItem(_Quality, quantity, _SheetId);
- if (item == NULL)
- break;
- const uint32 stackSize = item->getStackSize();
-
- if( form->Family != ITEMFAMILY::MISSION_ITEM )
+ const CStaticItem * form = CSheets::getForm( _SheetId );
+ if ( !form )
{
+ LOGMISSIONACTION("sheetId '" + _SheetId.toString() + "' is unknown");
+ return;
+ }
+ if (form->Family != ITEMFAMILY::MISSION_ITEM && !user->enterTempInventoryMode(TEMP_INV_MODE::MissionReward))
+ continue;
+
+ uint quantity = _Quantity;
+ while (quantity > 0)
+ {
+ CGameItemPtr item = user->createItem(_Quality, quantity, _SheetId);
+ if (item == NULL)
+ break;
+ const uint32 stackSize = item->getStackSize();
+
+ if( form->Family != ITEMFAMILY::MISSION_ITEM )
+ {
+ if (!user->addItemToInventory(INVENTORIES::temporary, item))
+ {
+ item.deleteItem();
+ break;
+ }
+ }
+ else
+ {
+ if (!user->addItemToInventory(INVENTORIES::bag, item))
+ {
+ item.deleteItem();
+ break;
+ }
+ }
+ // from here item maybe NULL (because of autostack)
+
+ quantity -= stackSize;
+ }
+ params[2].Int = _Quality;
+ }
+ else
+ {
+ const CStaticItem * form = CSheets::getForm( _Item.getSheetId() );
+ if ( !form )
+ {
+ LOGMISSIONACTION("sheetId '" + _Item.getSheetId().toString() + "' is unknown");
+ return;
+ }
+ uint quantity = _Quantity;
+ while (quantity > 0)
+ {
+ CGameItemPtr item = _Item.createItem(quantity);
+ if (item == NULL)
+ break;
+
+ const uint32 stackSize = item->getStackSize();
if (!user->addItemToInventory(INVENTORIES::temporary, item))
{
item.deleteItem();
break;
}
- }
- else
- {
- if (!user->addItemToInventory(INVENTORIES::bag, item))
- {
- item.deleteItem();
- break;
- }
- }
- // from here item maybe NULL (because of autostack)
+ // from here item maybe NULL (because of autostack)
- quantity -= stackSize;
+ quantity -= stackSize;
+ }
+ params[2].Int = _Item.getQuality();
}
- params[2].Int = _Quality;
+
+ params[0].SheetId = _SheetId;
+ params[1].Int = _Quantity;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_ITEM", params);
}
- else
- {
- const CStaticItem * form = CSheets::getForm( _Item.getSheetId() );
- if ( !form )
- {
- LOGMISSIONACTION("sheetId '" + _Item.getSheetId().toString() + "' is unknown");
- return;
- }
- uint quantity = _Quantity;
- while (quantity > 0)
- {
- CGameItemPtr item = _Item.createItem(quantity);
- if (item == NULL)
- break;
-
- const uint32 stackSize = item->getStackSize();
- if (!user->addItemToInventory(INVENTORIES::temporary, item))
- {
- item.deleteItem();
- break;
- }
- // from here item maybe NULL (because of autostack)
-
- quantity -= stackSize;
- }
- params[2].Int = _Item.getQuality();
- }
-
- params[0].SheetId = _SheetId;
- params[1].Int = _Quantity;
- PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_ITEM", params);
}
}
};
@@ -760,6 +875,7 @@ class CMissionActionRecvItem : public IMissionAction
uint16 _Quantity;
CSheetId _SheetId;
bool _Group;
+ bool _Guild;
MISSION_ACTION_GETNEWPTR(CMissionActionRecvItem)
};
@@ -772,9 +888,9 @@ class CMissionActionRecvNamedItem : public IMissionAction
bool buildAction ( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData)
{
_SourceLine = line;
- if ( script.size() != 2 && script.size() != 3 )
+ if ( script.size() != 2 && script.size() != 3 && script.size() != 4)
{
- MISLOGSYNTAXERROR(" [] [:group]");
+ MISLOGSYNTAXERROR(" [] [:group] [:guild]");
return false;
}
vector args;
@@ -813,6 +929,17 @@ class CMissionActionRecvNamedItem : public IMissionAction
_Group = true;
}
+ // We check for the guild option
+ _Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ _Guild = true;
+ break;
+ }
+ }
+
if ( _Quantity == 0 )
{
MISLOGERROR("quantity = 0");
@@ -848,7 +975,7 @@ class CMissionActionRecvNamedItem : public IMissionAction
}
}
}
- else if ( !_Group )
+ else if ( !_Group && !_Guild)
{
CCharacter * user = PlayerManager.getChar( entities[0] );
CTeam * team = TeamManager.getRealTeam(user->getTeamId());
@@ -859,41 +986,34 @@ class CMissionActionRecvNamedItem : public IMissionAction
}
}
- // check free room space in inventory
- // NB : in case of group, fail happens only if noone in the group have enough free space
- CGameItemPtr itemTmp = CNamedItems::getInstance().createNamedItem(_NamedItem, _Quantity);
- if( itemTmp != NULL )
+ // If the case we want to give the item to the guild
+ if (_Guild)
{
- sint16 neededSlotCount = (sint16) ceil( (float)_Quantity / itemTmp->getMaxStackSize() );
- uint32 neededBulk = _Quantity * itemTmp->getStackBulk();
- itemTmp.deleteItem();
-
- bool fail = true;
- for ( uint i = 0; i < entities.size(); i++ )
- {
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
- {
- CInventoryPtr invBag = user->getInventory( INVENTORIES::bag );
- sint16 freeSlotcount = invBag->getFreeSlotCount();
- uint32 maxBulk = invBag->getMaxBulk();
+ if (entities.size() == 0)
+ return;
- CInventoryPtr invTemp = user->getInventory( INVENTORIES::temporary );
- if( invTemp )
- {
- freeSlotcount -= invTemp->getUsedSlotCount();
- maxBulk -= invTemp->getInventoryBulk();
- }
-
- if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) )
- {
- fail = false;
- break;
- }
- }
-
+ CCharacter * user = PlayerManager.getChar( entities[0] );
+ if (!user)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid user");
+ return;
}
- if( fail )
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId());
+ if (!guild)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'");
+ return;
+ }
+
+ // add the item to inventory
+ CGameItemPtr item = CNamedItems::getInstance().createNamedItem(_NamedItem, _Quantity);
+ if (item == NULL)
+ {
+ LOGMISSIONACTION("named item '" + _NamedItem + "' is unknown");
+ return;
+ }
+ if (!guild->putItem(item))
{
CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
if ( templ )
@@ -905,39 +1025,103 @@ class CMissionActionRecvNamedItem : public IMissionAction
}
}
}
+ else
+ {
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ SM_STATIC_PARAMS_2(params, STRING_MANAGER::dyn_string_id, STRING_MANAGER::integer);
+ params[0].StringId = item->sendNameId(user);
+ params[1].Int = _Quantity;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_GUILD_RECV_NAMED_ITEM", params);
+ }
+ }
+ }
}
else
{
- LOGMISSIONACTION("named item '" + _NamedItem + "' is unknown");
- return;
- }
-
- // apply the action to all entities
- for ( uint i = 0; i < entities.size(); i++ )
- {
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
+ // check free room space in inventory
+ // NB : in case of group, fail happens only if noone in the group have enough free space
+ CGameItemPtr itemTmp = CNamedItems::getInstance().createNamedItem(_NamedItem, _Quantity);
+ if( itemTmp != NULL )
{
- if (!user->enterTempInventoryMode(TEMP_INV_MODE::MissionReward))
- continue;
+ sint16 neededSlotCount = (sint16) ceil( (float)_Quantity / itemTmp->getMaxStackSize() );
+ uint32 neededBulk = _Quantity * itemTmp->getStackBulk();
+ itemTmp.deleteItem();
+
+ bool fail = true;
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ CInventoryPtr invBag = user->getInventory( INVENTORIES::bag );
+ sint16 freeSlotcount = invBag->getFreeSlotCount();
+ uint32 maxBulk = invBag->getMaxBulk();
- // add the item to inventory
- CGameItemPtr item = CNamedItems::getInstance().createNamedItem(_NamedItem, _Quantity);
- if (item == NULL)
- {
- LOGMISSIONACTION("named item '" + _NamedItem + "' is unknown");
- return;
+ CInventoryPtr invTemp = user->getInventory( INVENTORIES::temporary );
+ if( invTemp )
+ {
+ freeSlotcount -= invTemp->getUsedSlotCount();
+ maxBulk -= invTemp->getInventoryBulk();
+ }
+
+ if( (neededSlotCount <= freeSlotcount) && ( neededBulk + invBag->getInventoryBulk() <= maxBulk) )
+ {
+ fail = false;
+ break;
+ }
+ }
+
}
- if(!user->addItemToInventory(INVENTORIES::temporary, item))
+ if( fail )
{
- item.deleteItem();
+ CMissionTemplate * templ = CMissionManager::getInstance()->getTemplate( instance->getTemplateId() );
+ if ( templ )
+ {
+ if ( templ->Tags.FailIfInventoryIsFull )
+ {
+ instance->setProcessingState(CMission::ActionFailed);
+ return;
+ }
+ }
}
- else
+ }
+ else
+ {
+ LOGMISSIONACTION("named item '" + _NamedItem + "' is unknown");
+ return;
+ }
+
+ // apply the action to all entities
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
{
- SM_STATIC_PARAMS_2(params, STRING_MANAGER::dyn_string_id, STRING_MANAGER::integer);
- params[0].StringId = item->sendNameId(user);
- params[1].Int = _Quantity;
- PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_NAMED_ITEM", params);
+ if (!user->enterTempInventoryMode(TEMP_INV_MODE::MissionReward))
+ continue;
+
+ // add the item to inventory
+ CGameItemPtr item = CNamedItems::getInstance().createNamedItem(_NamedItem, _Quantity);
+ if (item == NULL)
+ {
+ LOGMISSIONACTION("named item '" + _NamedItem + "' is unknown");
+ return;
+ }
+ if(!user->addItemToInventory(INVENTORIES::temporary, item))
+ {
+ item.deleteItem();
+ }
+ else
+ {
+ SM_STATIC_PARAMS_2(params, STRING_MANAGER::dyn_string_id, STRING_MANAGER::integer);
+ params[0].StringId = item->sendNameId(user);
+ params[1].Int = _Quantity;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_NAMED_ITEM", params);
+ }
}
}
}
@@ -945,6 +1129,7 @@ class CMissionActionRecvNamedItem : public IMissionAction
std::string _NamedItem;
uint16 _Quantity;
bool _Group;
+ bool _Guild;
MISSION_ACTION_GETNEWPTR(CMissionActionRecvNamedItem)
};
@@ -1043,9 +1228,9 @@ class CMissionActionDestroyItem :
{
// Parse the line
_SourceLine = line;
- if ( script.size() != 2 && script.size() != 3)
+ if ( script.size() != 2 && script.size() != 3 && script.size() != 4)
{
- MISLOGSYNTAXERROR("- [
] []:[npc_name]");
+ MISLOGSYNTAXERROR("- [
] []:[npc_name] [:guild]");
return false;
}
@@ -1060,6 +1245,17 @@ class CMissionActionDestroyItem :
ret= false;
}
+ // We check for the guild option
+ _Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ _Guild = true;
+ break;
+ }
+ }
+
return ret;
}
@@ -1074,36 +1270,86 @@ class CMissionActionDestroyItem :
instance->getEntities(entities);
if ( entities.empty() )
return;
- for ( uint i = 0; i < entities.size(); i++ )
+
+ // If the "guild" parameter is not set, we destroy the items for the users
+ if (!_Guild)
{
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
+
+ for ( uint i = 0; i < entities.size(); i++ )
{
- // Select the items in Bag AND mektoub that match the request
- vector itemList;
- user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList);
- for(uint pa=0;paselectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList);
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ // Select the items in Bag AND mektoub that match the request
+ vector itemList;
+ user->selectItems(INVENTORIES::bag, _SheetId, _Quality, &itemList);
+ for(uint pa=0;paselectItems(INVENTORIES::TInventory(INVENTORIES::pet_animal + pa), _SheetId, _Quality, &itemList);
- // Destroy them, up to quantity wanted
- // NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near!
- uint quantityReallyDestroyed;
- quantityReallyDestroyed= user->destroyItems(itemList, _Quantity);
+ // Destroy them, up to quantity wanted
+ // NB: don't care if destroying an item owned by a mektoub is strange because mektoub not near!
+ uint quantityReallyDestroyed;
+ quantityReallyDestroyed= user->destroyItems(itemList, _Quantity);
- // Send message
- SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
- TAIAlias botAlias= _Npc;
- if(botAlias==CAIAliasTranslator::Invalid)
- botAlias= instance->getGiver();
- params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias);
- params[1].SheetId = _SheetId;
- params[2].Int = quantityReallyDestroyed;
- params[3].Int = _Quality;
- PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params);
+ // Send message
+ SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
+ TAIAlias botAlias= _Npc;
+ if(botAlias==CAIAliasTranslator::Invalid)
+ botAlias= instance->getGiver();
+ params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias);
+ params[1].SheetId = _SheetId;
+ params[2].Int = quantityReallyDestroyed;
+ params[3].Int = _Quality;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params);
+ }
+ }
+
+ }
+ // We destroy the item in the guild
+ else
+ {
+ CCharacter * user = PlayerManager.getChar( entities[0] );
+ if (!user)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid user");
+ return;
+ }
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId());
+ if (!guild)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'");
+ return;
+ }
+
+ vector itemList;
+ guild->selectItems(_SheetId, _Quality, &itemList);
+
+ // Destroy them, up to quantity wanted
+ uint quantityReallyDestroyed;
+ quantityReallyDestroyed = guild->destroyItems(itemList, _Quantity);
+
+ // Send message
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ SM_STATIC_PARAMS_4(params, STRING_MANAGER::bot, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
+ TAIAlias botAlias= _Npc;
+ if(botAlias==CAIAliasTranslator::Invalid)
+ botAlias= instance->getGiver();
+ params[0].setEIdAIAlias(CAIAliasTranslator::getInstance()->getEntityId( botAlias ), botAlias);
+ params[1].SheetId = _SheetId;
+ params[2].Int = quantityReallyDestroyed;
+ params[3].Int = _Quality;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_DESTROY_ITEM", params);
+ }
}
}
};
TAIAlias _Npc;
+ bool _Guild;
MISSION_ACTION_GETNEWPTR(CMissionActionDestroyItem)
};
@@ -1607,9 +1853,9 @@ class CMissionActionRecvMoney : public IMissionAction
{
bool ret = true;
_SourceLine = line;
- if ( script.size() != 2 )
+ if ( script.size() != 2 && script.size() != 3)
{
- MISLOGSYNTAXERROR(" OR *[;]");
+ MISLOGSYNTAXERROR(" [: guild] OR *[;]");
return false;
}
@@ -1637,6 +1883,18 @@ class CMissionActionRecvMoney : public IMissionAction
ret = false;
}
}
+
+ // We check for the guild option
+ _Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ _Guild = true;
+ break;
+ }
+ }
+
return ret;
}
@@ -1647,22 +1905,67 @@ class CMissionActionRecvMoney : public IMissionAction
std::vector entities;
instance->getEntities(entities);
- uint amount = _Amount / (uint)entities.size();
- if ( amount == 0 || _Amount % entities.size() )
- amount++;
- for ( uint i = 0; i < entities.size(); i++ )
+
+ // If the guild parameter is not set we just divide the money and give it to each entity
+ if (!_Guild)
{
- CCharacter * user = PlayerManager.getChar( entities[i] );
- if ( user )
+
+ uint amount = _Amount / (uint)entities.size();
+ if ( amount == 0 || _Amount % entities.size() )
+ amount++;
+ for ( uint i = 0; i < entities.size(); i++ )
{
- user->giveMoney( _Amount );
- SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
- params[0].Int = _Amount;
- PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_MONEY",params);
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ user->giveMoney( _Amount );
+ SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
+ params[0].Int = _Amount;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_RECV_MONEY",params);
+ }
}
+
+ }
+ // Else we give the money to the guild
+ else
+ {
+ if (entities.size() == 0)
+ return;
+
+ CCharacter * user = PlayerManager.getChar( entities[0] );
+ if (!user)
+ {
+ LOGMISSIONACTION("recv_money : Invalid user");
+ return;
+ }
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId());
+ if (guild)
+ {
+ guild->addMoney(_Amount);
+ }
+ else
+ {
+ LOGMISSIONACTION("recv_money : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'");
+ return;
+ }
+
+ // tell everyone some money has been given to the guild
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CCharacter * user = PlayerManager.getChar( entities[i] );
+ if ( user )
+ {
+ SM_STATIC_PARAMS_1(params, STRING_MANAGER::integer);
+ params[0].Int = _Amount;
+ PHRASE_UTILITIES::sendDynamicSystemMessage(user->getEntityRowId(),"MIS_GUILD_RECV_MONEY",params);
+ }
+ }
+
}
};
uint _Amount;
+ bool _Guild;
MISSION_ACTION_GETNEWPTR(CMissionActionRecvMoney)
};
@@ -1675,9 +1978,9 @@ class CMissionActionRecvFame : public IMissionAction
bool buildAction ( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData)
{
_SourceLine = line;
- if ( script.size() != 2 )
+ if ( script.size() != 2 && script.size() != 3)
{
- MISLOGSYNTAXERROR(" ");
+ MISLOGSYNTAXERROR(" [:guild]");
return false;
}
vector args;
@@ -1700,6 +2003,18 @@ class CMissionActionRecvFame : public IMissionAction
MISLOGERROR("fame = 0");
return false;
}
+
+ // We check for the guild option
+ _Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ _Guild = true;
+ break;
+ }
+ }
+
return true;
}
@@ -1708,20 +2023,63 @@ class CMissionActionRecvFame : public IMissionAction
LOGMISSIONACTION("recv_fame");
std::vector entities;
instance->getEntities(entities);
- for ( uint i = 0; i < entities.size(); i++ )
- {
- CEntityId eid = TheDataset.getEntityId(entities[i]);
- CFameInterface::getInstance().addFameIndexed(eid, _Faction, _Value, true);
- // Make the client refresh the icons on mission giver NPCs, at once
- CCharacter *character = PlayerManager.getChar(entities[i]);
- if (character)
- character->sendEventForMissionAvailabilityCheck();
+ // If there is no "guild" parameter we give the fame to every user
+ if (!_Guild)
+ {
+
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ CEntityId eid = TheDataset.getEntityId(entities[i]);
+ CFameInterface::getInstance().addFameIndexed(eid, _Faction, _Value, true);
+
+ // Make the client refresh the icons on mission giver NPCs, at once
+ CCharacter *character = PlayerManager.getChar(entities[i]);
+ if (character)
+ character->sendEventForMissionAvailabilityCheck();
+ }
+
+ }
+ // Else we just give it to the guild
+ else
+ {
+
+ if (entities.size() == 0)
+ return;
+
+ CCharacter * user = PlayerManager.getChar( entities[0] );
+ if (!user)
+ {
+ LOGMISSIONACTION("recv_fame : Invalid user");
+ return;
+ }
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId(user->getGuildId());
+ if (guild)
+ {
+ CFameInterface::getInstance().addFameIndexed(guild->getEId(), _Faction, _Value, true);
+ }
+ else
+ {
+ LOGMISSIONACTION("recv_fame : Invalid guild id '" + NLMISC::toString(user->getGuildId()) + "'");
+ return;
+ }
+
+ // tell everyone some money has been given to the guild
+ for ( uint i = 0; i < entities.size(); i++ )
+ {
+ // Make the client refresh the icons on mission giver NPCs, at once
+ CCharacter *character = PlayerManager.getChar(entities[i]);
+ if (character)
+ character->sendEventForMissionAvailabilityCheck();
+ }
+
}
};
uint32 _Faction;
sint32 _Value;
+ bool _Guild;
MISSION_ACTION_GETNEWPTR(CMissionActionRecvFame)
};
@@ -3695,15 +4053,16 @@ protected:
TAIAlias Mission;
TAIAlias NPCOwner; // NPC giver the mission have to be attached at spawn time
+ bool Guild;
protected:
bool buildAction ( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData)
{
_SourceLine = line;
- if ( script.size() != 3 )
+ if ( script.size() != 3 && script.size() != 4)
{
- MISLOGSYNTAXERROR(" : ");
+ MISLOGSYNTAXERROR(" : [: guild]");
return false;
}
string name = CMissionParser::getNoBlankString( script[1] );
@@ -3736,6 +4095,17 @@ protected:
if (vRet.size() > 0)
NPCOwner = vRet[0];
+ // We check for the guild option
+ Guild = false;
+ for (std::vector< std::string >::const_iterator it = script.begin(); it != script.end(); ++it)
+ {
+ if (CMissionParser::getNoBlankString(*it) == "guild")
+ {
+ Guild = true;
+ break;
+ }
+ }
+
return true;
}
@@ -3746,13 +4116,13 @@ protected:
{
CAIAliasTranslator::getInstance()->getNPCNameFromAlias(instance->getGiver(), sDebugBotName);
nlassert(instance);
- CMissionEventAddMission * event = new CMissionEventAddMission( instance->getGiver(), Mission, mainMission );
+ CMissionEventAddMission * event = new CMissionEventAddMission( instance->getGiver(), Mission, mainMission, Guild );
eventList.push_back( event );
}
else
{
CAIAliasTranslator::getInstance()->getNPCNameFromAlias(NPCOwner, sDebugBotName);
- CMissionEventAddMission * event = new CMissionEventAddMission( NPCOwner, Mission, mainMission );
+ CMissionEventAddMission * event = new CMissionEventAddMission( NPCOwner, Mission, mainMission, Guild );
eventList.push_back( event );
}
LOGMISSIONACTION("spawn_mission bot:" + sDebugBotName + " newmiss:" + CPrimitivesParser::aliasToString(Mission)
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_event.h b/code/ryzom/server/src/entities_game_service/mission_manager/mission_event.h
index d2c879799..34ff36600 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_event.h
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_event.h
@@ -429,11 +429,12 @@ protected:
class CMissionEventAddMission: public CMissionEvent
{
public:
- CMissionEventAddMission( TAIAlias giver, TAIAlias mission, TAIAlias mainMission )
- :CMissionEvent(AddMission, TDataSetRow()) ,Giver(giver),Mission(mission),MainMission(mainMission) {}
+ CMissionEventAddMission( TAIAlias giver, TAIAlias mission, TAIAlias mainMission, bool guild )
+ :CMissionEvent(AddMission, TDataSetRow()) ,Giver(giver),Mission(mission),MainMission(mainMission), Guild(guild) {}
TAIAlias Mission;
TAIAlias Giver;
TAIAlias MainMission;
+ bool Guild;
protected:
friend class CMissionEvent;
bool buildFromScript( const std::vector< std::string > & script ,NLMISC::CLog& log){return false;}
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.cpp
index d3bb2c106..63b74e997 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.cpp
@@ -25,18 +25,83 @@
#include "player_manager/player.h"
#include "player_manager/character.h"
+using namespace std;
+using namespace NLMISC;
+
NL_INSTANCE_COUNTER_IMPL(CMissionGuild);
//----------------------------------------------------------------------------
void CMissionGuild::updateUsersJournalEntry()
{
- /// todo guild mission
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( _GuildId );
+ if (!guild)
+ {
+ nlwarning( "cant find guild ID : %d", _GuildId );
+ return;
+ }
+
+ for ( std::map::iterator it = guild->getMembersBegin();
+ it != guild->getMembersEnd();++it )
+ {
+ CCharacter * user = PlayerManager.getChar( it->first );
+ if ( !user )
+ {
+ nlwarning( "cant find user %s", it->first.toString().c_str() );
+ continue;
+ }
+ updateUserJournalEntry(*user,"GROUP:");
+ }
}
//----------------------------------------------------------------------------
void CMissionGuild::clearUsersJournalEntry()
{
- /// todo guild mission
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( _GuildId );
+ if (!guild)
+ {
+ nlwarning( "cant find guild ID : %d", _GuildId );
+ return;
+ }
+
+ for ( std::map::iterator it = guild->getMembersBegin();
+ it != guild->getMembersEnd();++it )
+ {
+ CCharacter * user = PlayerManager.getChar( it->first );
+ if ( !user )
+ {
+ nlwarning( "cant find user %s", it->first.toString().c_str() );
+ continue;
+ }
+
+ CBankAccessor_PLR::TGROUP::TMISSIONS::TArray &missionItem = CBankAccessor_PLR::getGROUP().getMISSIONS().getArray(_ClientIndex);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:TYPE",_ClientIndex), 0);
+ missionItem.setTYPE(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:ICON",_ClientIndex), 0);
+ missionItem.setICON(user->_PropertyDatabase, CSheetId::Unknown);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:TITLE",_ClientIndex), 0);
+ missionItem.setTITLE(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:DETAIL_TEXT",_ClientIndex), 0);
+ missionItem.setDETAIL_TEXT(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:END_DATE",_ClientIndex), 0 );
+ missionItem.setEND_DATE(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:BEGIN_DATE",_ClientIndex), 0 );
+ missionItem.setBEGIN_DATE(user->_PropertyDatabase, 0);
+ for (uint i = 0; i < NB_JOURNAL_COORDS; i++)
+ {
+ CBankAccessor_PLR::TGROUP::TMISSIONS::TArray::TTARGET &targetItem = missionItem.getTARGET(i);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:TARGET%u:TITLE",_ClientIndex,i), 0);
+ targetItem.setTITLE(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:TARGET%u:X",_ClientIndex,i), 0);
+ targetItem.setX(user->_PropertyDatabase, 0);
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:TARGET%u:Y",_ClientIndex,i), 0);
+ targetItem.setY(user->_PropertyDatabase, 0);
+ }
+ for (uint i = 0; i < NB_STEP_PER_MISSION; i++)
+ {
+ // user->_PropertyDatabase.setProp( NLMISC::toString( "GROUP:MISSIONS:%u:GOALS:%u:TEXT",_ClientIndex,i), 0);
+ missionItem.getGOALS().getArray(i).setTEXT(user->_PropertyDatabase, 0);
+ }
+ }
}
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.h b/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.h
index e0c65f2c2..b8635d1d4 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.h
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_guild.h
@@ -32,6 +32,7 @@ public:
CMissionGuild() : _Chained(false) { }
+ inline void setGuild( uint32 guildId );
/// override
void updateUsersJournalEntry();
/// override
@@ -58,6 +59,10 @@ private:
bool _Chained;
};
+void CMissionGuild::setGuild( uint32 guildId )
+{
+ _GuildId = guildId;
+}
#endif // RY_MISSION_GUILD_H
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp
index b0bd41ffb..ca5d4bba0 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_manager.cpp
@@ -44,6 +44,7 @@
#include "egs_utils.h"
#include "egs_pd.h"
#include "guild_manager/guild_member_module.h"
+#include "guild_manager/guild_manager.h"
#include "building_manager/building_manager.h"
#include "building_manager/room_instance.h"
#include "zone_manager.h"
@@ -836,25 +837,68 @@ void CMissionManager::instanciateMission(CCharacter* user,TAIAlias alias, TAIAl
}
else if ( templ->Type == MISSION_DESC::Guild )
{
- /// todo guild mission
+ /// Check to see if we can pick the mission
CGuildMemberModule * module;
if ( !user->getModuleParent().getModule( module ) )
{
MISDBG("%s user not in a guild", sDebugPrefix.c_str());
return;
}
- inst = module->pickMission( templ->Alias );
- if (!inst)
+ /* /// This is already checked in the prerequisites
+ if (!module->pickMission( templ->Alias ))
+ {
+ /// Todo : error message for the member
return;
- /// todo guild mission : see solo
- /*
- todo guild mission : implement that in module
- teamMission->initBasics( giver );
- soloMission->setTeam( user->getTeamId() );
+ }*/
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
+ if (!guild)
+ {
+ nlwarning( "cant find guild ID : %d", user->getGuildId() );
+ return;
+ }
+ if ( !templ->Tags.NoList && guild->getMissions().size() >= MaxGuildMissionCount)
+ {
+ CCharacter::sendDynamicSystemMessage(user->getId(), "MISSION_MAX_GUILD_REACHED" );
+ return;
+ }
+
+ CMissionGuild * guildMission = EGS_PD_CAST( EGSPD::CMissionGuildPD::create( templ->Alias ) );
+ if ( !guildMission )
+ {
+ MISDBG("%s could not create guild mission", sDebugPrefix.c_str());
+ return;
+ }
+ guildMission->onCreation( giver );
+ guildMission->setGuild(user->getGuildId());
+
+ // Find a suitable client index (for non-invisible missions)
+ if ( templ->Tags.NoList == false )
+ {
+ uint8 idx = 0;
+ for ( uint i = MaxGroupMissionCount; i < MaxGroupMissionCount + MaxGuildMissionCount; i++ )
+ {
+ if ( ! CBankAccessor_PLR::getGROUP().getMISSIONS().getArray(i).getTITLE(user->_PropertyDatabase))
+ {
+ idx = i;
+ break;
+ }
+ }
+ guildMission->setClientIndex( idx );
+ }
+
+ // Add mission
+ guild->addMission( guildMission );
+ inst = guildMission;
+
+ /// /!\ Do the same thing that the team missions but with the loop: for ( uint i = MaxGroupMissionCount; i < MaxGroupMissionCount + MaxGuildMissionCount; i++ )
+ /// Instead of for ( uint i = 0; i < MaxGroupMissionCount; i++ ), so that we use available space for guild missions
+
+ /*//teamMission->initBasics( giver );
+ //soloMission->setTeam( user->getTeamId() );
CGuild * guild = user->getGuild();
if ( guild )
{
- mission->getguild
if ( guild->getMissions().size() >= MaxGuildMissionCount)
{
CCharacter::sendDynamicSystemMessage(user->getId(), "MISSION_MAX_GUILD_REACHED" );
@@ -880,8 +924,7 @@ void CMissionManager::instanciateMission(CCharacter* user,TAIAlias alias, TAIAl
else
{
- }
- */
+ }*/
}
else
{
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_misc.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_misc.cpp
index ff8496eba..03ad33b28 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_misc.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_step_misc.cpp
@@ -1141,7 +1141,13 @@ MISSION_REGISTER_STEP(CMissionStepCast,"cast")
// ----------------------------------------------------------------------------
class CMissionStepDoMissions : public IMissionStepTemplate
{
- std::vector< std::string > _Missions;
+ struct MissionNb
+ {
+ std::string Mission;
+ uint32 NbNeedCompletion;
+ };
+
+ std::vector< MissionNb > _Missions;
virtual bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData )
{
@@ -1158,7 +1164,23 @@ class CMissionStepDoMissions : public IMissionStepTemplate
_Missions.resize(subs.size());
for ( uint i = 0; i < subs.size(); i++ )
{
- _Missions[i] = CMissionParser::getNoBlankString( subs[i] );
+ std::vector< std::string > params;
+ //NLMISC::splitString( subs[i]," \t", params );
+ subs[i] = CMissionParser::getNoBlankString(subs[i]);
+ std::size_t pos = subs[i].find_first_of(" \t");
+ std::string str = subs[i].substr(0, pos);
+ params.push_back(str);
+ if (pos != std::string::npos)
+ str = subs[i].substr(pos + 1);
+ else
+ str = "";
+ params.push_back(str);
+ //std::size_t pos = _Missions[i].find_first_of(" \t");
+ _Missions[i].Mission = CMissionParser::getNoBlankString( params[0] );
+ if (params.size() > 1)
+ NLMISC::fromString(params[1], _Missions[i].NbNeedCompletion);
+ else
+ _Missions[i].NbNeedCompletion = 1;
}
return true;
}
@@ -1168,7 +1190,7 @@ class CMissionStepDoMissions : public IMissionStepTemplate
if ( event.Type == CMissionEvent::MissionDone )
{
CMissionEventMissionDone & eventSpe = (CMissionEventMissionDone&)event;
- TAIAlias alias = CAIAliasTranslator::getInstance()->getMissionUniqueIdFromName( _Missions[subStepIndex] );
+ TAIAlias alias = CAIAliasTranslator::getInstance()->getMissionUniqueIdFromName( _Missions[subStepIndex].Mission );
if ( eventSpe.Mission == alias )
{
LOGMISSIONSTEPSUCCESS("mission");
@@ -1181,11 +1203,36 @@ class CMissionStepDoMissions : public IMissionStepTemplate
void getInitState( std::vector& ret )
{
ret.resize( _Missions.size(), 1 );
+ uint32 i = 0;
+ for (std::vector::const_iterator it = _Missions.begin(); it != _Missions.end(); ++it)
+ {
+ ret[i] = it->NbNeedCompletion;
+ i++;
+ }
}
virtual void getTextParams( uint & nbSubSteps,const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector& subStepStates)
{
- static const std::string stepText = "ERROR_UNSPECIFIED_MISSION_TEXT";
+ /*static const std::string stepText = "ERROR_UNSPECIFIED_MISSION_TEXT";
+ textPtr = &stepText;*/
+
+ // Because we can specify the number of times we want a mission to be completed, we specify the parameters
+ static const std::string stepText = "MIS_DO_MISSION_";
+ nlassert( _Missions.size() == subStepStates.size() );
+ for ( uint i = 0; i < subStepStates.size(); i++ )
+ {
+ if( subStepStates[i] != 0 )
+ {
+ nbSubSteps++;
+ retParams.push_back(STRING_MANAGER::TParam());
+ retParams.back().Type = STRING_MANAGER::integer;
+ retParams.back().Int = subStepStates[i];
+
+ retParams.push_back(STRING_MANAGER::TParam());
+ retParams.back().Type = STRING_MANAGER::literal;
+ retParams.back().Literal = _Missions[i].Mission;
+ }
+ }
textPtr = &stepText;
}
bool checkTextConsistency()
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp
index dfd516b45..af0686f1e 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/mission_template.cpp
@@ -1307,21 +1307,57 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
else if ( Type == MISSION_DESC::Guild )
{
/// todo guild mission
- /*
- CGuild * guild = user->getGuild();
+
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if ( guild == NULL )
{
MISDBG("No guild");
return MISSION_DESC::PreReqFail;
+
+ /*if (logOnFail)
+ MISDBG("%s No guild", sDebugPrefix.c_str());
+
+ if (!fillPrereqInfos)
+ return MISSION_DESC::PreReqFail;
+
+ prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "MISSION_PREREQ_TEAM", TVectorParamCheck());
+ prereqDesc.IsMandatory = true;
+ prereqDesc.Validated = false;
+ prereqInfos.Prerequisits.push_back(prereqDesc);
+
+ addedPrereqTexts.insert("MISSION_PREREQ_TEAM");
+
+ returnValue = MISSION_DESC::PreReqFail;
+ logOnFail = false;*/
}
// check if the mission is already picked
for ( uint j = 0 ; j < guild->getMissions().size(); j++ )
{
- if ( guild->getMissions()[j]->getTemplate()->Alias == alias )
+ if ( guild->getMissions()[j]->getTemplateId() == alias ||
+ guild->getMissions()[j]->getMainMissionTemplateId() == alias)
{
MISDBG("The guild already own this mission");
return MISSION_DESC::PreReqFail;
+
+ /*if (logOnFail)
+ MISDBG("%s The guild already own this mission", sDebugPrefix.c_str());
+
+ if (!fillPrereqInfos)
+ return MISSION_DESC::PreReqFail;
+
+ if (addedPrereqTexts.find("MISSION_PREREQ_ALREADY_DONE") == addedPrereqTexts.end())
+ {
+ prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "MISSION_PREREQ_ALREADY_DONE", TVectorParamCheck());
+ prereqDesc.IsMandatory = true;
+ prereqDesc.Validated = false;
+ prereqInfos.Prerequisits.push_back(prereqDesc);
+ addedPrereqTexts.insert("MISSION_PREREQ_ALREADY_DONE");
+ }
+
+ returnValue = MISSION_DESC::PreReqFail;
+ logOnFail = false;*/
}
+
}
// check non replayable missions
if( !Tags.Replayable )
@@ -1329,11 +1365,29 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
if (guild->isMissionSuccessfull(alias))
// if ( std::find(guild->getSuccessfulMissions().begin(),guild->getSuccessfulMissions().end(), alias) != guild->getSuccessfulMissions().end() )
{
- MISDBG("solo non replayable");
+ MISDBG("mission non replayable");
return MISSION_DESC::PreReqFail;
+
+ /*if (logOnFail)
+ MISDBG("%s Guild mission already done and not replayable", sDebugPrefix.c_str());
+
+ if (!fillPrereqInfos)
+ return MISSION_DESC::PreReqFailAlreadyDone;
+
+ if (addedPrereqTexts.find("MISSION_PREREQ_ALREADY_DONE") == addedPrereqTexts.end())
+ {
+ prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "MISSION_PREREQ_ALREADY_DONE", TVectorParamCheck());
+ prereqDesc.IsMandatory = true;
+ prereqDesc.Validated = false;
+ prereqInfos.Prerequisits.push_back(prereqDesc);
+ addedPrereqTexts.insert("MISSION_PREREQ_ALREADY_DONE");
+ }
+
+ returnValue = MISSION_DESC::PreReqFailAlreadyDone;
+ logOnFail = false;*/
}
}
- */
+
}
else
{
@@ -1412,7 +1466,7 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
if ( templ->Type == MISSION_DESC::Guild )
{
/// todo guild mission
- /*
+ CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if ( ! guild )
{
MISDBG("Require needed mission at line %u (guild mission but player has no guild)", Prerequisits.NeededMissions[i].Line);
@@ -1420,7 +1474,7 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
}
if (guild->isMissionSuccessfull(templ->Alias))
break;
- */
+
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@@ -1473,15 +1527,14 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
else if ( templ->Type == MISSION_DESC::Guild )
{
/// todo guild mission
- /*
+ CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if ( !guild )
break;
if (!guild->isMissionSuccessfull(templ->Alias))
-
- if (!guild || !guild->isMissionSuccessfull(templ->Alias))
-
break;
- */
+ /*if (!guild || !guild->isMissionSuccessfull(templ->Alias))
+ break;*/
+
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@@ -1537,8 +1590,8 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
{
/// todo guild mission
- /*
-
+
+ CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if ( !guild )
{
MISDBG("Require running mission at line %u (guild mission but player has no guild)", Prerequisits.RunningMissions[i].Line );
@@ -1548,12 +1601,12 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
for ( ; k < guild->getMissions().size(); k++ )
{
- if ( guild->getMissions()[k]->getTemplate()->Alias == templ->Alias )
+ if ( guild->getMissions()[k]->getTemplateId() == templ->Alias )
break;
}
if (k != guild->getMissions().size())
break;
- */
+
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@@ -1651,20 +1704,20 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
{
/// todo guild mission
- /*
-
+
+ CGuild* guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
if(!guild)
break;
uint k=0;
for ( ; k < guild->getMissions().size(); k++ )
{
- if ( guild->getMissions()[k]->getTemplate()->Alias == templ->Alias )
+ if ( guild->getMissions()[k]->getTemplateId() == templ->Alias )
break;
}
if (k == guild->getMissions().size())
break;
- */
+
}
else if ( templ->Type == MISSION_DESC::Solo )
{
@@ -2041,6 +2094,15 @@ uint32 CMissionTemplate::testPrerequisits( CCharacter * user, CPrerequisitInfos
if (!fillPrereqInfos)
return MISSION_DESC::PreReqFail;
+ /*if (addedPrereqTexts.find("GUILD_BUILDING_BAD_GRADE") == addedPrereqTexts.end())
+ {
+ prereqDesc.Description = STRING_MANAGER::sendStringToClient(user->getEntityRowId(), "GUILD_BUILDING_BAD_GRADE", TVectorParamCheck());
+ prereqDesc.IsMandatory = true;
+ prereqDesc.Validated = false;
+ prereqInfos.Prerequisits.push_back(prereqDesc);
+ addedPrereqTexts.insert("GUILD_BUILDING_BAD_GRADE");
+ }*/
+
returnValue = MISSION_DESC::PreReqFail;
logOnFail = false;
}
diff --git a/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp b/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp
index 78229d3a8..a5f0f863f 100644
--- a/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp
+++ b/code/ryzom/server/src/entities_game_service/mission_manager/missions_commands.cpp
@@ -30,7 +30,9 @@
#include "team_manager/team_manager.h"
#include "mission_manager/mission_team.h"
#include "mission_manager/mission_step_ai.h"
+#include "mission_manager/mission_guild.h"
#include "guild_manager/guild_manager.h"
+#include "guild_manager/guild.h"
#include "admin.h"
#include "creature_manager/creature_manager.h"
@@ -81,10 +83,18 @@ NLMISC_COMMAND(forceJournalUpdate,"force mission journal update","getMissions()[i]->updateUsersJournalEntry();
}
}
- for (uint i = 0; i < MaxGuildMissionCount; i++)
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( user->getGuildId() );
+ if (guild)
+ {
+ for ( uint i = 0; i < guild->getMissions().size(); i++ )
+ {
+ guild->getMissions()[i]->updateUsersJournalEntry();
+ }
+ }
+ /*for (uint i = 0; i < MaxGuildMissionCount; i++)
{
/// todo guild mission
- }
+ }*/
return true;
} // missionProgress //
diff --git a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp
index 9af9606ea..70c8238ac 100644
--- a/code/ryzom/server/src/entities_game_service/player_manager/character.cpp
+++ b/code/ryzom/server/src/entities_game_service/player_manager/character.cpp
@@ -1344,6 +1344,22 @@ uint32 CCharacter::tickUpdate()
}
}
+ // Adding UpdateCompass for guild missions
+ {
+ H_AUTO(CharacterUpdateGuildCompass);
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( _GuildId );
+ if ( guild )
+ {
+ const uint size = (uint)guild->getMissions().size();
+ for ( uint i = 0; i < size; i++ )
+ {
+ nlassert(guild->getMissions()[i]);
+ guild->getMissions()[i]->updateCompass(*this, string(""));
+ guild->getMissions()[i]->updateCompass(*this, string("GROUP:"));
+ }
+ }
+ }
+
{
H_AUTO(CharacterUpdateTargetCoordinatesCompass);
// update compass coordinates information
@@ -10709,6 +10725,7 @@ void CCharacter::acceptExchange(uint8 exchangeId)
}
CTeam * team = TeamManager.getRealTeam( _TeamId );
+ CGuild* guild = CGuildManager::getInstance()->getGuildFromId( _GuildId );
if (_BotGift == NULL)
{
nlwarning("Player %s has no bot gift", _Id.toString().c_str());
@@ -10732,6 +10749,15 @@ void CCharacter::acceptExchange(uint8 exchangeId)
}
mission = team->getMissionByAlias( missionAlias );
}
+ else if (type == MISSION_DESC::Guild)
+ {
+ if (guild == NULL)
+ {
+ nlwarning("CCharacter::acceptExchange : character %s -> no guild",_Id.toString().c_str() );
+ return;
+ }
+ mission = guild->getMissionByAlias( missionAlias );
+ }
vector vect;
vector exchangePlayerPets;
@@ -10765,6 +10791,8 @@ void CCharacter::acceptExchange(uint8 exchangeId)
processMissionStepUserEvent( eventList,missionAlias,stepIndex );
else if ( type == MISSION_DESC::Group )
team->processTeamMissionStepEvent( eventList,missionAlias,stepIndex );
+ else if ( type == MISSION_DESC::Guild )
+ guild->processGuildMissionStepEvent( eventList,missionAlias,stepIndex );
eventList.pop_front();
for ( std::list< CMissionEvent* >::iterator it = eventList.begin(); it != eventList.end(); ++it )
processMissionEvent(*(*it));
@@ -10784,6 +10812,8 @@ void CCharacter::acceptExchange(uint8 exchangeId)
processMissionStepUserEvent( eventList,missionAlias,stepIndex );
else if ( type == MISSION_DESC::Group )
team->processTeamMissionStepEvent( eventList,missionAlias,stepIndex );
+ else if ( type == MISSION_DESC::Guild )
+ guild->processGuildMissionStepEvent( eventList,missionAlias,stepIndex );
eventList.pop_front();
for ( std::list< CMissionEvent* >::iterator it = eventList.begin(); it != eventList.end(); ++it )
processMissionEvent(*(*it));
@@ -11616,7 +11646,7 @@ bool CCharacter::processMissionEventList( std::list< CMissionEvent* > & eventLis
bool processed = false;
bool firstEvent = true;
- CGuild * guild = NULL;
+ CGuild * guild = CGuildManager::getInstance()->getGuildFromId( _GuildId );
while ( !eventList.empty() )
{
bool eventProcessed = false;
@@ -11628,11 +11658,33 @@ bool CCharacter::processMissionEventList( std::list< CMissionEvent* > & eventLis
TAIAlias mission = eventSpe.Mission;
TAIAlias giver = eventSpe.Giver;
TAIAlias mainMission = eventSpe.MainMission;
+ bool missionForGuild = eventSpe.Guild;
// add mission event are always allocated on heap
delete ( CMissionEvent *) ( eventList.front() );
eventList.pop_front();
- CMissionManager::getInstance()->instanciateMission(this, mission, giver ,eventList, mainMission);
+
+ // If the mission is not for guild members we just instanciate it
+ if (!missionForGuild)
+ CMissionManager::getInstance()->instanciateMission(this, mission, giver ,eventList, mainMission);
+ else
+ {
+ // We find the guild and each guild members and we instanciate the mission for them
+ if (guild)
+ {
+ for ( std::map::iterator it = guild->getMembersBegin();
+ it != guild->getMembersEnd();++it )
+ {
+ CCharacter * guildUser = PlayerManager.getChar( it->first );
+ if ( !guildUser )
+ {
+ nlwarning( "cant find user %s", it->first.toString().c_str() );
+ continue;
+ }
+ CMissionManager::getInstance()->instanciateMission(guildUser, mission, giver ,eventList, mainMission);
+ }
+ }
+ }
}
// event may have been processed during instanciateMission
if ( eventList.empty() )
@@ -11653,6 +11705,13 @@ bool CCharacter::processMissionEventList( std::list< CMissionEvent* > & eventLis
eventProcessed = team->processTeamMissionEvent(eventList, alias);
}
+ // THIRD - Check with guild missions (if event not already processed and char belongs to a guild)
+ if (!eventProcessed)// && (event.Restriction != CMissionEvent::NoGroup))
+ {
+ if (guild != NULL)
+ eventProcessed = guild->processGuildMissionEvent(eventList, alias);
+ }
+
processed |= eventProcessed;
// the first event of the list was processed, so we remove it.
diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.h b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.h
index 756b3859d..6f993679b 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.h
+++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/mission_compiler.h
@@ -318,6 +318,11 @@ public:
bool isThereAJumpTo(const std::string &stepName);
+ bool isGuildMission() const
+ {
+ return _Guild;
+ }
+
private:
std::string genPreRequisites();
diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/step.h b/code/ryzom/tools/leveldesign/mission_compiler_lib/step.h
index e93db4524..fdb1db4be 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_lib/step.h
+++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/step.h
@@ -192,6 +192,11 @@ protected:
std::vector _RoleplayObj;
CPhrase _RoleplayPhrase;
bool _HideObj;
+
+ // Option nb_guild_members_needed, available for each objective
+ /*int _NbGuildMembersNeeded;
+
+ std::string genNbGuildMembersNeededOption(CMissionData &md);*/
public:
void init(CMissionData &md, NLLIGO::IPrimitive *prim);
diff --git a/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp b/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp
index c0d78ab74..f327f836a 100644
--- a/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp
+++ b/code/ryzom/tools/leveldesign/mission_compiler_lib/step_content.cpp
@@ -142,6 +142,7 @@ REGISTER_STEP_CONTENT(CActionJumpTo, "jump_to");
class CActionRecvMoney : public IStepContent
{
string _Amount;
+ bool _Guild;
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -152,12 +153,27 @@ public:
{
IStepContent::init(md, prim);
_Amount = md.getProperty(prim, "amount", true, false);
+
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
}
string genCode(CMissionData &md)
{
if (!_Amount.empty())
- return "recv_money : "+_Amount+NL;
+ {
+ string ret;
+ ret = "recv_money : "+_Amount;
+ if (_Guild)
+ ret += ": guild";
+ ret += NL;
+ return ret;
+ }
else
return string();
}
@@ -166,12 +182,79 @@ public:
REGISTER_STEP_CONTENT(CActionRecvMoney, "recv_money");
+// ---------------------------------------------------------------------------
+class CActionRecvChargePoint : public IStepContent
+{
+ string _Amount;
+
+ void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
+ {
+ numEntry = 0;
+ }
+public:
+ void init(CMissionData &md, IPrimitive *prim)
+ {
+ IStepContent::init(md, prim);
+ _Amount = md.getProperty(prim, "charge_points", true, false);
+ }
+
+ string genCode(CMissionData &md)
+ {
+ if (!_Amount.empty())
+ {
+ string ret;
+ ret = "recv_charge_point : "+_Amount;
+ ret += NL;
+ return ret;
+ }
+ else
+ return string();
+ }
+
+};
+REGISTER_STEP_CONTENT(CActionRecvChargePoint, "recv_charge_point");
+
+
+// ---------------------------------------------------------------------------
+class CActionGiveOutpostControl : public IStepContent
+{
+ string _OutpostName;
+
+ void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
+ {
+ numEntry = 0;
+ }
+public:
+ void init(CMissionData &md, IPrimitive *prim)
+ {
+ IStepContent::init(md, prim);
+ _OutpostName = md.getProperty(prim, "outpost_name", true, false);
+ }
+
+ string genCode(CMissionData &md)
+ {
+ if (!_OutpostName.empty())
+ {
+ string ret;
+ ret = "give_control : "+_OutpostName;
+ ret += NL;
+ return ret;
+ }
+ else
+ return string();
+ }
+
+};
+REGISTER_STEP_CONTENT(CActionGiveOutpostControl, "give_control");
+
+
// ---------------------------------------------------------------------------
class CActionSpawnMission : public IStepContent
{
protected:
string _MissionName;
string _GiverName;
+ bool _Guild;
private:
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -186,17 +269,29 @@ public:
if (_GiverName.empty())
{
throw EParseException(prim, "giver_name is empty !");
- }
+ }
+
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
}
string genCode(CMissionData &md)
{
+ string ret = "";
if (!_MissionName.empty())
- return "spawn_mission : " + _MissionName + " : " + _GiverName + NL;
- else
- return string();
+ {
+ ret = "spawn_mission : " + _MissionName + " : " + _GiverName;
+ if (_Guild)
+ ret += " : guild";
+ ret += NL;
+ }
+ return ret;
}
-
};
REGISTER_STEP_CONTENT(CActionSpawnMission, "spawn_mission");
@@ -590,6 +685,7 @@ class CActionRecvFame : public IStepContent
{
string _Faction;
string _Fame;
+ bool _Guild;
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -602,12 +698,27 @@ public:
_Faction = md.getProperty(prim, "faction", true, false);
_Fame = md.getProperty(prim, "value", true, false);
+
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
}
string genCode(CMissionData &md)
{
if (!_Faction.empty() && !_Fame.empty())
- return string("recv_fame : ")+_Faction+" "+_Fame+NL;
+ {
+ string ret;
+ ret = "recv_fame : "+_Faction+" "+_Fame;
+ if (_Guild)
+ ret += ": guild";
+ ret += NL;
+ return ret;
+ }
else
return string();
}
@@ -628,6 +739,7 @@ class CActionRecvItem : public IStepContent
vector _Items;
bool _QualSpec;
bool _Group;
+ bool _Guild;
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -675,6 +787,13 @@ public:
s = md.getProperty(prim, "group", true, false);
_Group = (NLMISC::toLower(s) == "true");
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
IStepContent::init(md, prim);
}
@@ -693,6 +812,8 @@ public:
ret += " : "+_BotGiver;
if (_Group)
ret += " : group";
+ if (_Guild)
+ ret += ": guild";
ret += NL;
}
@@ -707,6 +828,7 @@ class CActionRecvNamedItem : public IStepContent
{
vector _Items;
bool _Group;
+ bool _Guild;
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -743,6 +865,14 @@ public:
s = md.getProperty(prim, "group", true, false);
_Group = (NLMISC::toLower(s) == "true");
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
+
IStepContent::init(md, prim);
}
@@ -756,6 +886,8 @@ public:
ret += "recv_named_item : "+item.ItemName+" "+item.ItemQuant;
if (_Group)
ret += " : group";
+ if (_Guild)
+ ret += ": guild";
ret += NL;
}
@@ -777,6 +909,7 @@ class CActionDestroyItem : public IStepContent
string _BotDestroyer;
vector _Items;
+ bool _Guild;
void getPredefParam(uint32 &numEntry, CPhrase::TPredefParams &predef)
{
@@ -821,6 +954,14 @@ public:
_Items.push_back(item);
}
}
+
+ _Guild = md.getProperty(prim, "guild", false, true) == "true";
+ // Check: if _Guild is true then check if we are in a guild mission
+ if (_Guild && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): 'guild' option true 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }
IStepContent::init(md, prim);
}
@@ -839,6 +980,8 @@ public:
ret +=" "+item.Desc.ItemQual;
if (!_BotDestroyer.empty())
ret += " : "+_BotDestroyer;
+ if (_Guild)
+ ret += ": guild";
ret += NL;
}
@@ -1630,6 +1773,20 @@ void CContentObjective::init(CMissionData &md, IPrimitive *prim)
_OverloadPhrase.initPhrase(md, prim, _OverloadObj, numEntry, params);
// init the roleplay phrase
_RoleplayPhrase.initPhrase(md, prim, _RoleplayObj, numEntry, params);
+
+ // check for the 'nb_guild_members_needed' option and see if it's correct for this mission
+ /*string nbGuildMembersNeeded = md.getProperty(prim, "nb_guild_members_needed", false, true);
+ if (nbGuildMembersNeeded.empty())
+ nbGuildMembersNeeded = "1";
+ if (!fromString(nbGuildMembersNeeded.c_str(), _NbGuildMembersNeeded))
+ _NbGuildMembersNeeded = 1;
+
+ // Check:
+ if (!md.isGuildMission() && _NbGuildMembersNeeded != 1)
+ {
+ string err = toString("primitive(%s): nb_guild_members_needed != 1 for non guild mission.", prim->getName().c_str());
+ throw EParseException(prim, err.c_str());
+ }*/
}
// ---------------------------------------------------------------------------
@@ -1649,6 +1806,20 @@ string CContentObjective::genCode(CMissionData &md)
return ret;
}
+// ---------------------------------------------------------------------------
+/*std::string CContentObjective::genNbGuildMembersNeededOption(CMissionData &md)
+{
+ string ret = "";
+ // If we are in a guild mission we add the 'nb_guild_members_needed' option to the script
+ if (md.isGuildMission())
+ {
+ ret = ": nb_guild_members_needed ";
+ ret += toString(_NbGuildMembersNeeded);
+ }
+
+ return ret;
+}*/
+
// ---------------------------------------------------------------------------
string CContentObjective::genPhrase()
{
@@ -1949,6 +2120,9 @@ public:
if (!_Place.empty())
ret += " : "+_Place;
+
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2004,6 +2178,8 @@ public:
if (!_Phrase.isEmpty())
ret += " : "+_Phrase.genScript(md);
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2078,6 +2254,8 @@ public:
{
ret += ": "+_Place;
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2151,6 +2329,8 @@ public:
if (i < _Mps.size()-1)
ret += "; ";
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2276,6 +2456,8 @@ public:
if (i < _Items.size()-1)
ret += "; ";
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2349,6 +2531,8 @@ public:
if (i < _Items.size()-1)
ret += "; ";
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2479,7 +2663,8 @@ public:
if (!_Place.empty())
ret += " : " + _Place;
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2564,6 +2749,8 @@ public:
{
ret += " : "+_Npc;
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2645,6 +2832,8 @@ public:
{
ret += " : "+_Npc;
}
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2755,7 +2944,10 @@ public:
if (i < _Items.size()-1)
ret += "; ";
};
- ret += " : "+_Npc +NL;
+ ret += " : "+_Npc;
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
+ ret += NL;
return ret;
}
@@ -2790,7 +2982,10 @@ public:
string ret;
ret = CContentObjective::genCode(md);
- ret += "give_money : "+_Amount+" : "+_Npc+NL;
+ ret += "give_money : "+_Amount+" : "+_Npc;
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
+ ret += NL;
return ret;
}
@@ -2841,7 +3036,8 @@ public:
ret += "; ";
}
}
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2877,7 +3073,8 @@ public:
if (_SaveAll)
ret += " : save_all";
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2950,7 +3147,8 @@ public:
if (i < _Skills.size()-1)
ret += "; ";
}
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -2968,9 +3166,12 @@ class CContentMission: public CContentObjective
}
public:
+ CContentMission(): _Prim(0) {}
+
void init(CMissionData &md, IPrimitive *prim)
{
_Missions = md.getPropertyArray(prim, "mission_names", true, false);
+ _Prim = prim;
CContentObjective::init(md, prim);
}
@@ -2987,12 +3188,23 @@ public:
ret += _Missions[i];
if (i < _Missions.size()-1)
ret += "; ";
- }
+ // We check to see if we specified a number after the mission name. If so, we check if it's a guild mission
+ std::size_t pos = _Missions[i].find_first_of(" \t");
+ if (pos != std::string::npos && !md.isGuildMission())
+ {
+ string err = toString("primitive(%s): CContentMission: Number of members needed to complete the mission specified but the mission is not a guild mission.", _Prim->getName().c_str());
+ throw EParseException(_Prim, err.c_str());
+ }
+ }
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
}
+
+ IPrimitive *_Prim;
};
REGISTER_STEP_CONTENT(CContentMission, "do_mission");
@@ -3026,7 +3238,8 @@ public:
if (i < _MsgContent.size()-1)
ret += " ";
}
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;
@@ -3242,7 +3455,8 @@ public:
ret += "ring_scenario : ";
ret += _ScenarioTag;
-
+ // Add the 'nb_guild_members_needed' parameter if needed
+ //ret += CContentObjective::genNbGuildMembersNeededOption(md);
ret += NL;
return ret;