Changed: Merge changes from next patch

This commit is contained in:
kervala 2011-05-31 21:51:26 +02:00
parent 4b4c3b9a56
commit 7ecd6513a5
43 changed files with 2325 additions and 132 deletions

View file

@ -9006,6 +9006,14 @@ void CCharacterCL::setAuraFX(uint index, const CAnimationFX *sheet)
if (sheet == NULL) if (sheet == NULL)
{ {
std::list<CAttachedFX::CBuildInfo>::iterator itAttachedFxToStart = _AttachedFXListToStart.begin();
while(itAttachedFxToStart != _AttachedFXListToStart.end())
{
if ((*itAttachedFxToStart).MaxNumAnimCount == index)
itAttachedFxToStart = _AttachedFXListToStart.erase(itAttachedFxToStart);
else
++itAttachedFxToStart;
}
// if there's already an aura attached, and if it is not already shutting down // if there's already an aura attached, and if it is not already shutting down
if (_AuraFX[index] && _AuraFX[index]->TimeOutDate == 0.f) if (_AuraFX[index] && _AuraFX[index]->TimeOutDate == 0.f)
{ {

View file

@ -2497,7 +2497,9 @@ class CAHAddShape : public IActionHandler
{ {
shape = sShape.substr(0, index); shape = sShape.substr(0, index);
sShape = sShape.substr(index+1); sShape = sShape.substr(index+1);
} else { }
else
{
shape = sShape; shape = sShape;
have_shapes = false; have_shapes = false;
} }

View file

@ -2052,7 +2052,8 @@ void getItemText (CDBCtrlSheet *item, ucstring &itemText, const CItemSheet*pIS)
case ITEMFAMILY::CONSUMABLE : case ITEMFAMILY::CONSUMABLE :
{ {
strFindReplace(itemText, "%consumption_time", toString(pIS->Consumable.ConsumptionTime)); strFindReplace(itemText, "%consumption_time", toString(pIS->Consumable.ConsumptionTime));
strFindReplace(itemText, "%overdose_timer", toString(pIS->Consumable.OverdoseTimer/60)); strFindReplace(itemText, "%overdose_timer_min", toString(pIS->Consumable.OverdoseTimer/60));
strFindReplace(itemText, "%overdose_timer_sec", toString(pIS->Consumable.OverdoseTimer % 60));
// Get Item Consumable infos // Get Item Consumable infos
CItemConsumableEffectHelper::getInstance()->getItemConsumableEffectText(pIS, itemText, item->getQuality()); CItemConsumableEffectHelper::getInstance()->getItemConsumableEffectText(pIS, itemText, item->getQuality());
} }

View file

@ -2095,13 +2095,13 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, armourCol); rVR.draw11RotFlipBitmap (_RenderLayer, x, y, 0, false, _DispOverBmpId, armourCol);
// decal layer because must drawn after Items/Brick in DXTC // decal layer because must drawn after Items/Brick in DXTC
// NB: use OverColor, not Over2Color here. Because of hack in updateArmourColor() // NB: use OverColor, not Over2Color here. Because of hack in updateArmourColor()
rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor)); rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOverColor));
} }
else else
{ {
// decal layer because must drawn after Items/Brick in DXTC // decal layer because must drawn after Items/Brick in DXTC
rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor)); rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOverBmpId, fastMulRGB(curSheetColor, _IconOverColor));
rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color)); rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
} }
// Draw Quality. -1 for lookandfeel. Draw it with global color // Draw Quality. -1 for lookandfeel. Draw it with global color

View file

@ -871,6 +871,13 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c
{ {
_TextColor.push_back(_TextColor.empty() ? CRGBA::White : _TextColor.back()); _TextColor.push_back(_TextColor.empty() ? CRGBA::White : _TextColor.back());
} }
if (present[HTML_FONT_SIZE] && value[HTML_FONT_SIZE])
{
uint fontsize;
fromString(value[HTML_FONT_SIZE], fontsize);
_FontSize.push_back(fontsize);
}
} }
break; break;
case HTML_BR: case HTML_BR:
@ -1407,6 +1414,7 @@ void CGroupHTML::endElement (uint element_number)
{ {
case HTML_FONT: case HTML_FONT:
popIfNotEmpty (_TextColor); popIfNotEmpty (_TextColor);
popIfNotEmpty (_FontSize);
break; break;
case HTML_A: case HTML_A:
popIfNotEmpty (_TextColor); popIfNotEmpty (_TextColor);
@ -2251,8 +2259,9 @@ void CGroupHTML::addImage(const char *img, bool globalColor)
else*/ else*/
getParagraph()->addChild(newImage); getParagraph()->addChild(newImage);
paragraphChange (); paragraphChange ();
} else { }
else
{
// //
// 2/ if it doesn't work, try to load the image in cache // 2/ if it doesn't work, try to load the image in cache
// //
@ -3394,7 +3403,8 @@ int CGroupHTML::luaInsertText(CLuaState &ls)
ucstring text; ucstring text;
text.fromUtf8(ls.toString(2)); text.fromUtf8(ls.toString(2));
if (!_Forms.empty()) { if (!_Forms.empty())
{
for (uint i=0; i<_Forms.back().Entries.size(); i++) for (uint i=0; i<_Forms.back().Entries.size(); i++)
{ {
if (_Forms.back().Entries[i].TextArea && _Forms.back().Entries[i].Name == name) if (_Forms.back().Entries[i].TextArea && _Forms.back().Entries[i].Name == name)
@ -3438,11 +3448,14 @@ int CGroupHTML::luaAddImage(CLuaState &ls)
paragraphChange(); paragraphChange();
} }
string url = getLink(); string url = getLink();
if (!url.empty()) { if (!url.empty())
{
string params = "name=" + getId() + "|url=" + getLink (); string params = "name=" + getId() + "|url=" + getLink ();
addButton(CCtrlButton::PushButton, ls.toString(1), ls.toString(1), ls.toString(1), addButton(CCtrlButton::PushButton, ls.toString(1), ls.toString(1), ls.toString(1),
"", ls.toBoolean(2), "browse", params.c_str(), ""); "", ls.toBoolean(2), "browse", params.c_str(), "");
} else { }
else
{
addImage(ls.toString(1), ls.toBoolean(2)); addImage(ls.toString(1), ls.toBoolean(2));
} }

View file

@ -277,7 +277,7 @@ string CGroupHTMLWebIG::home ()
void CGroupHTMLWebIG::handle () void CGroupHTMLWebIG::handle ()
{ {
Home = "http://atys.ryzom.com/start/index.php"; // Home = "http://atys.ryzom.com/start/index.php";
CGroupHTML::handle (); CGroupHTML::handle ();
} }

View file

@ -133,8 +133,8 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet *
strFindReplace(result, "%minutes", toString(duration/60)); strFindReplace(result, "%minutes", toString(duration/60));
strFindReplace(result, "%secondes", toString(duration%60)); strFindReplace(result, "%secondes", toString(duration%60));
strFindReplace(result, "%radius", toString(radius)); strFindReplace(result, "%radius", toString(radius));
strFindReplace(result, "%targetDisableTime", toString(targetDisableTime)); strFindReplace(result, "%targetDisableTime", "0");
strFindReplace(result, "%userDisableTime", toString(userDisableTime)); strFindReplace(result, "%userDisableTime", "0");
effects += result; effects += result;
effects += "\n"; effects += "\n";
@ -183,12 +183,12 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet *
fromString(params[4].c_str(), userDisableTime); fromString(params[4].c_str(), userDisableTime);
ucstring result = CI18N::get("uiItemConsumableEffectStaminaAura"); ucstring result = CI18N::get("uiItemConsumableEffectStaminaAura");
strFindReplace(result, "%modifier", toString(regenMod)); strFindReplace(result, "%modifier", toString(bonus));
strFindReplace(result, "%minutes", toString(duration/60)); strFindReplace(result, "%minutes", toString(duration/60));
strFindReplace(result, "%secondes", toString(duration%60)); strFindReplace(result, "%secondes", toString(duration%60));
strFindReplace(result, "%radius", toString(radius)); strFindReplace(result, "%radius", toString(radius));
strFindReplace(result, "%targetDisableTime", toString(targetDisableTime)); strFindReplace(result, "%targetDisableTime", "0");
strFindReplace(result, "%userDisableTime", toString(userDisableTime)); strFindReplace(result, "%userDisableTime", "0");
effects += result; effects += result;
effects += "\n"; effects += "\n";
@ -240,8 +240,8 @@ void CItemConsumableEffectHelper::getItemConsumableEffectText(const CItemSheet *
strFindReplace(result, "%minutes", toString(duration/60)); strFindReplace(result, "%minutes", toString(duration/60));
strFindReplace(result, "%secondes", toString(duration%60)); strFindReplace(result, "%secondes", toString(duration%60));
strFindReplace(result, "%radius", toString(radius)); strFindReplace(result, "%radius", toString(radius));
strFindReplace(result, "%targetDisableTime", toString(targetDisableTime)); strFindReplace(result, "%targetDisableTime", "0");
strFindReplace(result, "%userDisableTime", toString(userDisableTime)); strFindReplace(result, "%userDisableTime", "0");
effects += result; effects += result;
effects += "\n"; effects += "\n";

View file

@ -503,7 +503,6 @@ void CSPhraseManager::updateMemoryDBAll()
for(uint i=0;i<PHRASE_MAX_MEMORY_SLOT;i++) for(uint i=0;i<PHRASE_MAX_MEMORY_SLOT;i++)
{ {
_MemoryDbLeaves[i]->setValue32(0); _MemoryDbLeaves[i]->setValue32(0);
_MemoryAltDbLeaves[i]->setValue32(0);
} }
} }
else else
@ -515,7 +514,14 @@ void CSPhraseManager::updateMemoryDBAll()
_MemoryDbLeaves[i]->setValue32(0); _MemoryDbLeaves[i]->setValue32(0);
else else
_MemoryDbLeaves[i]->setValue32(slot.Id); _MemoryDbLeaves[i]->setValue32(slot.Id);
}
}
if(_SelectedMemoryDB != -1 && (sint32)_Memories.size() > 0)
{
// Always update alt gestionsets
for(uint i=0;i<PHRASE_MAX_MEMORY_SLOT;i++)
{
CMemorySlot &slotAlt= _Memories[0].Slot[i]; CMemorySlot &slotAlt= _Memories[0].Slot[i];
if(!slotAlt.isPhrase()) if(!slotAlt.isPhrase())
_MemoryAltDbLeaves[i]->setValue32(0); _MemoryAltDbLeaves[i]->setValue32(0);

View file

@ -15,10 +15,10 @@ addSkillPoints :DEV:SGM:GM:EM: // Add skill points of given type (Fight=0, M
addXPToSkill :DEV:SGM:GM:EM: // Gain experience in the given skill: <xp> <skill> [<count>] addXPToSkill :DEV:SGM:GM:EM: // Gain experience in the given skill: <xp> <skill> [<count>]
broadcast :DEV:SGM:GM:EM:VG: // Broadcast a message: [repeat=<num repeat> or during=<time in seconds>] [every=<delay in secondes>] <message> broadcast :DEV:SGM:GM:EM:VG: // Broadcast a message: [repeat=<num repeat> or during=<time in seconds>] [every=<delay in secondes>] <message>
changeHairCut :DEV:SGM:GM:EM: // Change the haircut of a player: <sheet name> changeHairCut :DEV:SGM:GM:EM: // Change the haircut of a player: <sheet name>
changeMode :DEV:SGM:GM: // Change mode of a player: <mode> changeMode :DEV:SGM:GM:EM: // Change mode of a player: <mode>
changeVar :DEV:SGM:GM: // Change a variable of a player: <var> <val> changeVar :DEV:SGM:GM:EM: // Change a variable of a player: <var> <val>
checkTargetSP :DEV:SGM:GM: // Check target player skill points checkTargetSP :DEV:SGM:GM: // Check target player skill points
clearEventFaction :DEV:SGM:GM: // Clear the event faction of player: <player name> clearEventFaction :DEV:SGM:GM:EM: // Clear the event faction of player: <player name>
clearFriendsList :DEV:SGM:GM: // Clear the friend list of a player clearFriendsList :DEV:SGM:GM: // Clear the friend list of a player
clearGuildMessage // Clear the guild message of the day clearGuildMessage // Clear the guild message of the day
clearIgnoreList :DEV:SGM:GM: // Clear the ignore list of a player clearIgnoreList :DEV:SGM:GM: // Clear the ignore list of a player
@ -36,8 +36,8 @@ dodge // Set the defense mode to dodge
execPhrase :DEV:SGM:GM: // Execute a phrase with given bricks: <cyclic 0/1> [<brick ids>...] execPhrase :DEV:SGM:GM: // Execute a phrase with given bricks: <cyclic 0/1> [<brick ids>...]
executeSabrinaPhrase :DEV:SGM:GM: // Execute a sabrina phrase: <cyclic 0/1> <phraseId> executeSabrinaPhrase :DEV:SGM:GM: // Execute a sabrina phrase: <cyclic 0/1> <phraseId>
failMission :DEV:SGM:GM: // Force mission failure: <mission idx> failMission :DEV:SGM:GM: // Force mission failure: <mission idx>
forceTargetToDie :DEV:SGM:GM: // Force entity target to die forceTargetToDie :DEV:SGM:GM:EM: // Force entity target to die
getEventFaction :DEV:SGM:GM: // Get the event faction of player: <player name> getEventFaction :DEV:SGM:GM:EM: // Get the event faction of player: <player name>
giveRespawnPoint :DEV:SGM:GM: // Give a respawn point to a player: <respawn point name> giveRespawnPoint :DEV:SGM:GM: // Give a respawn point to a player: <respawn point name>
guildInvite // Send a guild invite to a player character without distance constrainte guildInvite // Send a guild invite to a player character without distance constrainte
roomInvite // Send a room invite roomInvite // Send a room invite
@ -59,7 +59,7 @@ loadFromXML :DEV:SGM: // Load a character from an XML file: <file name>
logXpGain :DEV:SGM:GM: // Log or not xp gain infos for specified player: <on/off> logXpGain :DEV:SGM:GM: // Log or not xp gain infos for specified player: <on/off>
lPosFlags :DEV:SGM:GM:VG:SG:G:EM:EG: // List position flags (short format): [<radius in meters>] lPosFlags :DEV:SGM:GM:VG:SG:G:EM:EG: // List position flags (short format): [<radius in meters>]
monitorMissions :DEV:SGM:GM: // Monitor missions of the given player: <player name> monitorMissions :DEV:SGM:GM: // Monitor missions of the given player: <player name>
motd :DEV:SGM:GM:VG: // Set the current message of the day: <message to be displayed> motd :DEV:SGM:GM:EM:VG: // Set the current message of the day: <message to be displayed>
mute :DEV:SGM:GM:EM:VG:SG: // Mute a user: <player name> <duration> mute :DEV:SGM:GM:EM:VG:SG: // Mute a user: <player name> <duration>
muteUniverse :DEV:SGM:GM:EM:VG:SG: // Mute the universe channel: <duration> muteUniverse :DEV:SGM:GM:EM:VG:SG: // Mute the universe channel: <duration>
outpostBanGuild :DEV:SGM:GM:EM: // Ban a guild for an outpost conflit: <outpost_id> <guild_name> [<all|atk|def>] outpostBanGuild :DEV:SGM:GM:EM: // Ban a guild for an outpost conflit: <outpost_id> <guild_name> [<all|atk|def>]
@ -70,14 +70,14 @@ parry // Set the defense mode to parry
progressMission :DEV:SGM:GM: // Force mission progression: <mission idx> [repeat] progressMission :DEV:SGM:GM: // Force mission progression: <mission idx> [repeat]
renameGuild :DEV:SGM:GM:EM: // Rename a guild: <guild name> <new guild name> renameGuild :DEV:SGM:GM:EM: // Rename a guild: <guild name> <new guild name>
renamePlayer [SU] :DEV:SGM:GM:EM: // Rename a player: <player name> <new playerName> renamePlayer [SU] :DEV:SGM:GM:EM: // Rename a player: <player name> <new playerName>
renamePlayerForEvent :DEV:SGM:EM:EG: // Rename a player temporarily for an event: <player name> <new playerName> renamePlayerForEvent :DEV:SGM:GM:EM:EG: // Rename a player temporarily for an event: <player name> <new playerName>
resetPowerFlags :DEV:SGM:GM: // Reset the ineffective aura and the power flags for given character resetPowerFlags :DEV:SGM:GM:EM: // Reset the ineffective aura and the power flags for given character
respawnAfterDeath // Respawn after death at re-spawn point name, it must be valid (validated by PC and usable): <Respawn idx> respawnAfterDeath // Respawn after death at re-spawn point name, it must be valid (validated by PC and usable): <Respawn idx>
resurrected // Another PC resurrect PC by giving some energy: <Hp> <Sta> <Sap> <Focus> resurrected // Another PC resurrect PC by giving some energy: <Hp> <Sta> <Sap> <Focus>
root :DEV:SGM:GM:EM:VG:SG: // Root a player: <player name> <time in seconds> root :DEV:SGM:GM:EM:VG:SG: // Root a player: <player name> <time in seconds>
saveToPDR :DEV:SGM: // Save a character to a binary PDR file: <file name> saveToPDR :DEV:SGM: // Save a character to a binary PDR file: <file name>
saveToXML :DEV:SGM: // Save a character to an XML file: <file name> saveToXML :DEV:SGM: // Save a character to an XML file: <file name>
setEventFaction :DEV:SGM:GM: // Set the event faction of player: <player name> <event faction> setEventFaction :DEV:SGM:GM:EM: // Set the event faction of player: <player name> <event faction>
setGMGuild :DEV:SGM:GM: // Set the current GM guild setGMGuild :DEV:SGM:GM: // Set the current GM guild
setGuildChargePoint :DEV:SGM:GM:EM: // Set the charge points of a guild: <guild name> <points> setGuildChargePoint :DEV:SGM:GM:EM: // Set the charge points of a guild: <guild name> <points>
setGuildDescription :DEV:SGM:GM:EM: // Set a guild description: <guild name> <new guild description> setGuildDescription :DEV:SGM:GM:EM: // Set a guild description: <guild name> <new guild description>
@ -90,13 +90,16 @@ setPvPTag // Set player character PvP tag to true or false
setSkillsToMaxValue :DEV:SGM:GM:EM: // Set player skills to max value setSkillsToMaxValue :DEV:SGM:GM:EM: // Set player skills to max value
showCSR :DEV:SGM:GM:VG:SG:G:EM:EG: // Show CSR title if the player is a CSR showCSR :DEV:SGM:GM:VG:SG:G:EM:EG: // Show CSR title if the player is a CSR
showFBT :DEV:SGM:GM:EM: // Show Focus Beta Tester title if the player is a FBT showFBT :DEV:SGM:GM:EM: // Show Focus Beta Tester title if the player is a FBT
startEvent :DEV:SGM:GM: // Start an event with the given name: <event name> startEvent :DEV:SGM:GM:EM: // Start an event with the given name: <event name>
stopEvent :DEV:SGM:GM:EM: // Stop previous started event stopEvent :DEV:SGM:GM:EM: // Stop previous started event
stopMonitorMissions :DEV:SGM:GM: // Stop monitoring missions of the given player stopMonitorMissions :DEV:SGM:GM: // Stop monitoring missions of the given player
summon :DEV:SGM:GM:VG:SG:EM: // Summon a player in front of the CSR: <player name> summon :DEV:SGM:GM:VG:SG:EM: // Summon a player in front of the CSR: <player name>
targetInfos :DEV:SGM:GM:EM: // Give infos on the target targetInfos :DEV:SGM:GM:EM: // Give infos on the target
teamInvite // Send a team invite to a player character teamInvite // Send a team invite to a player character
connectUserChannel // Connect to User Channel Chat connectUserChannel // Connect to User Channel Chat
webExecCommand // Execute web command (need HMAC signature)
webDelCommandsIds // Delete web transactions for web_app
webAddCommandsIds // Add web command transactions for web_app
teleport :DEV:SGM:GM:VG:SG:G:OBSERVER:EM:EG: // Teleport the CSR in front of a player: <player name> teleport :DEV:SGM:GM:VG:SG:G:OBSERVER:EM:EG: // Teleport the CSR in front of a player: <player name>
tpPosFlag :DEV:SGM:GM:VG:SG:G:EM:EG: // Teleport a player to a position flag: <flag name> tpPosFlag :DEV:SGM:GM:VG:SG:G:EM:EG: // Teleport a player to a position flag: <flag name>
universe :DEV:SGM:GM:EM: // Chat in universe mode: <boolean> universe :DEV:SGM:GM:EM: // Chat in universe mode: <boolean>
@ -113,8 +116,8 @@ addFactionAttackableToTarget :DEV: // add attackable possibility for player o
forceMissionProgress :DEV: // force mission step progression (for debug purpose only) forceMissionProgress :DEV: // force mission step progression (for debug purpose only)
savePlayerActiveChar :DEV:SGM: // save immediatly a player active char, a specific filename can enter for backup a character in specific situation/context savePlayerActiveChar :DEV:SGM: // save immediatly a player active char, a specific filename can enter for backup a character in specific situation/context
reloadPlayer :DEV:SGM: // set next filename used for loading a character (must be offline and log later) or relaod an online character to previous backup or with a specified filename. reloadPlayer :DEV:SGM: // set next filename used for loading a character (must be offline and log later) or relaod an online character to previous backup or with a specified filename.
farTPPush :DEV:SGM:GM:VG:SG: // used to tp on a specific session farTPPush :DEV:SGM:GM:VG:SG:EM: // used to tp on a specific session
farTPReturn :DEV:SGM:GM:VG:SG: // used to tp back to your previous session farTPReturn :DEV:SGM:GM:VG:SG:EM: // used to tp back to your previous session
characterMissionDump :DEV:SGM:GM: //Dump mission list for a character characterMissionDump :DEV:SGM:GM: //Dump mission list for a character
removeMission :DEV:SGM:GM: //Remove a mission of a character removeMission :DEV:SGM:GM: //Remove a mission of a character
addMission :DEV:SGM:GM: //add a mission to a character addMission :DEV:SGM:GM: //add a mission to a character
@ -135,11 +138,12 @@ Name :DEV:SGM:GM:EM: // Name of a player
Position :DEV:SGM:GM:VG:PR:OBSERVER:EM:EG: // Position of a player (in meters) <posx>,<posy>[,<posz>]] | <bot name> | <player name> | home Position :DEV:SGM:GM:VG:PR:OBSERVER:EM:EG: // Position of a player (in meters) <posx>,<posy>[,<posz>]] | <bot name> | <player name> | home
Priv :DEV: // User privilege Priv :DEV: // User privilege
PriviledgePVP :DEV:SGM:GM:EM:EG: // Turns PVP on/off on character (blame coder for typo) PriviledgePVP :DEV:SGM:GM:EM:EG: // Turns PVP on/off on character (blame coder for typo)
RyzomDate :DEV:SGM:GM: // Current ryzom date RyzomDate :DEV:SGM:GM:EM: // Current ryzom date
RyzomTime :DEV:SGM:GM: // Current ryzom time RyzomTime :DEV:SGM:GM:EM: // Current ryzom time
// Event commands // Event commands
eventCreateNpcGroup :DEV:SGM:GM:EM: // Create a npc group eventCreateNpcGroup :DEV:SGM:GM:EM: // Create a npc group
eScript :DEV:SGM:GM:EM: // Execute a script on an event npc group (new version)
eventNpcGroupScript :DEV:SGM:GM:EM: // Execute a script on an event npc group eventNpcGroupScript :DEV:SGM:GM:EM: // Execute a script on an event npc group
eventSetBotName :DEV:SGM:GM:EM: // Set the name of a bot eventSetBotName :DEV:SGM:GM:EM: // Set the name of a bot
eventSetBotScale :DEV:SGM:GM:EM: // Set the scale of a bot eventSetBotScale :DEV:SGM:GM:EM: // Set the scale of a bot
@ -155,3 +159,4 @@ eventSetBotFaction :DEV:SGM:GM:EM: // Changes the faction of a bot: <faction
eventSetBotFameByKill :DEV:SGM:GM:EM: // Changes the amount of fame earned for bot faction when killing it: <fame value> eventSetBotFameByKill :DEV:SGM:GM:EM: // Changes the amount of fame earned for bot faction when killing it: <fame value>
eventSetBotURL :DEV:SGM:GM:EM: // Set the url of a bot eventSetBotURL :DEV:SGM:GM:EM: // Set the url of a bot
eventSetBotURLName :DEV:SGM:GM:EM: // Set the url name of a bot eventSetBotURLName :DEV:SGM:GM:EM: // Set the url name of a bot
eventSpawnToxic :DEV:SGM:GM:EM: // Add toxic cloud

View file

@ -68,6 +68,9 @@ CAIInstance::~CAIInstance()
static bool zoneHaveError = false; static bool zoneHaveError = false;
/// map of lastCreatedNpcGroup by player id
static std::map<CEntityId, string> _PlayersLastCreatedNpcGroup;
void CAIInstance::addZone(string const& zoneName, CNpcZone* zone) void CAIInstance::addZone(string const& zoneName, CNpcZone* zone)
{ {
#if !FINAL_VERSION #if !FINAL_VERSION
@ -850,12 +853,14 @@ void cbEventCreateNpcGroup( NLNET::CMessage& msgin, const std::string &serviceNa
sint32 orientation; sint32 orientation;
uint32 nbBots; uint32 nbBots;
NLMISC::CSheetId sheetId; NLMISC::CSheetId sheetId;
CEntityId playerId;
double dispersionRadius; double dispersionRadius;
bool spawnBots; bool spawnBots;
std::string botsName; std::string botsName;
msgin.serial(messageVersion); msgin.serial(messageVersion);
nlassert(messageVersion==1); nlassert(messageVersion==1);
msgin.serial(instanceNumber); msgin.serial(instanceNumber);
msgin.serial(playerId);
msgin.serial(x); msgin.serial(x);
msgin.serial(y); msgin.serial(y);
msgin.serial(orientation); msgin.serial(orientation);
@ -867,7 +872,11 @@ void cbEventCreateNpcGroup( NLNET::CMessage& msgin, const std::string &serviceNa
CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber); CAIInstance* instance = CAIS::instance().getAIInstance(instanceNumber);
if (instance) if (instance)
{ {
instance->eventCreateNpcGroup(nbBots, sheetId, CAIVector((double)x/1000., (double)y/1000.), dispersionRadius, spawnBots, (double)orientation/1000., botsName); CGroupNpc* npcGroup = instance->eventCreateNpcGroup(nbBots, sheetId, CAIVector((double)x/1000., (double)y/1000.), dispersionRadius, spawnBots, (double)orientation/1000., botsName);
if (npcGroup != NULL)
{
_PlayersLastCreatedNpcGroup[playerId] = npcGroup->getName();
}
} }
} }
@ -882,12 +891,56 @@ void cbEventNpcGroupScript( NLNET::CMessage& msgin, const std::string &serviceNa
msgin.serial(messageVersion); msgin.serial(messageVersion);
nlassert(messageVersion==1); nlassert(messageVersion==1);
msgin.serial(nbString); msgin.serial(nbString);
strings.resize(nbString);
nlinfo("Event group script with %d strings", nbString); string eid;
for (uint32 i=0; i<nbString; ++i) string firstCommand;
msgin.serial(eid); // Player or boteid
msgin.serial(firstCommand); // Player or boteid
if (firstCommand[0] == '(') // Old eventNpcGroupScript command : (boteid, commands...)
{ {
msgin.serial(strings[i]); nlinfo("Event group script with %d strings :", nbString);
nlinfo(" %d '%s'", i, strings[i].c_str()); strings.resize(nbString);
strings[0] = eid;
nlinfo(" %d '%s'", 0, strings[0].c_str());
strings[1] = firstCommand;
nlinfo(" %d '%s'", 1, strings[1].c_str());
for (uint32 i=2; i<nbString-2; ++i)
{
msgin.serial(strings[i]);
nlinfo(" %d '%s'", i, strings[i].c_str());
}
}
else
{
nlinfo("Event group script with %d strings :", nbString-1);
CEntityId playerId(eid);
strings.resize(nbString-1);
NLMISC::CSString groupname = CSString(firstCommand);
if (firstCommand[0] == '#' && firstCommand[1] == '(')
{
NLMISC::CEntityId botEId = NLMISC::CEntityId(firstCommand.substr(1));
if (botEId==NLMISC::CEntityId::Unknown)
return;
CAIEntityPhysical* entity = CAIEntityPhysicalLocator::getInstance()->getEntity(botEId);
CSpawnBotNpc* bot = dynamic_cast<CSpawnBotNpc*>(entity);
if (!bot)
return;
if (!bot->getPersistent().getOwner())
return;
strings[0] = bot->getPersistent().getOwner()->getName();
}
else
{
strings[0] = (string)groupname.replace("#last", _PlayersLastCreatedNpcGroup[playerId].c_str());
}
nlinfo(" %d '%s'", 0, strings[0].c_str());
for (uint32 i=1; i<nbString-1; ++i)
{
msgin.serial(strings[i]);
nlinfo(" %d '%s'", i, strings[i].c_str());
}
} }
scriptCommands2.push_back(strings); scriptCommands2.push_back(strings);
} }

View file

@ -4421,14 +4421,20 @@ void getCurrentSpeakerEid__s(CStateInstance* entity, CScriptStack& stack)
return; return;
} }
//////////////////////////////////////////////////////////////////////////////
// Undocumented methods //
//////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// CGroup /** @page code
@subsection setSheet_s_
Change the sheet of a creature
Arguments: -> s(sheetName)
@code
()setSheet('ccdeb2');
@endcode
*/
void setSheet_s_(CStateInstance* entity, CScriptStack& stack) void setSheet_s_(CStateInstance* entity, CScriptStack& stack)
{ {
string sheetname = stack.top(); string sheetname = stack.top();
@ -4450,8 +4456,23 @@ void setSheet_s_(CStateInstance* entity, CScriptStack& stack)
} }
} }
/****************************************************************************/
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// CGroup /** @page code
@subsection setHealer_f_
Make the group healer (need test)
Arguments: -> f(isHealer)
@code
()setHealer(1);
@endcode
*/
void setHealer_f_(CStateInstance* entity, CScriptStack& stack) void setHealer_f_(CStateInstance* entity, CScriptStack& stack)
{ {
bool value = ((float)stack.top())!=0.f; bool value = ((float)stack.top())!=0.f;

View file

@ -295,6 +295,7 @@ void setActivity_s_(CStateInstance* entity, CScriptStack& stack)
spawnGroup->activityProfile().setAIProfile(new CGrpProfileBandit(spawnGroup)); spawnGroup->activityProfile().setAIProfile(new CGrpProfileBandit(spawnGroup));
break; break;
} }
nlwarning("trying to set activity profile to an unknown profile name"); nlwarning("trying to set activity profile to an unknown profile name");
} }
} }
@ -402,6 +403,106 @@ void stopMoving__(CStateInstance* entity, CScriptStack& stack)
spawnGroup->movingProfile().setAIProfile(new CGrpProfileIdle(spawnGroup)); spawnGroup->movingProfile().setAIProfile(new CGrpProfileIdle(spawnGroup));
} }
//----------------------------------------------------------------------------
/** @page code
@subsection startWander_f_
Set activity to wander in current pos:
Arguments: f(Radius) ->
@param[in] Radius dispersion of wander activity
@code
()startWander(100); // Gives a wander activity to the group with dispersion of 100
@endcode
*/
// Spawned CGroupNpc not in a family behaviour
void startWander_f_(CStateInstance* entity, CScriptStack& stack)
{
uint32 dispersionRadius = (uint32)(float&)stack.top();
stack.pop();
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
if (!aiInstance)
return;
if (!entity) { nlwarning("setActivity failed!"); return; }
CGroupNpc* group = dynamic_cast<CGroupNpc*>(entity->getGroup());
if (!group)
{ nlwarning("startWander failed: no NPC group");
return;
}
CSpawnGroupNpc* spawnGroup = group->getSpawnObj();
if (!spawnGroup)
{ nlwarning("startWander failed: no spawned group");
return;
}
CAIVector centerPos;
if (!spawnGroup->calcCenterPos(centerPos)) // true if there's some bots in the group.
{ nlwarning("startWander failed: no center pos");
return;
}
NLMISC::CSmartPtr<CNpcZonePlaceNoPrim> destZone = NLMISC::CSmartPtr<CNpcZonePlaceNoPrim>(new CNpcZonePlaceNoPrim());
destZone->setPosAndRadius(AITYPES::vp_auto, CAIPos(centerPos, 0, 0), (uint32)(dispersionRadius*1000.));
spawnGroup->movingProfile().setAIProfile(new CGrpProfileWanderNoPrim(spawnGroup, destZone));
}
//----------------------------------------------------------------------------
/** @page code
@subsection startMoving_fff_
Set activity to wander in current pos:
Arguments: f(Radius) ->
@param[in] Radius dispersion of wander activity
@code
()startWander(100); // Gives a wander activity to the group with dispersion of 100
@endcode
*/
// Spawned CGroupNpc not in a family behaviour
void startMoving_fff_(CStateInstance* entity, CScriptStack& stack)
{
uint32 dispersionRadius = (uint32)(float&)stack.top();
stack.pop();
float const y = (float&)stack.top();
stack.pop();
float const x = (float&)stack.top();
stack.pop();
IManagerParent* const managerParent = entity->getGroup()->getOwner()->getOwner();
CAIInstance* const aiInstance = dynamic_cast<CAIInstance*>(managerParent);
if (!aiInstance)
return;
if (!entity) { nlwarning("setActivity failed!"); return; }
CGroupNpc* group = dynamic_cast<CGroupNpc*>(entity->getGroup());
if (!group)
{ nlwarning("setActivity failed: no NPC group");
return;
}
CSpawnGroupNpc* spawnGroup = group->getSpawnObj();
if (!spawnGroup)
{ nlwarning("setActivity failed: no spawned group");
return;
}
NLMISC::CSmartPtr<CNpcZonePlaceNoPrim> destZone = NLMISC::CSmartPtr<CNpcZonePlaceNoPrim>(new CNpcZonePlaceNoPrim());
destZone->setPosAndRadius(AITYPES::vp_auto, CAIPos(CAIVector(x, y), 0, 0), (uint32)(dispersionRadius*1000.));
spawnGroup->movingProfile().setAIProfile(new CGrpProfileWanderNoPrim(spawnGroup, destZone));
return;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** @page code /** @page code
@ -2284,7 +2385,7 @@ void emote_css_(CStateInstance* entity, CScriptStack& stack)
//CBot& bot = spawnBot->getPersistent(); //CBot& bot = spawnBot->getPersistent();
// The entity Id must be valid (whe know that the bot is alive so its entity Id must be ok) // The entity Id must be valid (we know that the bot is alive so its entity Id must be ok)
NLMISC::CEntityId entityId=spawnBot->getEntityId(); NLMISC::CEntityId entityId=spawnBot->getEntityId();
if (entityId == NLMISC::CEntityId::Unknown) if (entityId == NLMISC::CEntityId::Unknown)
{ {
@ -2342,6 +2443,105 @@ void emote_ss_(CStateInstance* entity, CScriptStack& stack)
NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout ); NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout );
} }
void emote_s_(CStateInstance* entity, CScriptStack& stack)
{
string emoteName = (string)stack.top(); stack.pop();
// Is the emote valid
uint32 emoteId = CAIS::instance().getEmotNumber(emoteName);
if (emoteId == ~0)
return;
// Get the behaviour Id
MBEHAV::EBehaviour behaviourId = (MBEHAV::EBehaviour)(emoteId + MBEHAV::EMOTE_BEGIN);
CGroup* group = entity->getGroup();
if (group->isSpawned())
{
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBot* bot = *itBot;
if (bot)
{
// Change the behaviour
if (bot->isSpawned())
{
CSpawnBot *spawnBot = bot->getSpawnObj();
if (spawnBot)
{
CEntityId botId = spawnBot->getEntityId();
NLNET::CMessage msgout("SET_BEHAVIOUR");
msgout.serial(botId);
MBEHAV::CBehaviour bh(behaviourId);
bh.Data = (uint16)(CTimeInterface::gameCycle());
msgout.serial(bh);
NLNET::CUnifiedNetwork::getInstance()->send( "EGS", msgout );
}
}
}
}
}
}
void rename_s_(CStateInstance* entity, CScriptStack& stack)
{
string newName = (string)stack.top(); stack.pop();
CGroup* group = entity->getGroup();
if (group->isSpawned())
{
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBot* bot = *itBot;
if (bot)
{
if (bot->isSpawned())
{
CSpawnBot *spawnBot = bot->getSpawnObj();
if (spawnBot)
{
TDataSetRow row = spawnBot->dataSetRow();
ucstring name;
name.fromUtf8(newName);
NLNET::CMessage msgout("CHARACTER_NAME");
msgout.serial(row);
msgout.serial(name);
sendMessageViaMirror("IOS", msgout);
}
}
}
}
}
}
void vpx_s_(CStateInstance* entity, CScriptStack& stack)
{
string vpx = (string)stack.top(); stack.pop();
CGroup* group = entity->getGroup();
if (group->isSpawned())
{
FOREACH(itBot, CCont<CBot>, group->bots())
{
CBotNpc* bot = NLMISC::safe_cast<CBotNpc*>(*itBot);
if (bot)
{
bot->setVisualProperties(vpx);
bot->sendVisualProperties();
}
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
/** @page code /** @page code
@ -2446,6 +2646,8 @@ std::map<std::string, FScrptNativeFunc> nfGetNpcGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, setFactionProp_ss_); REGISTER_NATIVE_FUNC(functions, setFactionProp_ss_);
REGISTER_NATIVE_FUNC(functions, moveToZone_ss_); REGISTER_NATIVE_FUNC(functions, moveToZone_ss_);
REGISTER_NATIVE_FUNC(functions, setActivity_s_); REGISTER_NATIVE_FUNC(functions, setActivity_s_);
REGISTER_NATIVE_FUNC(functions, startWander_f_);
REGISTER_NATIVE_FUNC(functions, startMoving_fff_);
REGISTER_NATIVE_FUNC(functions, waitInZone_s_); REGISTER_NATIVE_FUNC(functions, waitInZone_s_);
REGISTER_NATIVE_FUNC(functions, stopMoving__); REGISTER_NATIVE_FUNC(functions, stopMoving__);
REGISTER_NATIVE_FUNC(functions, wander__); REGISTER_NATIVE_FUNC(functions, wander__);
@ -2481,6 +2683,9 @@ std::map<std::string, FScrptNativeFunc> nfGetNpcGroupNativeFunctions()
REGISTER_NATIVE_FUNC(functions, facing_cscs_); REGISTER_NATIVE_FUNC(functions, facing_cscs_);
REGISTER_NATIVE_FUNC(functions, emote_css_); REGISTER_NATIVE_FUNC(functions, emote_css_);
REGISTER_NATIVE_FUNC(functions, emote_ss_); REGISTER_NATIVE_FUNC(functions, emote_ss_);
REGISTER_NATIVE_FUNC(functions, emote_s_);
REGISTER_NATIVE_FUNC(functions, rename_s_);
REGISTER_NATIVE_FUNC(functions, vpx_s_);
REGISTER_NATIVE_FUNC(functions, npcSay_css_); REGISTER_NATIVE_FUNC(functions, npcSay_css_);
REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_); REGISTER_NATIVE_FUNC(functions, dssMessage_fsss_);
REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_); REGISTER_NATIVE_FUNC(functions, despawnBotByAlias_s_);

File diff suppressed because it is too large Load diff

View file

@ -152,7 +152,7 @@ void CRoomInstancePlayer::removeUser( CCharacter* user )
msgout.serial(phrase); msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout); sendMessageViaMirror("IOS", msgout);
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams); uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "web_transactions", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, "CLOSE_URL", textParams); uint32 textId = STRING_MANAGER::sendStringToUser(userId, "CLOSE_URL", textParams);
PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId); PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId);
@ -195,7 +195,7 @@ void CRoomInstancePlayer::addUser( CCharacter* user, CCharacter* owner )
msgout.serial(phrase); msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout); sendMessageViaMirror("IOS", msgout);
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "ANSWER_OK", titleParams); uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "web_transactions", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, "RYZHOME_URL", textParams); uint32 textId = STRING_MANAGER::sendStringToUser(userId, "RYZHOME_URL", textParams);
PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId); PlayerManager.sendImpulseToClient(user->getId(), "USER:POPUP", titleId, textId);

View file

@ -3073,7 +3073,7 @@ void cbClientEventSetItemCustomText( NLNET::CMessage& msgin, const std::string &
CCharacter* character = PlayerManager.getChar(eid); CCharacter* character = PlayerManager.getChar(eid);
if(!character) return; if(!character) return;
if (!character->havePriv(":DEV:SGM:EM:")) if (!character->havePriv(":DEV:SGM:GM:EM:"))
{ {
// it should be the crafter of the item, check // it should be the crafter of the item, check
if (inventory==INVENTORIES::UNDEFINED) return; if (inventory==INVENTORIES::UNDEFINED) return;
@ -3111,6 +3111,10 @@ void cbClientEventSetItemCustomText( NLNET::CMessage& msgin, const std::string &
return; return;
} }
// prevent use of @WEB at begin
if (text.size() >= 4 && text[0]=='@' && text[1]=='W' && text[2]=='E' && text[3]=='B')
text = text.substr(4, text.size() - 4);
// force that the begin of the text for non admin is %mfc // force that the begin of the text for non admin is %mfc
if(!text.empty() && text.substr(0, 4) != ucstring("%mfc")) if(!text.empty() && text.substr(0, 4) != ucstring("%mfc"))
{ {

View file

@ -429,6 +429,7 @@ void CCreature::initFormPointer(NLMISC::CSheetId sheetId)
if (_UserModelId.empty() || _PrimAlias == 0) if (_UserModelId.empty() || _PrimAlias == 0)
{ {
_Form = CSheets::getCreaturesForm( sheetId ); _Form = CSheets::getCreaturesForm( sheetId );
_SheetName = sheetId.toString();
} }
else else
{ {
@ -1703,7 +1704,10 @@ void CCreature::kill(TDataSetRow killerRowId)
{ {
if( killer != this && killer->getId().getType() != RYZOMID::player ) if( killer != this && killer->getId().getType() != RYZOMID::player )
{ {
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->removeCreature(_EntityRowId); if (_SheetName.size() != 15 || (_SheetName.size() == 15 && _SheetName[5] != '5' && _SheetName[5] != '6' && _SheetName[5] != '7'))
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->removeXpCreature(_EntityRowId);
else
PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->removeCreature(_EntityRowId);
} }
else if( killer != this ) else if( killer != this )
{ {

View file

@ -552,6 +552,8 @@ private:
/// keep pointer on creature form /// keep pointer on creature form
const CStaticCreatures * _Form; const CStaticCreatures * _Form;
std::string _SheetName;
uint32 _Faction; uint32 _Faction;
bool _FameByKillValid; bool _FameByKillValid;
sint32 _FameByKill; sint32 _FameByKill;

View file

@ -1309,6 +1309,16 @@ void addParam(const std::string &paramStr, std::vector<TBrickParam::IIdPtr> &Par
Params.push_back(new CSBrickParamLifeAura(tail)); Params.push_back(new CSBrickParamLifeAura(tail));
break; break;
case TBrickParam::SP_LIFE_AURA2:
// $*STRUCT CSBrickParamLifeAura2 TBrickParam::SP_LIFE_AURA2
// $*-i uint16 RegenMod // regen modifier (in %) proportionally to item level
// $*-f float Duration // duration in seconds
// $*-f float Radius // aura radius in meters
// $*-f float TargetDisableTime // disable life aura for x seconds on targets
// $*-f float UserDisableTime // disable life aura for x seconds on user
Params.push_back(new CSBrickParamLifeAura2(tail));
break;
case TBrickParam::SP_STAMINA_AURA: case TBrickParam::SP_STAMINA_AURA:
// $*STRUCT CSBrickParamStaminaAura TBrickParam::SP_STAMINA_AURA // $*STRUCT CSBrickParamStaminaAura TBrickParam::SP_STAMINA_AURA
// $*-i uint16 RegenMod // regen modifier (in %) // $*-i uint16 RegenMod // regen modifier (in %)
@ -1319,6 +1329,16 @@ void addParam(const std::string &paramStr, std::vector<TBrickParam::IIdPtr> &Par
Params.push_back(new CSBrickParamStaminaAura(tail)); Params.push_back(new CSBrickParamStaminaAura(tail));
break; break;
case TBrickParam::SP_STAMINA_AURA2:
// $*STRUCT CSBrickParamStaminaAura2 TBrickParam::SP_STAMINA_AURA2
// $*-i uint16 RegenMod // regen modifier (in %) proportionally to item level
// $*-f float Duration // duration in seconds
// $*-f float Radius // aura radius in meters
// $*-f float TargetDisableTime // disable life aura for x seconds on targets
// $*-f float UserDisableTime // disable life aura for x seconds on user
Params.push_back(new CSBrickParamStaminaAura2(tail));
break;
case TBrickParam::SP_SAP_AURA: case TBrickParam::SP_SAP_AURA:
// $*STRUCT CSBrickParamSapAura TBrickParam::SP_SAP_AURA // $*STRUCT CSBrickParamSapAura TBrickParam::SP_SAP_AURA
// $*-i uint16 RegenMod // regen modifier (in %) // $*-i uint16 RegenMod // regen modifier (in %)
@ -1329,6 +1349,16 @@ void addParam(const std::string &paramStr, std::vector<TBrickParam::IIdPtr> &Par
Params.push_back(new CSBrickParamSapAura(tail)); Params.push_back(new CSBrickParamSapAura(tail));
break; break;
case TBrickParam::SP_SAP_AURA2:
// $*STRUCT CSBrickParamSapAura2 TBrickParam::SP_SAP_AURA2
// $*-i uint16 RegenMod // regen modifier (in %) proportionally to item level
// $*-f float Duration // duration in seconds
// $*-f float Radius // aura radius in meters
// $*-f float TargetDisableTime // disable life aura for x seconds on targets
// $*-f float UserDisableTime // disable life aura for x seconds on user
Params.push_back(new CSBrickParamSapAura2(tail));
break;
case TBrickParam::SP_SPEEDING_UP: case TBrickParam::SP_SPEEDING_UP:
// $*STRUCT CSBrickParamSpeedingUp TBrickParam::SP_SPEEDING_UP // $*STRUCT CSBrickParamSpeedingUp TBrickParam::SP_SPEEDING_UP
// $*-i uint16 SpeedMod // speed modifier (in %) // $*-i uint16 SpeedMod // speed modifier (in %)

View file

@ -123,8 +123,11 @@ public:
SP_TAUNT, SP_TAUNT,
SP_SHIELDING, SP_SHIELDING,
SP_LIFE_AURA, SP_LIFE_AURA,
SP_LIFE_AURA2,
SP_STAMINA_AURA, SP_STAMINA_AURA,
SP_STAMINA_AURA2,
SP_SAP_AURA, SP_SAP_AURA,
SP_SAP_AURA2,
SP_SPEEDING_UP, SP_SPEEDING_UP,
SP_INVULNERABILITY, SP_INVULNERABILITY,
SP_MELEE_PROTECTION_AURA, SP_MELEE_PROTECTION_AURA,
@ -299,8 +302,11 @@ public:
if (copyOfStr=="sp_taunt") {_Value=SP_TAUNT; return *this;} if (copyOfStr=="sp_taunt") {_Value=SP_TAUNT; return *this;}
if (copyOfStr=="sp_shielding") {_Value=SP_SHIELDING; return *this;} if (copyOfStr=="sp_shielding") {_Value=SP_SHIELDING; return *this;}
if (copyOfStr=="sp_life_aura") {_Value=SP_LIFE_AURA; return *this;} if (copyOfStr=="sp_life_aura") {_Value=SP_LIFE_AURA; return *this;}
if (copyOfStr=="sp_life_aura2") {_Value=SP_LIFE_AURA2; return *this;}
if (copyOfStr=="sp_stamina_aura") {_Value=SP_STAMINA_AURA; return *this;} if (copyOfStr=="sp_stamina_aura") {_Value=SP_STAMINA_AURA; return *this;}
if (copyOfStr=="sp_sap_aura") {_Value=SP_SAP_AURA; return *this;} if (copyOfStr=="sp_stamina_aura2") {_Value=SP_STAMINA_AURA2; return *this;}
if (copyOfStr=="sp_sap_aura") {_Value=SP_SAP_AURA; return *this;}
if (copyOfStr=="sp_sap_aura2") {_Value=SP_SAP_AURA2; return *this;}
if (copyOfStr=="sp_speeding_up") {_Value=SP_SPEEDING_UP; return *this;} if (copyOfStr=="sp_speeding_up") {_Value=SP_SPEEDING_UP; return *this;}
if (copyOfStr=="sp_invulnerability") {_Value=SP_INVULNERABILITY; return *this;} if (copyOfStr=="sp_invulnerability") {_Value=SP_INVULNERABILITY; return *this;}
if (copyOfStr=="sp_melee_protection_aura") {_Value=SP_MELEE_PROTECTION_AURA; return *this;} if (copyOfStr=="sp_melee_protection_aura") {_Value=SP_MELEE_PROTECTION_AURA; return *this;}
@ -3843,6 +3849,54 @@ struct CSBrickParamLifeAura : public TBrickParam::IId
}; };
struct CSBrickParamLifeAura2 : public TBrickParam::IId
{
// regen modifier (in %)
uint16 RegenMod;
// duration in seconds
float Duration;
// aura radius in meters
float Radius;
// disable life aura for x seconds on targets
float TargetDisableTime;
// disable life aura for x seconds on user
float UserDisableTime;
CSBrickParamLifeAura2():
RegenMod(),
Duration(),
Radius(),
TargetDisableTime(),
UserDisableTime()
{
_Id = TBrickParam::SP_LIFE_AURA2;
}
CSBrickParamLifeAura2(const std::string&str)
{
*this=CSBrickParamLifeAura2();
*this=str;
}
const CSBrickParamLifeAura2& operator=(const std::string& input)
{
std::vector<std::string> args;
convertInput(args, input);
if (args.size()!=5)
return *this;
ParsedOk=true;
RegenMod=atoi(args[0].c_str());
Duration=(float)atof(args[1].c_str());
Radius=(float)atof(args[2].c_str());
TargetDisableTime=(float)atof(args[3].c_str());
UserDisableTime=(float)atof(args[4].c_str());
return *this;
}
};
struct CSBrickParamStaminaAura : public TBrickParam::IId struct CSBrickParamStaminaAura : public TBrickParam::IId
{ {
// regen modifier (in %) // regen modifier (in %)
@ -3891,7 +3945,53 @@ struct CSBrickParamStaminaAura : public TBrickParam::IId
} }
}; };
struct CSBrickParamStaminaAura2 : public TBrickParam::IId
{
// regen modifier (in %)
uint16 RegenMod;
// duration in seconds
float Duration;
// aura radius in meters
float Radius;
// disable life aura for x seconds on targets
float TargetDisableTime;
// disable life aura for x seconds on user
float UserDisableTime;
CSBrickParamStaminaAura2():
RegenMod(),
Duration(),
Radius(),
TargetDisableTime(),
UserDisableTime()
{
_Id = TBrickParam::SP_STAMINA_AURA2;
}
CSBrickParamStaminaAura2(const std::string&str)
{
*this=CSBrickParamStaminaAura2();
*this=str;
}
const CSBrickParamStaminaAura2& operator=(const std::string& input)
{
std::vector<std::string> args;
convertInput(args, input);
if (args.size()!=5)
return *this;
ParsedOk=true;
RegenMod=atoi(args[0].c_str());
Duration=(float)atof(args[1].c_str());
Radius=(float)atof(args[2].c_str());
TargetDisableTime=(float)atof(args[3].c_str());
UserDisableTime=(float)atof(args[4].c_str());
return *this;
}
};
struct CSBrickParamSapAura : public TBrickParam::IId struct CSBrickParamSapAura : public TBrickParam::IId
{ {
// regen modifier (in %) // regen modifier (in %)
@ -3940,7 +4040,53 @@ struct CSBrickParamSapAura : public TBrickParam::IId
} }
}; };
struct CSBrickParamSapAura2 : public TBrickParam::IId
{
// regen modifier (in %)
uint16 RegenMod;
// duration in seconds
float Duration;
// aura radius in meters
float Radius;
// disable life aura for x seconds on targets
float TargetDisableTime;
// disable life aura for x seconds on user
float UserDisableTime;
CSBrickParamSapAura2():
RegenMod(),
Duration(),
Radius(),
TargetDisableTime(),
UserDisableTime()
{
_Id = TBrickParam::SP_SAP_AURA2;
}
CSBrickParamSapAura2(const std::string&str)
{
*this=CSBrickParamSapAura2();
*this=str;
}
const CSBrickParamSapAura2& operator=(const std::string& input)
{
std::vector<std::string> args;
convertInput(args, input);
if (args.size()!=5)
return *this;
ParsedOk=true;
RegenMod=atoi(args[0].c_str());
Duration=(float)atof(args[1].c_str());
Radius=(float)atof(args[2].c_str());
TargetDisableTime=(float)atof(args[3].c_str());
UserDisableTime=(float)atof(args[4].c_str());
return *this;
}
};
struct CSBrickParamSpeedingUp : public TBrickParam::IId struct CSBrickParamSpeedingUp : public TBrickParam::IId
{ {
// speed modifier (in %) // speed modifier (in %)

View file

@ -45,6 +45,7 @@ bool CMissionEvent::simMissionEvent(const std::vector< std::string > & script, C
NL_STRING_CONVERSION_TABLE_ENTRY(EnterZone) NL_STRING_CONVERSION_TABLE_ENTRY(EnterZone)
NL_STRING_CONVERSION_TABLE_ENTRY(Cast) NL_STRING_CONVERSION_TABLE_ENTRY(Cast)
NL_STRING_CONVERSION_TABLE_ENTRY(Kill) NL_STRING_CONVERSION_TABLE_ENTRY(Kill)
NL_STRING_CONVERSION_TABLE_ENTRY(KillPlayer)
NL_STRING_CONVERSION_TABLE_ENTRY(BuyItem) NL_STRING_CONVERSION_TABLE_ENTRY(BuyItem)
NL_STRING_CONVERSION_TABLE_ENTRY(SellItem) NL_STRING_CONVERSION_TABLE_ENTRY(SellItem)
NL_STRING_CONVERSION_TABLE_ENTRY(Forage) NL_STRING_CONVERSION_TABLE_ENTRY(Forage)
@ -93,6 +94,9 @@ bool CMissionEvent::simMissionEvent(const std::vector< std::string > & script, C
case Kill: case Kill:
event = new CMissionEventKill; event = new CMissionEventKill;
break; break;
case KillPlayer:
event = new CMissionEventKillPlayer;
break;
case BuyItem: case BuyItem:
event = new CMissionEventBuyItem; event = new CMissionEventBuyItem;
break; break;
@ -266,7 +270,24 @@ bool CMissionEventKill::buildFromScript( const std::vector< std::string > & scri
TargetEntity = c->getEntityRowId(); TargetEntity = c->getEntityRowId();
return true; return true;
} }
bool CMissionEventKillPlayer::buildFromScript( const std::vector< std::string > & script ,NLMISC::CLog& log)
{
if ( script.size() != 1 )
{
log.displayNL("param entity expected");
return false;
}
CEntityId id;
id.fromString( script[0].c_str() );
CCharacter *victim = PlayerManager.getChar( id );
if ( !victim )
{
log.displayNL("invalid victim entity %s",script[0].c_str() );
return false;
}
TargetEntity = victim->getEntityRowId();
return true;
}
bool CMissionEventBuyItem::buildFromScript( const std::vector< std::string > & script ,NLMISC::CLog& log) bool CMissionEventBuyItem::buildFromScript( const std::vector< std::string > & script ,NLMISC::CLog& log)
{ {
bool ret = true; bool ret = true;

View file

@ -50,6 +50,7 @@ public:
EnterZone, EnterZone,
Cast, Cast,
Kill, Kill,
KillPlayer,
BuyItem, BuyItem,
SellItem, SellItem,
Forage, Forage,
@ -200,6 +201,18 @@ protected:
}; };
/// "Kill player" event
class CMissionEventKillPlayer : public CMissionEvent
{
public:
CMissionEventKillPlayer(const TDataSetRow & victimId)
:CMissionEvent(KillPlayer, victimId){}
protected:
friend class CMissionEvent;
CMissionEventKillPlayer(){};
bool buildFromScript( const std::vector< std::string > & script ,NLMISC::CLog& log);
};
/// "buy" event /// "buy" event
class CMissionEventBuyItem: public CMissionEvent class CMissionEventBuyItem: public CMissionEvent
{ {

View file

@ -29,6 +29,7 @@
#include "mission_manager/mission_parser.h" #include "mission_manager/mission_parser.h"
#include "nel/misc/algo.h" #include "nel/misc/algo.h"
#include "game_share/fame.h" #include "game_share/fame.h"
#include "game_share/pvp_clan.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -39,6 +40,7 @@ Steps linked with kill events
-kill_fauna -kill_fauna
-kill_species ( from the GSPeople::EPeople enum ) -kill_species ( from the GSPeople::EPeople enum )
-kill_npc -kill_npc
-kill_player
***************************************************************************************************/ ***************************************************************************************************/
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -795,7 +797,6 @@ class CMissionStepKillByName : public IMissionStepTemplate
{ {
if ( event.Type == CMissionEvent::Kill ) if ( event.Type == CMissionEvent::Kill )
{ {
CMissionStepKillByName & eventSpe = (CMissionStepKillByName&)event;
CCreature * c = CreatureManager.getCreature( event.TargetEntity ); CCreature * c = CreatureManager.getCreature( event.TargetEntity );
if ( !c ) if ( !c )
{ {
@ -888,3 +889,206 @@ class CMissionStepKillByName : public IMissionStepTemplate
MISSION_STEP_GETNEWPTR(CMissionStepKillByName) MISSION_STEP_GETNEWPTR(CMissionStepKillByName)
}; };
MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name"); MISSION_REGISTER_STEP(CMissionStepKillByName,"kill_npc_by_name");
// ----------------------------------------------------------------------------
class CMissionStepKillPlayer : public IMissionStepTemplate
{
struct CSubStep
{
sint32 Clan;
sint32 MinLevel;
sint32 MaxLevel;
uint16 Quantity;
};
virtual bool buildStep( uint32 line, const std::vector< std::string > & script, CMissionGlobalParsingData & globalData, CMissionSpecificParsingData & missionData )
{
_SourceLine = line;
_Place = 0xFFFF;
if ( script.size() < 2 || script.size() > 3)
{
MISLOGSYNTAXERROR("<clan_name> <min_level> <max_level> <quantity> *[; <clan_name> <min_level> <max_level> <quantity>] [:<place>]");
return false;
}
std::vector< std::string > subs;
NLMISC::splitString( script[1],";", subs );
for ( uint i = 0; i < subs.size(); i++ )
{
std::vector< std::string > args;
CMissionParser::tokenizeString( subs[i]," \t", args );
if ( args.size() != 4 )
{
MISLOGSYNTAXERROR("<clan_name> <min_level> <max_level> <quantity> *[; <clan_name> <min_level> <max_level> <quantity>] [:<place>]");
return false;
}
CSubStep subStep;
subStep.Clan = PVP_CLAN::getFactionIndex(PVP_CLAN::fromString(args[0]));
if ( subStep.Clan == CStaticFames::INVALID_FACTION_INDEX )
{
MISLOGERROR("invalid faction name (Allowed = kami/karavan/tryker/matis/fyros/zorai)");
return false;
}
// missionData.ChatParams.push_back( make_pair( args[0], STRING_MANAGER::clan ) );
subStep.MinLevel = atoi( args[1].c_str() ) * kFameMultipler;
subStep.MaxLevel = atoi( args[2].c_str() ) * kFameMultipler;
if ( subStep.MinLevel >= subStep.MaxLevel )
{
MISLOGERROR("min_level >= max_level");
return false;
}
subStep.Quantity = (uint16) atoi( args[3].c_str() );
if ( subStep.Quantity == 0 )
{
MISLOGERROR("invalid quantity 0");
return false;
}
_SubSteps.push_back( subStep );
}
if ( script.size() == 3 )
{
string placeStr = CMissionParser::getNoBlankString( script[2] );
missionData.ChatParams.push_back( make_pair(placeStr,STRING_MANAGER::place) );
CPlace * place = CZoneManager::getInstance().getPlaceFromName( placeStr );
if ( !place )
{
MISLOGERROR1("invalid place '%s'", script[2].c_str());
return false;
}
else {_Place = place->getId();}
}
return true;
}
uint processEvent( const TDataSetRow & userRow, const CMissionEvent & event,uint subStepIndex,const TDataSetRow & giverRow )
{
if ( event.Type == CMissionEvent::KillPlayer )
{
CCharacter * victim = PlayerManager.getChar( event.TargetEntity );
if ( !victim )
{
LOGMISSIONSTEPERROR("kill_player : invalid victim " + toString(event.TargetEntity.getIndex()));
}
else
{
sint32 victimFame = CFameInterface::getInstance().getFameIndexed(victim->getId(), _SubSteps[subStepIndex].Clan);
if ( (victimFame > _SubSteps[subStepIndex].MinLevel) &&
(victimFame < _SubSteps[subStepIndex].MaxLevel) )
{
if ( _Place != 0xFFFF )
{
float gooDistance;
const CPlace * stable = NULL;
std::vector<const CPlace *> places;
const CRegion * region = NULL;
const CContinent * continent = NULL;
if ( !CZoneManager::getInstance().getPlace( victim->getState().X, victim->getState().Y, gooDistance, &stable, places, &region , &continent ) )
return 0;
if ( continent && continent->getId() == _Place )
{
LOGMISSIONSTEPSUCCESS("kill_player");
return 1;
}
if ( region && region->getId() == _Place )
{
LOGMISSIONSTEPSUCCESS("kill_player");
return 1;
}
for ( uint i = 0; i < places.size(); i++ )
{
if ( places[i] && places[i]->getId() == _Place )
{
LOGMISSIONSTEPSUCCESS("kill_player");
return 1;
}
}
return 0;
}
else
{
LOGMISSIONSTEPSUCCESS("kill_player");
return 1;
}
}
}
}
return 0;
}
void getInitState( std::vector<uint32>& ret )
{
ret.clear();
ret.resize( _SubSteps.size() );
for ( uint i = 0; i < _SubSteps.size(); i++ )
{
ret[i] = _SubSteps[i].Quantity;
}
}
virtual void getTextParams( uint & nbSubSteps, const std::string* & textPtr,TVectorParamCheck& retParams, const std::vector<uint32>& subStepStates)
{
static const std::string stepText = "MIS_KILL_PLAYER";
static const std::string stepTextLoc = "MIS_KILL_PLAYER_LOC";
if ( _Place != 0xFFFF )
retParams.resize(3);
else
retParams.resize(2);
textPtr = &stepText;
nlassert( _SubSteps.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::faction;
retParams.back().Enum = _SubSteps[i].Clan;
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::integer;
retParams.back().Int = _SubSteps[i].MinLevel;
retParams.push_back(STRING_MANAGER::TParam());
retParams.back().Type = STRING_MANAGER::integer;
retParams.back().Int = _SubSteps[i].MaxLevel;
}
}
/*
if ( _Place != 0xFFFF )
{
STRING_MANAGER::TParam param;
param.Type = STRING_MANAGER::place;
CPlace * place = CZoneManager::getInstance().getPlaceFromId(_Place);
if ( !place )
{
MISLOG("sline:%u ERROR : kill_player : Invalid place %u", _SourceLine, _Place);
}
else
{
param.Identifier = place->getName();
retParams.push_back(param);
}
textPtr = &stepTextLoc;
}
else
*/
textPtr = &stepText;
}
std::vector< CSubStep > _SubSteps;
uint16 _Place;
MISSION_STEP_GETNEWPTR(CMissionStepKillPlayer)
};
MISSION_REGISTER_STEP(CMissionStepKillPlayer, "kill_player");

View file

@ -560,7 +560,7 @@ public:
else else
{ {
CPlayer *p = PlayerManager.getPlayer(uint32(character->getId().getShortId())>>4); CPlayer *p = PlayerManager.getPlayer(uint32(character->getId().getShortId())>>4);
if (p && p->havePriv(":SGM:GM:VG:SG:G")) if (p && p->havePriv(":SGM:GM:VG:SG:G:"))
{ {
// do not override state with those from the ring // do not override state with those from the ring
} }

View file

@ -135,21 +135,28 @@ void CAuraRootEffect::createEffectOnEntity(CEntityBase *entity, CEntityBase *cre
} }
else else
{ {
auraEffect->addLifeTime(); if (_Value < auraEffect->getParamValue())
{
auraEffect->stopEffect();
}
else
{
auraEffect->addLifeTime();
return;
}
} }
return;
} }
} }
// no effect found, create one if the entity can receive this effect // no effect found, create one if the entity can receive this effect
static NLMISC::TGameCycle endDate; static NLMISC::TGameCycle endDate;
if (character->isAuraEffective(_PowerType, endDate, creator->getId()) ) if (character->isAuraEffective(_PowerType, endDate, creator->getId()) || _IsFromConsumable )
{ {
CAuraBaseEffect *effect = IAuraEffectFactory::buildEffectFromPowerType(_PowerType, *this, entity->getEntityRowId()); CAuraBaseEffect *effect = IAuraEffectFactory::buildEffectFromPowerType(_PowerType, *this, entity->getEntityRowId());
if (effect) if (effect)
{ {
effect->setIsFromConsumable(_IsFromConsumable);
effect->setEffectDisabledEndDate( CTickEventHandler::getGameCycle() + _TargetDisableTime ); effect->setEffectDisabledEndDate( CTickEventHandler::getGameCycle() + _TargetDisableTime );
entity->addSabrinaEffect(effect); entity->addSabrinaEffect(effect);
character->useAura(_PowerType, CTickEventHandler::getGameCycle(), CTickEventHandler::getGameCycle() + _TargetDisableTime, creator->getId()); character->useAura(_PowerType, CTickEventHandler::getGameCycle(), CTickEventHandler::getGameCycle() + _TargetDisableTime, creator->getId());
@ -218,6 +225,7 @@ CAuraBaseEffect::CAuraBaseEffect( const CAuraRootEffect &rootEffect, TDataSetRow
CTickEventHandler::getGameCycle() + (NLMISC::TGameCycle)AurasUpdateFrequency.get() + 10) CTickEventHandler::getGameCycle() + (NLMISC::TGameCycle)AurasUpdateFrequency.get() + 10)
{ {
_PowerType = rootEffect.powerType(); _PowerType = rootEffect.powerType();
_IsFromConsumable = false;
} }
void CAuraBaseEffect::addLifeTime() void CAuraBaseEffect::addLifeTime()
@ -252,8 +260,10 @@ void CAuraBaseEffect::removed()
if (_EffectIndexInDB >= 0) if (_EffectIndexInDB >= 0)
{ {
// player->removeEffectInDB((uint8)_EffectIndexInDB, true); if (_IsFromConsumable)
player->disableEffectInDB( (uint8)_EffectIndexInDB,true, _DisabledEndDate); player->removeEffectInDB((uint8)_EffectIndexInDB, true);
else
player->disableEffectInDB( (uint8)_EffectIndexInDB,true, _DisabledEndDate);
} }
} // removed // } // removed //

View file

@ -49,6 +49,7 @@ public:
_PowerType(powerType), _CreatedEffectFamily(effectFamily) _PowerType(powerType), _CreatedEffectFamily(effectFamily)
{ {
_AffectGuild = affectGuild; _AffectGuild = affectGuild;
_IsFromConsumable = false;
#ifdef NL_DEBUG #ifdef NL_DEBUG
_LastUpdateDate = CTickEventHandler::getGameCycle(); _LastUpdateDate = CTickEventHandler::getGameCycle();
#endif #endif
@ -69,6 +70,7 @@ public:
inline void setRadius(float radius) { _AuraRadius = radius; } inline void setRadius(float radius) { _AuraRadius = radius; }
// set disable time for targets // set disable time for targets
inline void setTargetDisableTime(NLMISC::TGameCycle time) { _TargetDisableTime = time; } inline void setTargetDisableTime(NLMISC::TGameCycle time) { _TargetDisableTime = time; }
inline void setIsFromConsumable(bool fromConsumable) { _IsFromConsumable = fromConsumable; }
protected: protected:
/// create or update the real effect on target entity /// create or update the real effect on target entity
@ -93,6 +95,8 @@ private:
// is aura affecting guild members ? (teammates are always affected) // is aura affecting guild members ? (teammates are always affected)
bool _AffectGuild; bool _AffectGuild;
bool _IsFromConsumable;
#ifdef NL_DEBUG #ifdef NL_DEBUG
NLMISC::TGameCycle _LastUpdateDate; NLMISC::TGameCycle _LastUpdateDate;
#endif #endif

View file

@ -1053,6 +1053,11 @@ bool CCombatPhrase::validate()
if ( _Attacker->getItem( CCombatAttacker::RightHandItem, _RightWeapon) ) if ( _Attacker->getItem( CCombatAttacker::RightHandItem, _RightWeapon) )
{ {
// forbid use of multi target with an area effect weapon !!!!
if ( FightAreaEffectOn && _RightWeapon.Area && _HitAllMeleeAggressors )
return false;
if (_RightWeapon.Family == ITEMFAMILY::MELEE_WEAPON ) if (_RightWeapon.Family == ITEMFAMILY::MELEE_WEAPON )
{ {
_MeleeCombat = true; _MeleeCombat = true;

View file

@ -662,10 +662,19 @@ protected:
for (it=effects.begin(), itEnd=effects.end(); it!=itEnd; ++it) for (it=effects.begin(), itEnd=effects.end(); it!=itEnd; ++it)
{ {
float rnd = RandomGenerator.frand(); float rnd = RandomGenerator.frand();
if (rnd<it->EffectArgFloat[0]) float effect0 = it->EffectArgFloat[0];
float effect1 = it->EffectArgFloat[1];
// Clamp boost when player do not have required privs
if (!character->havePriv(":DEV:") && !character->havePriv(":SGM:"))
{ {
applyProcAddLimit(Params, statBitField, it->EffectArgFloat[1]); clamp(effect0, 0.f, 0.25f);
PHRASE_UTILITIES::sendItemSpecialEffectProcMessage(ITEM_SPECIAL_EFFECT::ISE_CRAFT_ADD_LIMIT, character, NULL, (sint32)(it->EffectArgFloat[1]*100.f)); clamp(effect1, 0.f, 0.25f);
}
if (rnd < effect0)
{
applyProcAddLimit(Params, statBitField, effect1);
PHRASE_UTILITIES::sendItemSpecialEffectProcMessage(ITEM_SPECIAL_EFFECT::ISE_CRAFT_ADD_LIMIT, character, NULL, (sint32)(effect1*100.f));
} }
} }
} }

View file

@ -421,7 +421,7 @@ void CMagicPhrase::computeCastingTime(float castingTimeFactor, float wearMalus)
nlwarning("CMagicPhrase:computeCastingTime: _MaxCastTime(%u) < _MinCastTime(%u)", _MaxCastTime, _MinCastTime); nlwarning("CMagicPhrase:computeCastingTime: _MaxCastTime(%u) < _MinCastTime(%u)", _MaxCastTime, _MinCastTime);
_MaxCastTime = _MinCastTime; _MaxCastTime = _MinCastTime;
} }
// apply magic focus item factor // apply magic focus item factor
float meanFactor = 0.0f; float meanFactor = 0.0f;
for (uint i = 0 ; i < _Skills.size() ; ++i) for (uint i = 0 ; i < _Skills.size() ; ++i)
@ -922,6 +922,9 @@ void CMagicPhrase::execute()
} }
castingTime = NLMISC::TGameCycle ( castingTime * (slowingParam / 100.0f + 1.0f ) ); castingTime = NLMISC::TGameCycle ( castingTime * (slowingParam / 100.0f + 1.0f ) );
if (_Nature == ACTNATURE::RECHARGE)
castingTime /= 2;
_ExecutionEndDate = time + castingTime; _ExecutionEndDate = time + castingTime;
if (_IsStatic && caster->getId().getType() == RYZOMID::player ) if (_IsStatic && caster->getId().getType() == RYZOMID::player )
@ -954,6 +957,9 @@ void CMagicPhrase::execute()
case ACTNATURE::OFFENSIVE_MAGIC: case ACTNATURE::OFFENSIVE_MAGIC:
behav = MBEHAV::CAST_OFF; behav = MBEHAV::CAST_OFF;
break; break;
case ACTNATURE::RECHARGE:
behav = MBEHAV::CAST_MIX;
break;
} }
} }
else else
@ -1412,6 +1418,10 @@ bool CMagicPhrase::launch()
// tmp nico : stats about projectiles // tmp nico : stats about projectiles
projStatsIncrement(); projStatsIncrement();
break; break;
case ACTNATURE::RECHARGE:
behav = MBEHAV::CAST_MIX_SUCCESS;
break;
} }
} }
else else
@ -1428,6 +1438,10 @@ bool CMagicPhrase::launch()
case ACTNATURE::OFFENSIVE_MAGIC: case ACTNATURE::OFFENSIVE_MAGIC:
behav = MBEHAV::CAST_OFF_FAIL; behav = MBEHAV::CAST_OFF_FAIL;
break; break;
case ACTNATURE::RECHARGE:
behav = MBEHAV::CAST_MIX_FAIL;
break;
} }
} }
} }
@ -1769,6 +1783,10 @@ void CMagicPhrase::stop()
case ACTNATURE::OFFENSIVE_MAGIC: case ACTNATURE::OFFENSIVE_MAGIC:
behav = MBEHAV::CAST_OFF_FAIL; behav = MBEHAV::CAST_OFF_FAIL;
break; break;
case ACTNATURE::RECHARGE:
behav = MBEHAV::CAST_MIX_FAIL;
break;
} }
// set behaviour // set behaviour
PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, behav ); PHRASE_UTILITIES::sendUpdateBehaviour( _ActorRowId, behav );

View file

@ -96,7 +96,7 @@ public:
///\ctor ///\ctor
CSEffect() CSEffect()
:_IsRemoved(false),_Value(0),_Power(0) :_IsRemoved(false),_Value(0),_Power(0),_IsFromConsumable(false)
{ {
_UpdateTimer.setRemaining(1, new CUpdateEffectTimerEvent(this, true)); _UpdateTimer.setRemaining(1, new CUpdateEffectTimerEvent(this, true));
_Skill = SKILLS::unknown; _Skill = SKILLS::unknown;
@ -106,7 +106,7 @@ public:
} }
inline CSEffect( const TDataSetRow & creatorRowId, const TDataSetRow & targetRowId, EFFECT_FAMILIES::TEffectFamily family, bool stackable, sint32 effectValue, uint32 power) inline CSEffect( const TDataSetRow & creatorRowId, const TDataSetRow & targetRowId, EFFECT_FAMILIES::TEffectFamily family, bool stackable, sint32 effectValue, uint32 power)
:_CreatorRowId(creatorRowId),_TargetRowId(targetRowId),_Family(family),_Value(effectValue),_Power(power),_IsStackable(stackable),_IsRemoved(false) :_CreatorRowId(creatorRowId),_TargetRowId(targetRowId),_Family(family),_Value(effectValue),_Power(power),_IsStackable(stackable),_IsRemoved(false),_IsFromConsumable(false)
{ {
++NbAllocatedEffects; ++NbAllocatedEffects;
_EffectChatName = EFFECT_FAMILIES::getAssociatedChatId(family); // txt msg _EffectChatName = EFFECT_FAMILIES::getAssociatedChatId(family); // txt msg
@ -160,7 +160,13 @@ public:
inline sint32 getParamValue() const{ return _Value;} inline sint32 getParamValue() const{ return _Value;}
inline uint32 getPower() const{ return _Power;} inline uint32 getPower() const{ return _Power;}
inline SKILLS::ESkills getSkill() const{ return _Skill; } inline SKILLS::ESkills getSkill() const{ return _Skill; }
virtual NLMISC::CSheetId getAssociatedSheetId() const { return EFFECT_FAMILIES::getAssociatedSheetId(_Family); } virtual NLMISC::CSheetId getAssociatedSheetId() const
{
if (_IsFromConsumable)
return NLMISC::CSheetId("hatred.sbrick");
else
return EFFECT_FAMILIES::getAssociatedSheetId(_Family);
}
//@} //@}
///\name write accessors ///\name write accessors
@ -203,6 +209,10 @@ public:
/// set if the effect has been removed from affected entity /// set if the effect has been removed from affected entity
inline void isRemoved(bool removed) { _IsRemoved = removed; } inline void isRemoved(bool removed) { _IsRemoved = removed; }
inline void setIsFromConsumable(bool fromConsumable) { _IsFromConsumable = fromConsumable; }
inline bool getIsFromConsumable() { return _IsFromConsumable; }
protected: protected:
/// send chat message for effect begin /// send chat message for effect begin
void sendEffectBeginMessages(); void sendEffectBeginMessages();
@ -245,6 +255,9 @@ protected:
/// timer used to end the effect /// timer used to end the effect
CTimer _EndTimer; CTimer _EndTimer;
bool _IsFromConsumable;
public: public:
static uint32 NbAllocatedEffects; static uint32 NbAllocatedEffects;
static uint32 NbDesallocatedEffects; static uint32 NbDesallocatedEffects;

View file

@ -49,7 +49,10 @@ bool CSpecialPower::validate(std::string &errorCode)
nlwarning("<CSpecialPower::validate> Cannot find actor entity or not a player"); nlwarning("<CSpecialPower::validate> Cannot find actor entity or not a player");
return false; return false;
} }
if (_ByPassDisablePowerTimer)
return true;
TGameCycle endDate; TGameCycle endDate;
if (!actor->canUsePower(_PowerType, (uint16)~0, endDate)) if (!actor->canUsePower(_PowerType, (uint16)~0, endDate))
{ {
@ -87,6 +90,8 @@ bool CSpecialPowerAuras::validate(std::string &errorCode)
if (actor->isDead()) if (actor->isDead())
return false; return false;
if (_ByPassTargetsDisableAuraTime)
return true;
TGameCycle endDate = actor->getForbidAuraUseEndDate(); TGameCycle endDate = actor->getForbidAuraUseEndDate();
if (actor->getForbidAuraUseEndDate() >= CTickEventHandler::getGameCycle()) if (actor->getForbidAuraUseEndDate() >= CTickEventHandler::getGameCycle())
{ {

View file

@ -38,7 +38,7 @@ class CSpecialPower
NL_INSTANCE_COUNTER_DECL(CSpecialPower); NL_INSTANCE_COUNTER_DECL(CSpecialPower);
public: public:
/// Constructor /// Constructor
CSpecialPower() : _Phrase(NULL), _ApplyOnTargets(true), _PowerType(POWERS::UnknownType), _DisablePowerTime(0) CSpecialPower() : _Phrase(NULL), _ApplyOnTargets(true), _PowerType(POWERS::UnknownType), _DisablePowerTime(0), _ByPassDisablePowerTimer(false)
{} {}
/// validate the power utilisation /// validate the power utilisation
@ -51,6 +51,9 @@ public:
inline bool applyOnTargets() const { return _ApplyOnTargets; } inline bool applyOnTargets() const { return _ApplyOnTargets; }
inline void applyOnTargets(bool b) { _ApplyOnTargets = b; } inline void applyOnTargets(bool b) { _ApplyOnTargets = b; }
/// set ByPass DisablePowerTimer
inline void setByPass(bool flag) { _ByPassDisablePowerTimer = flag; }
protected: protected:
/// actor /// actor
TDataSetRow _ActorRowId; TDataSetRow _ActorRowId;
@ -66,6 +69,8 @@ protected:
/// related phrase /// related phrase
CSpecialPowerPhrase *_Phrase; CSpecialPowerPhrase *_Phrase;
bool _ByPassDisablePowerTimer;
}; };
/** /**
@ -83,6 +88,7 @@ public:
_TargetsDisableAuraTime = 0; _TargetsDisableAuraTime = 0;
_AuraRadius = 0.0f; _AuraRadius = 0.0f;
_AffectGuild = false; _AffectGuild = false;
_ByPassTargetsDisableAuraTime = false;
} }
/// validate the power utilisation /// validate the power utilisation
@ -96,6 +102,9 @@ public:
/// set affect guild flag /// set affect guild flag
inline void affectGuild(bool flag) { _AffectGuild = flag; } inline void affectGuild(bool flag) { _AffectGuild = flag; }
/// set ByPass TargetsDisableAuraTime
inline void setByPass(bool flag) { _ByPassTargetsDisableAuraTime = flag; }
protected: protected:
// disable this aura on targets for x ticks // disable this aura on targets for x ticks
@ -104,6 +113,9 @@ protected:
float _AuraRadius; float _AuraRadius;
/// affect guild members ? (always affect teammates) /// affect guild members ? (always affect teammates)
bool _AffectGuild; bool _AffectGuild;
bool _ByPassTargetsDisableAuraTime;
}; };
#endif // RYZOM_SPECIAL_POWER_H #endif // RYZOM_SPECIAL_POWER_H

View file

@ -54,7 +54,10 @@ void CSpecialPowerBasicAura::apply()
} }
// disable auras // disable auras
actor->setForbidAuraUseDates(CTickEventHandler::getGameCycle(), CTickEventHandler::getGameCycle() + _DisablePowerTime); if (!_ByPassTargetsDisableAuraTime)
{
actor->setForbidAuraUseDates(CTickEventHandler::getGameCycle(), CTickEventHandler::getGameCycle() + _DisablePowerTime);
}
const TGameCycle endDate = _Duration + CTickEventHandler::getGameCycle(); const TGameCycle endDate = _Duration + CTickEventHandler::getGameCycle();
@ -66,7 +69,11 @@ void CSpecialPowerBasicAura::apply()
return; return;
} }
effect->setRadius(_AuraRadius); effect->setRadius(_AuraRadius);
effect->setIsFromConsumable(_ByPassTargetsDisableAuraTime);
effect->setTargetDisableTime(_TargetsDisableAuraTime); effect->setTargetDisableTime(_TargetsDisableAuraTime);
actor->addSabrinaEffect(effect); actor->addSabrinaEffect(effect);
// add aura FX on the actor // add aura FX on the actor

View file

@ -118,7 +118,7 @@ bool CSpecialPowerPhrase::buildFromConsumable(const TDataSetRow & actorRowId, co
//----------------------------------------------- //-----------------------------------------------
// CSpecialPowerPhrase processParams // CSpecialPowerPhrase processParams
//----------------------------------------------- //-----------------------------------------------
void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &params, bool /*isConsumable*/, uint16 quality) void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &params, bool isConsumable, uint16 quality)
{ {
// process params // process params
for ( uint j = 0 ; j < params.size() ; ++j) for ( uint j = 0 ; j < params.size() ; ++j)
@ -172,6 +172,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
power->setNoShieldProtection( ((CSBrickParamShielding *)param)->NoShieldProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->NoShieldProtectionMax); power->setNoShieldProtection( ((CSBrickParamShielding *)param)->NoShieldProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->NoShieldProtectionMax);
power->setBucklerProtection( ((CSBrickParamShielding *)param)->BucklerProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->BucklerProtectionMax); power->setBucklerProtection( ((CSBrickParamShielding *)param)->BucklerProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->BucklerProtectionMax);
power->setShieldProtection( ((CSBrickParamShielding *)param)->ShieldProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->ShieldProtectionMax); power->setShieldProtection( ((CSBrickParamShielding *)param)->ShieldProtectionFactor / 100.0f, ((CSBrickParamShielding *)param)->ShieldProtectionMax);
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
break; break;
@ -191,11 +192,32 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
lifeAura->setRadius(((CSBrickParamLifeAura *)param)->Radius); lifeAura->setRadius(((CSBrickParamLifeAura *)param)->Radius);
lifeAura->setFamilies(EFFECT_FAMILIES::PowerRootLifeAura,EFFECT_FAMILIES::PowerLifeAura ); lifeAura->setFamilies(EFFECT_FAMILIES::PowerRootLifeAura,EFFECT_FAMILIES::PowerLifeAura );
lifeAura->setParamValue(((CSBrickParamLifeAura *)param)->RegenMod); lifeAura->setParamValue(((CSBrickParamLifeAura *)param)->RegenMod);
lifeAura->setByPass(isConsumable);
_Powers.push_back(lifeAura); _Powers.push_back(lifeAura);
} }
} }
break; break;
case TBrickParam::SP_LIFE_AURA2:
{
// $*STRUCT CSBrickParamLifeAura: public TBrickParam::CId <TBrickParam::SP_LIFE_AURA2>
// $*-i uint16 RegenMod // regen modifier proportionally to item level
// $*-f float Duration // duration in seconds
// $*-f float Radius // aura radius in meters
// $*-f float TargetDisableTime // disable life aura for x seconds on targets
// $*-f float UserDisableTime // disable life aura for x seconds on user
CSpecialPowerBasicAura *lifeAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamLifeAura *)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamLifeAura *)param)->TargetDisableTime, POWERS::LifeAura);
if (lifeAura)
{
lifeAura->setRadius(((CSBrickParamLifeAura *)param)->Radius);
lifeAura->setFamilies(EFFECT_FAMILIES::PowerRootLifeAura,EFFECT_FAMILIES::PowerLifeAura );
lifeAura->setParamValue(((CSBrickParamLifeAura *)param)->RegenMod*quality);
lifeAura->setByPass(isConsumable);
_Powers.push_back(lifeAura);
}
}
break;
case TBrickParam::SP_STAMINA_AURA: case TBrickParam::SP_STAMINA_AURA:
{ {
CSpecialPowerBasicAura *staminaAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamStaminaAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamStaminaAura *)param)->TargetDisableTime, POWERS::StaminaAura); CSpecialPowerBasicAura *staminaAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamStaminaAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamStaminaAura *)param)->TargetDisableTime, POWERS::StaminaAura);
@ -204,11 +226,26 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
staminaAura->setRadius(((CSBrickParamStaminaAura *)param)->Radius); staminaAura->setRadius(((CSBrickParamStaminaAura *)param)->Radius);
staminaAura->setFamilies(EFFECT_FAMILIES::PowerRootStaminaAura,EFFECT_FAMILIES::PowerStaminaAura ); staminaAura->setFamilies(EFFECT_FAMILIES::PowerRootStaminaAura,EFFECT_FAMILIES::PowerStaminaAura );
staminaAura->setParamValue(((CSBrickParamStaminaAura *)param)->RegenMod); staminaAura->setParamValue(((CSBrickParamStaminaAura *)param)->RegenMod);
staminaAura->setByPass(isConsumable);
_Powers.push_back(staminaAura); _Powers.push_back(staminaAura);
} }
} }
break; break;
case TBrickParam::SP_STAMINA_AURA2:
{
CSpecialPowerBasicAura *staminaAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamStaminaAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamStaminaAura *)param)->TargetDisableTime, POWERS::StaminaAura);
if (staminaAura)
{
staminaAura->setRadius(((CSBrickParamStaminaAura *)param)->Radius);
staminaAura->setFamilies(EFFECT_FAMILIES::PowerRootStaminaAura,EFFECT_FAMILIES::PowerStaminaAura );
staminaAura->setParamValue(((CSBrickParamStaminaAura *)param)->RegenMod*quality);
staminaAura->setByPass(isConsumable);
_Powers.push_back(staminaAura);
}
}
break;
case TBrickParam::SP_SAP_AURA: case TBrickParam::SP_SAP_AURA:
{ {
CSpecialPowerBasicAura *sapAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamSapAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamSapAura *)param)->TargetDisableTime, POWERS::SapAura); CSpecialPowerBasicAura *sapAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamSapAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamSapAura *)param)->TargetDisableTime, POWERS::SapAura);
@ -217,11 +254,25 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
sapAura->setRadius(((CSBrickParamSapAura *)param)->Radius); sapAura->setRadius(((CSBrickParamSapAura *)param)->Radius);
sapAura->setFamilies(EFFECT_FAMILIES::PowerRootSapAura,EFFECT_FAMILIES::PowerSapAura ); sapAura->setFamilies(EFFECT_FAMILIES::PowerRootSapAura,EFFECT_FAMILIES::PowerSapAura );
sapAura->setParamValue(((CSBrickParamSapAura *)param)->RegenMod); sapAura->setParamValue(((CSBrickParamSapAura *)param)->RegenMod);
sapAura->setByPass(isConsumable);
_Powers.push_back(sapAura); _Powers.push_back(sapAura);
} }
} }
break; break;
case TBrickParam::SP_SAP_AURA2:
{
CSpecialPowerBasicAura *sapAura = new CSpecialPowerBasicAura(_ActorRowId, this, ((CSBrickParamSapAura*)param)->Duration, ((CSBrickParamLifeAura *)param)->UserDisableTime, ((CSBrickParamSapAura *)param)->TargetDisableTime, POWERS::SapAura);
if (sapAura)
{
sapAura->setRadius(((CSBrickParamSapAura *)param)->Radius);
sapAura->setFamilies(EFFECT_FAMILIES::PowerRootSapAura,EFFECT_FAMILIES::PowerSapAura );
sapAura->setParamValue(((CSBrickParamSapAura *)param)->RegenMod*quality);
sapAura->setByPass(isConsumable);
_Powers.push_back(sapAura);
}
}
break;
case TBrickParam::SP_SPEEDING_UP: case TBrickParam::SP_SPEEDING_UP:
{ {
@ -232,6 +283,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
CSpecialPowerSpeedingUp *power = new CSpecialPowerSpeedingUp(_ActorRowId, this, (uint8)((CSBrickParamSpeedingUp *)param)->SpeedMod, ((CSBrickParamSpeedingUp *)param)->Duration, ((CSBrickParamSpeedingUp *)param)->DisableTime); CSpecialPowerSpeedingUp *power = new CSpecialPowerSpeedingUp(_ActorRowId, this, (uint8)((CSBrickParamSpeedingUp *)param)->SpeedMod, ((CSBrickParamSpeedingUp *)param)->Duration, ((CSBrickParamSpeedingUp *)param)->DisableTime);
if (power) if (power)
{ {
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
} }
@ -246,6 +298,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
if (power) if (power)
{ {
power->setEffectFamily( EFFECT_FAMILIES::PowerInvulnerability ); power->setEffectFamily( EFFECT_FAMILIES::PowerInvulnerability );
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
} }
@ -263,6 +316,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
{ {
aura->setRadius(((CSBrickParamMeleeProtection *)param)->Radius); aura->setRadius(((CSBrickParamMeleeProtection *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootProtection,EFFECT_FAMILIES::PowerProtection ); aura->setFamilies(EFFECT_FAMILIES::PowerRootProtection,EFFECT_FAMILIES::PowerProtection );
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
} }
@ -280,6 +334,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
{ {
aura->setRadius(((CSBrickParamRangeProtection *)param)->Radius); aura->setRadius(((CSBrickParamRangeProtection *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootUmbrella,EFFECT_FAMILIES::PowerUmbrella); aura->setFamilies(EFFECT_FAMILIES::PowerRootUmbrella,EFFECT_FAMILIES::PowerUmbrella);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
} }
@ -297,6 +352,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
{ {
aura->setRadius(((CSBrickParamMagicProtection *)param)->Radius); aura->setRadius(((CSBrickParamMagicProtection *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootAntiMagicShield,EFFECT_FAMILIES::PowerAntiMagicShield); aura->setFamilies(EFFECT_FAMILIES::PowerRootAntiMagicShield,EFFECT_FAMILIES::PowerAntiMagicShield);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
} }
@ -316,6 +372,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
aura->setParamValue(((CSBrickParamWarCry *)param)->DamageBonus); aura->setParamValue(((CSBrickParamWarCry *)param)->DamageBonus);
aura->setRadius(((CSBrickParamWarCry *)param)->Radius); aura->setRadius(((CSBrickParamWarCry *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootWarCry,EFFECT_FAMILIES::PowerWarCry); aura->setFamilies(EFFECT_FAMILIES::PowerRootWarCry,EFFECT_FAMILIES::PowerWarCry);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
break; break;
@ -335,6 +392,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
aura->setParamValue(((CSBrickParamFireWall *)param)->Damage); aura->setParamValue(((CSBrickParamFireWall *)param)->Damage);
aura->setRadius(((CSBrickParamFireWall *)param)->Radius); aura->setRadius(((CSBrickParamFireWall *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootFireWall,EFFECT_FAMILIES::PowerFireWall); aura->setFamilies(EFFECT_FAMILIES::PowerRootFireWall,EFFECT_FAMILIES::PowerFireWall);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
break; break;
@ -354,6 +412,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
aura->setParamValue(((CSBrickParamThornWall *)param)->Damage); aura->setParamValue(((CSBrickParamThornWall *)param)->Damage);
aura->setRadius(((CSBrickParamThornWall *)param)->Radius); aura->setRadius(((CSBrickParamThornWall *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootThornWall,EFFECT_FAMILIES::PowerThornWall); aura->setFamilies(EFFECT_FAMILIES::PowerRootThornWall,EFFECT_FAMILIES::PowerThornWall);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
break; break;
@ -373,6 +432,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
aura->setParamValue(((CSBrickParamWaterWall *)param)->Damage); aura->setParamValue(((CSBrickParamWaterWall *)param)->Damage);
aura->setRadius(((CSBrickParamWaterWall *)param)->Radius); aura->setRadius(((CSBrickParamWaterWall *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootWaterWall,EFFECT_FAMILIES::PowerWaterWall); aura->setFamilies(EFFECT_FAMILIES::PowerRootWaterWall,EFFECT_FAMILIES::PowerWaterWall);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
break; break;
@ -392,6 +452,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
aura->setParamValue(((CSBrickParamLightningWall *)param)->Damage); aura->setParamValue(((CSBrickParamLightningWall *)param)->Damage);
aura->setRadius(((CSBrickParamLightningWall *)param)->Radius); aura->setRadius(((CSBrickParamLightningWall *)param)->Radius);
aura->setFamilies(EFFECT_FAMILIES::PowerRootLightningWall,EFFECT_FAMILIES::PowerLightningWall); aura->setFamilies(EFFECT_FAMILIES::PowerRootLightningWall,EFFECT_FAMILIES::PowerLightningWall);
aura->setByPass(isConsumable);
_Powers.push_back(aura); _Powers.push_back(aura);
} }
break; break;
@ -412,6 +473,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
power->setDamagePerUpdate(((CSBrickParamBerserk *)param)->DamagePerUpdate); power->setDamagePerUpdate(((CSBrickParamBerserk *)param)->DamagePerUpdate);
power->setParamValue(((CSBrickParamBerserk *)param)->DamageBonus); power->setParamValue(((CSBrickParamBerserk *)param)->DamageBonus);
power->setEffectFamily( EFFECT_FAMILIES::PowerBerserker ); power->setEffectFamily( EFFECT_FAMILIES::PowerBerserker );
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
} }
@ -449,6 +511,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
if (power) if (power)
{ {
power->setAffectedScore( SCORES::toScore(cp->AffectedScore) ); power->setAffectedScore( SCORES::toScore(cp->AffectedScore) );
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
} }
@ -469,6 +532,7 @@ void CSpecialPowerPhrase::processParams(const vector<TBrickParam::IIdPtr> &param
if (power) if (power)
{ {
power->setAffectedScore( SCORES::toScore(cp->AffectedScore) ); power->setAffectedScore( SCORES::toScore(cp->AffectedScore) );
power->setByPass(isConsumable);
_Powers.push_back(power); _Powers.push_back(power);
} }
} }

View file

@ -34,6 +34,8 @@
// //
#include "nel/net/message.h" #include "nel/net/message.h"
#include "game_share/visual_fx.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
using namespace NLNET; using namespace NLNET;
@ -187,6 +189,15 @@ CGameItemPtr CTPTimedAction::getAndUnlockTP(CEntityBase *actor)
// unlock item, Tp player and destroy item // unlock item, Tp player and destroy item
character->unLockItem(INVENTORIES::bag, ticketSlot,1); character->unLockItem(INVENTORIES::bag, ticketSlot,1);
// Remove fx
CMirrorPropValue<TYPE_VISUAL_FX> visualFx( TheDataset, character->getEntityRowId(), DSPropertyVISUAL_FX );
CVisualFX fx;
fx.unpack(visualFx.getValue());
fx.Aura = MAGICFX::NoAura;
sint64 prop;
fx.pack(prop);
visualFx = (sint16)prop;
return item; return item;
} }

View file

@ -25,6 +25,8 @@
#include "nel/misc/o_xml.h" #include "nel/misc/o_xml.h"
#include "nel/misc/i_xml.h" #include "nel/misc/i_xml.h"
#include "nel/misc/path.h" #include "nel/misc/path.h"
#include "nel/misc/md5.h"
#include "nel/misc/sha1.h"
#include "nel/misc/vectord.h" #include "nel/misc/vectord.h"
#include "nel/misc/vector_2d.h" #include "nel/misc/vector_2d.h"
#include "nel/misc/sstring.h" #include "nel/misc/sstring.h"
@ -217,6 +219,7 @@ CVariable<uint32> NBLoginStats("egs","NBLoginStats", "Nb logins stats kept (logo
// Max Bonus/malus/consumable effects displayed by client (database corresponding array must have the same size, and client must process the same size) // Max Bonus/malus/consumable effects displayed by client (database corresponding array must have the same size, and client must process the same size)
const uint32 MaxBonusMalusDisplayed = 12; const uint32 MaxBonusMalusDisplayed = 12;
const string randomStrings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789#";
// We use this constant instead of the _StartingCharacteristicValues because _StartingCharacteristicValues is not working // We use this constant instead of the _StartingCharacteristicValues because _StartingCharacteristicValues is not working
//TODO //TODO
//const uint32 StartCharacteristicsValue = 10; //const uint32 StartCharacteristicsValue = 10;
@ -4206,6 +4209,20 @@ void CCharacter::setName(const ucstring &name)
} }
} }
//-----------------------------------------------
// CCharacter::haveBrick check if player have the brick
//-----------------------------------------------
bool CCharacter::haveBrick( const CSheetId& brickId )
{
const CStaticBrick* brickForm = CSheets::getSBrickForm( brickId );
if( brickForm )
{
// if brick already known, just return
if ( _KnownBricks.find( brickId ) != _KnownBricks.end())
return true;
}
return false;
}
//----------------------------------------------- //-----------------------------------------------
// CCharacter::addKnownBrick add a know brick // CCharacter::addKnownBrick add a know brick
@ -13329,6 +13346,144 @@ uint16 CCharacter::getFirstFreeSlotInKnownPhrase()
} // getFirstFreeSlotInKnownPhrase // } // getFirstFreeSlotInKnownPhrase //
void CCharacter::sendUrl(const string &url, const string &salt)
{
string control;
if (!salt.empty())
{
string checksum = salt+url;
control = "&hmac="+getHMacSHA1((uint8*)&url[0], url.size(), (uint8*)&salt[0], salt.size()).toString();;
}
nlinfo(url.c_str());
TVectorParamCheck titleParams;
TVectorParamCheck textParams;
uint32 userId = PlayerManager.getPlayerId(getId());
std::string name = "CUSTOM_URL_"+toString(userId);
ucstring phrase = ucstring(name+"(){[WEB : "+url+control+"]}");
NLNET::CMessage msgout("SET_PHRASE");
msgout.serial(name);
msgout.serial(phrase);
sendMessageViaMirror("IOS", msgout);
uint32 titleId = STRING_MANAGER::sendStringToUser(userId, "web_transactions", titleParams);
uint32 textId = STRING_MANAGER::sendStringToUser(userId, name, textParams);
PlayerManager.sendImpulseToClient(getId(), "USER:POPUP", titleId, textId);
}
void CCharacter::addWebCommandCheck(const string &url, const string &data, const string &salt)
{
uint webCommand = getWebCommandCheck(url);
string randomString;
for (uint8 i = 0; i < 8; i++)
{
uint32 r = (uint32)((double)rand()/((double)RAND_MAX)*62);
randomString += randomStrings[r];
}
if (webCommand == INVENTORIES::NbBagSlots)
{
CGameItemPtr item = createItemInInventoryFreeSlot(INVENTORIES::bag, 1, 1, CSheetId("web_transaction.sitem"));
if (item != 0)
{
if (data.empty())
{
item->setCustomText(ucstring(url));
vector<string> infos;
NLMISC::splitString(url, "\n", infos);
sendUrl(infos[0]+"&player_eid="+getId().toString()+"&event=command_added", salt);
}
else
{
vector<string> infos;
NLMISC::splitString(data, ",", infos);
string finalData = randomString+infos[0];
for (uint i = 1; i < infos.size(); i++)
{
finalData += ","+randomString+infos[i];
}
item->setCustomText(ucstring(url+"\n"+finalData));
sendUrl(url+"&player_eid="+getId().toString()+"&event=command_added&transaction_id="+randomString, salt);
}
}
}
else
{
CInventoryPtr inv = getInventory(INVENTORIES::bag);
if(inv)
{
CGameItemPtr item = inv->getItem(webCommand);
if (item != NULL && item->getStaticForm() != NULL )
{
if(item->getStaticForm()->Name == "Web Transaction"
|| item->getStaticForm()->Family == ITEMFAMILY::SCROLL)
{
string cText = item->getCustomText().toString();
if (!cText.empty())
{
vector<string> infos;
NLMISC::splitString(cText, "\n", infos);
vector<string> datas;
NLMISC::splitString(infos[1], ",", datas);
sendUrl(infos[0]+"&player_eid="+getId().toString()+"&event=command_added&transaction_id="+datas[0].substr(0, 8), salt);
}
}
}
}
}
}
uint CCharacter::getWebCommandCheck(const string &url)
{
CInventoryPtr inv = getInventory(INVENTORIES::bag);
if(inv)
{
for(uint i = 0; i < INVENTORIES::NbBagSlots; ++i)
{
CGameItemPtr item = inv->getItem(i);
if (item != NULL && item->getStaticForm() != NULL )
{
if(item->getStaticForm()->Name == "Web Transaction"
|| item->getStaticForm()->Family == ITEMFAMILY::SCROLL)
{
string cText = item->getCustomText().toString();
if (!cText.empty())
{
vector<string> infos;
NLMISC::splitString(cText, "\n", infos);
if (infos.size() == 2)
{
if (infos[0] == url)
{
return i;
}
}
}
}
}
}
}
return INVENTORIES::NbBagSlots;
}
uint CCharacter::checkWebCommand(const string &url, const string &data, const string &hmac, const string &salt)
{
if (salt.empty())
return INVENTORIES::NbBagSlots;
uint slot = getWebCommandCheck(url);
if (slot == INVENTORIES::NbBagSlots)
return slot;
string checksum = url + data + getId().toString();
string realhmac = getHMacSHA1((uint8*)&checksum[0], checksum.size(), (uint8*)&salt[0], salt.size()).toString();
if (realhmac == hmac)
return slot;
return INVENTORIES::NbBagSlots;
}
//----------------------------------------------- //-----------------------------------------------
// getAvailablePhrasesList // getAvailablePhrasesList
//----------------------------------------------- //-----------------------------------------------
@ -13726,9 +13881,12 @@ void CCharacter::setFameValuePlayer(uint32 factionIndex, sint32 playerFame, sint
{ {
sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx); sint32 fame = CFameInterface::getInstance().getFameIndexed(_Id, fameIdx);
if (fame >= PVPFameRequired*6000) { if (fame >= PVPFameRequired*6000)
{
canPvp = true; canPvp = true;
} else if (fame <= -PVPFameRequired*6000) { }
else if (fame <= -PVPFameRequired*6000)
{
canPvp = true; canPvp = true;
} }
} }
@ -14576,7 +14734,7 @@ void CCharacter::addPlayerToIgnoreList(const NLMISC::CEntityId &id)
// update ios state // update ios state
uint32 playerId = PlayerManager.getPlayerId(id); uint32 playerId = PlayerManager.getPlayerId(id);
CPlayer *player = PlayerManager.getPlayer( playerId ); CPlayer *player = PlayerManager.getPlayer( playerId );
if ( (!player) || (!player->havePriv( ":SGM:GM:VG:SG:G:" )) ) // if online, messages from CSRs can't be ignored if ( (!player) || (!player->havePriv( ":SGM:GM:VG:SG:G:EM:EG:" )) ) // if online, messages from CSRs can't be ignored
{ {
CEntityId senderId = getId(); CEntityId senderId = getId();
CEntityId ignoredId = id; CEntityId ignoredId = id;
@ -15078,7 +15236,7 @@ void CCharacter::online(bool onlineStatus)
// if the character has a CSR grade, remove from all ignore lists // if the character has a CSR grade, remove from all ignore lists
if ( onlineStatus && (! _IsIgnoredBy.empty()) && havePriv( ":SGM:GM:VG:SG:G:" ) ) if ( onlineStatus && (! _IsIgnoredBy.empty()) && havePriv( ":SGM:GM:VG:SG:G:EM:EG:" ) )
{ {
CMessage msgout( "UNIGNORE_ALL" ); CMessage msgout( "UNIGNORE_ALL" );
msgout.serial( _Id ); msgout.serial( _Id );
@ -15267,6 +15425,8 @@ void CCharacter::onConnection()
{ {
IShardUnifierEvent::getInstance()->charConnected(_Id, getLastDisconnectionDate()); IShardUnifierEvent::getInstance()->charConnected(_Id, getLastDisconnectionDate());
} }
CPVPManager2::getInstance()->playerConnects(this);
} }
//-------------------------------------------------------------- //--------------------------------------------------------------

View file

@ -702,6 +702,9 @@ public:
/// add a known brick /// add a known brick
void addKnownBrick( const NLMISC::CSheetId& brickId ); void addKnownBrick( const NLMISC::CSheetId& brickId );
/// check if have brick
bool haveBrick( const NLMISC::CSheetId& brickId );
/// remove a known brick /// remove a known brick
void removeKnownBrick( const NLMISC::CSheetId& brickId ); void removeKnownBrick( const NLMISC::CSheetId& brickId );
@ -1608,6 +1611,18 @@ public:
/// get ammo item /// get ammo item
virtual CGameItemPtr getAmmoItem() const; virtual CGameItemPtr getAmmoItem() const;
/// send custom url
void sendUrl(const std::string &url, const std::string &salt);
/// add web command validation check
void addWebCommandCheck(const std::string &url, const std::string &data, const std::string &salt);
/// get web command validation check
uint getWebCommandCheck(const std::string &url);
/// validate web command. Return web command item index in bag if command is valid or INVENTORIES::NbBagSlots if not
uint checkWebCommand(const std::string &url, const std::string &data, const std::string &hmac, const std::string &salt);
/// get the available phrases /// get the available phrases
void getAvailablePhrasesList(const std::string &brickFilter, std::vector<NLMISC::CSheetId> &selectedPhrases, EGSPD::CPeople::TPeople people = EGSPD::CPeople::Common, bool bypassBrickRequirements = false, bool includeNonRolemasterBricks = true ); void getAvailablePhrasesList(const std::string &brickFilter, std::vector<NLMISC::CSheetId> &selectedPhrases, EGSPD::CPeople::TPeople people = EGSPD::CPeople::Common, bool bypassBrickRequirements = false, bool includeNonRolemasterBricks = true );
@ -1833,7 +1848,6 @@ public:
void setLastPosXInDB(sint32 x); void setLastPosXInDB(sint32 x);
/// set last Y pos in DB (for teammates) /// set last Y pos in DB (for teammates)
void setLastPosYInDB(sint32 y); void setLastPosYInDB(sint32 y);
/// \name Friend/Ignore lists management. /// \name Friend/Ignore lists management.
@ -3410,6 +3424,8 @@ private:
// duel opponent // duel opponent
CCharacter * _DuelOpponent; CCharacter * _DuelOpponent;
TAIAlias _LastCreatedNpcGroup;
// :KLUDGE: ICDBStructNode non-const 'coz getName and getParent are not // :KLUDGE: ICDBStructNode non-const 'coz getName and getParent are not
// const methods. See CCDBSynchronised::getICDBStructNodeFromName for more // const methods. See CCDBSynchronised::getICDBStructNodeFromName for more
// info. // info.

View file

@ -72,6 +72,9 @@
#include "server_share/log_item_gen.h" #include "server_share/log_item_gen.h"
#include "egs_dynamic_sheet_manager.h" #include "egs_dynamic_sheet_manager.h"
#include "game_share/visual_fx.h"
#include "game_share/teleport_types.h"
/////////// ///////////
// USING // // USING //
/////////// ///////////
@ -2439,7 +2442,22 @@ void CCharacter::sendItemInfos( uint16 slotId )
infos.TypeSkillMods = item->getTypeSkillMods(); infos.TypeSkillMods = item->getTypeSkillMods();
infos.CustomText = item->getCustomText(); // Special case of web missions items
if (item->getStaticForm()->Name == "Web Transaction" || item->getStaticForm()->Family == ITEMFAMILY::SCROLL)
{
string cText = item->getCustomText().toString();
string::size_type sPos = cText.find(" ");
string::size_type ePos = cText.find("\n---\n");
if (sPos != string::npos && sPos != (cText.length()-1) && ePos != string::npos && ePos != (cText.length()-1))
{
string cUrl = cText.substr(sPos, ePos-sPos);
infos.CustomText = ucstring("@WEBIG "+cUrl);
}
else
infos.CustomText = "";
}
else
infos.CustomText = item->getCustomText();
CMessage msgout( "IMPULSION_ID" ); CMessage msgout( "IMPULSION_ID" );
CBitMemStream bms; CBitMemStream bms;
@ -2522,11 +2540,10 @@ void CCharacter::createCrystallizedActionItem(const std::vector<NLMISC::CSheetId
// **************************************************************************** // ****************************************************************************
void CCharacter::createRechargeItem(uint32 sapRecharge) void CCharacter::createRechargeItem(uint32 sapRecharge)
{ {
static const CSheetId rechargeSheetId("item_sap_recharge.sitem");
if (!EnchantSystemEnabled) if (!EnchantSystemEnabled)
return; return;
/*** OLD METHOD **********************************************
if (!enterTempInventoryMode(TEMP_INV_MODE::Crystallize)) if (!enterTempInventoryMode(TEMP_INV_MODE::Crystallize))
return; return;
@ -2535,7 +2552,42 @@ void CCharacter::createRechargeItem(uint32 sapRecharge)
{ {
item->setSapLoad(sapRecharge); item->setSapLoad(sapRecharge);
addItemToInventory(INVENTORIES::temporary, item); addItemToInventory(INVENTORIES::temporary, item);
}******/
CInventoryPtr handlingInv = getInventory(INVENTORIES::handling);
if (handlingInv == NULL)
return;
CGameItemPtr rightHandItem = handlingInv->getItem(INVENTORIES::right); // item to reload
if (rightHandItem == NULL)
{
TVectorParamCheck params;
sendDynamicSystemMessage(_EntityRowId, "RIGHT_HAND_EMPTY", params);
return;
} }
// check the right hand holds a weapon item
const CStaticItem * form = rightHandItem->getStaticForm();
if (form == NULL)
{
nlwarning("item %s has no static form", rightHandItem->getSheetId().toString().c_str());
return;
}
if ((form->Family != ITEMFAMILY::MELEE_WEAPON) && (form->Family != ITEMFAMILY::RANGE_WEAPON))
{
TVectorParamCheck params;
sendDynamicSystemMessage(_EntityRowId, "WEAPONS_ONLY_CAN_BEEN_RECHARGED", params);
return;
}
rightHandItem->reloadSapLoad(sapRecharge);
SM_STATIC_PARAMS_3(params, STRING_MANAGER::item, STRING_MANAGER::integer, STRING_MANAGER::integer);
params[0].SheetId = rightHandItem->getSheetId();
params[1].Int = rightHandItem->sapLoad();
params[2].Int = rightHandItem->maxSapLoad();
sendDynamicSystemMessage(_EntityRowId, "ITEM_IS_RECHARGED", params);
} }
// check if enchant or recharge an item // check if enchant or recharge an item
@ -2858,6 +2910,14 @@ void CCharacter::useItem(uint32 slot)
if ( form->Family == ITEMFAMILY::TELEPORT ) if ( form->Family == ITEMFAMILY::TELEPORT )
{ {
pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> allegeance = getAllegiance();
if ((form->TpType == TELEPORT_TYPES::KAMI) && (allegeance.first == PVP_CLAN::Karavan)
|| (form->TpType == TELEPORT_TYPES::KARAVAN) && (allegeance.first == PVP_CLAN::Kami))
{
CCharacter::sendDynamicSystemMessage(_Id, "ALTAR_RESTRICTION");
return;
}
if( CPVPManager2::getInstance()->isTPValid(this, item) && IsRingShard == false ) if( CPVPManager2::getInstance()->isTPValid(this, item) && IsRingShard == false )
{ {
// teleport dont work in the same way if the user is dead or alive // teleport dont work in the same way if the user is dead or alive
@ -2892,6 +2952,35 @@ void CCharacter::useItem(uint32 slot)
_TpTicketSlot = slot; _TpTicketSlot = slot;
lockItem( INVENTORIES::bag, slot, 1 ); lockItem( INVENTORIES::bag, slot, 1 );
// add fx
CMirrorPropValue<TYPE_VISUAL_FX> visualFx( TheDataset, _EntityRowId, DSPropertyVISUAL_FX );
CVisualFX fx;
fx.unpack(visualFx.getValue());
if (allegeance.first != PVP_CLAN::None
&& allegeance.first != PVP_CLAN::Neutral
&& CFameInterface::getInstance().getFameIndexed(_Id, PVP_CLAN::getFactionIndex(allegeance.first)) >= 600000)
{
if (allegeance.first == PVP_CLAN::Kami)
{
fx.Aura = MAGICFX::TeleportKami;
}
else if (allegeance.first == PVP_CLAN::Karavan)
{
fx.Aura = MAGICFX::TeleportKara;
}
else
{
fx.Aura = MAGICFX::NoAura;
}
}
else
{
fx.Aura = MAGICFX::NoAura;
}
sint64 prop;
fx.pack(prop);
visualFx = (sint16)prop;
// add tp phrase in manager // add tp phrase in manager
static CSheetId tpBrick("bapa01.sbrick"); static CSheetId tpBrick("bapa01.sbrick");
vector<CSheetId> bricks; vector<CSheetId> bricks;
@ -2964,6 +3053,13 @@ void CCharacter::useTeleport(const CStaticItem & form)
} }
else else
{ {
CMirrorPropValue<TYPE_VISUAL_FX> visualFx( TheDataset, _EntityRowId, DSPropertyVISUAL_FX );
CVisualFX fx;
fx.unpack(visualFx.getValue());
fx.Aura = MAGICFX::NoAura;
sint64 prop;
fx.pack(prop);
visualFx = (sint16)prop;
sint32 x,y,z; sint32 x,y,z;
float theta; float theta;
zone->getRandomPoint( x,y,z,theta ); zone->getRandomPoint( x,y,z,theta );

View file

@ -2251,7 +2251,7 @@ bool CPlayerManager::hasBetterCSRGrade( CPlayer* p1, CPlayer *p2, bool devIsNorm
if ( p2->havePriv(":SGM:") ) if ( p2->havePriv(":SGM:") )
return ( p1->havePriv(":SGM:") ); return ( p1->havePriv(":SGM:") );
if ( p2->havePriv(":EM:") ) if ( p2->havePriv(":EM:") )
return ( p1->havePriv(":SGM:EM:") ); return ( p1->havePriv(":SGM:EM:GM:") );
if ( p2->havePriv(":GM:") ) if ( p2->havePriv(":GM:") )
return ( p1->havePriv(":SGM:EM:GM:") ); return ( p1->havePriv(":SGM:EM:GM:") );
if ( p2->havePriv(":EG:") ) if ( p2->havePriv(":EG:") )

View file

@ -401,12 +401,12 @@ void CCharacterProgressionPVE::creatureDeath(TDataSetRow creature)
else else
{ {
const TDataSetRow rowId = TheDataset.getDataSetRow(creatureTakenDmg.PlayerInflictedDamage[index].PlayerId); const TDataSetRow rowId = TheDataset.getDataSetRow(creatureTakenDmg.PlayerInflictedDamage[index].PlayerId);
creaturePtr->enableLootRights(rowId);
TCharacterActionsContainer::iterator it = _CharacterActions.find(rowId); TCharacterActionsContainer::iterator it = _CharacterActions.find(rowId);
if( it != _CharacterActions.end() ) if( it != _CharacterActions.end() )
{ {
// Enable loot rights for this player alone // Enable loot rights for this player alone
creaturePtr->enableLootRights(rowId);
// Display XP gain // Display XP gain
list<CEntityId> teamMembers; list<CEntityId> teamMembers;
@ -1528,6 +1528,39 @@ void CCharacterProgressionPVE::enableXpGainForPlayer(const CEntityId &playerId,
} }
} }
//----------------------------------------------------------------------------
// CCharacterProgressionPVE::removeCreature
//----------------------------------------------------------------------------
void CCharacterProgressionPVE::removeXpCreature(TDataSetRow creature)
{
TCreatureTakenDamageContainer::iterator itCreatureDamage = _CreatureTakenDamage.find(creature);
if (itCreatureDamage == _CreatureTakenDamage.end())
return;
// clear damage inflicted by players and teams on this creature
const vector<CTeamDamage> &damage = (*itCreatureDamage).second.PlayerInflictedDamage;
for (uint i = 0 ; i < damage.size() ; ++i )
{
if (damage[i].TeamId != CTEAM::InvalidTeamId)
{
// forget Xp gain on this creature for whole team
CTeam *team = TeamManager.getRealTeam(damage[i].TeamId);
if (team)
{
const list<CEntityId> &teamMembers = team->getTeamMembers();
for ( list<CEntityId>::const_iterator it = teamMembers.begin() ; it != teamMembers.end() ; ++it)
{
forgetXpGain(creature, TheDataset.getDataSetRow(*it));
}
}
}
else
{
// forget Xp gain on this creature
forgetXpGain(creature, TheDataset.getDataSetRow(damage[i].PlayerId));
}
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// CCharacterProgressionPVE::removeCreature // CCharacterProgressionPVE::removeCreature

View file

@ -272,13 +272,14 @@ struct CCreatureTakenDamage
/// return index of the team which has inflicted the most damage, returns -1 if most damage have been made by other creatures /// return index of the team which has inflicted the most damage, returns -1 if most damage have been made by other creatures
sint16 getMaxInflictedDamageTeamIndex() sint16 getMaxInflictedDamageTeamIndex()
{ {
float maxDmg = TotalCreatureInflictedDamage; float maxDmg = 0;//TotalCreatureInflictedDamage;
sint16 index = -1; sint16 index = -1;
const uint size = (uint)PlayerInflictedDamage.size(); const uint size = (uint)PlayerInflictedDamage.size();
for ( uint i = 0 ; i < size ; ++i) for ( uint i = 0 ; i < size ; ++i)
{ {
if ( PlayerInflictedDamage[i].TotalDamage > maxDmg ) if ( PlayerInflictedDamage[i].TotalDamage > maxDmg )
{ {
nlinfo("set damage by player");
maxDmg = PlayerInflictedDamage[i].TotalDamage; maxDmg = PlayerInflictedDamage[i].TotalDamage;
index = (sint16)i; index = (sint16)i;
} }
@ -450,6 +451,8 @@ public:
void addDamage(const NLMISC::CEntityId &actorId, const NLMISC::CEntityId &targetId, uint32 damage); void addDamage(const NLMISC::CEntityId &actorId, const NLMISC::CEntityId &targetId, uint32 damage);
/// enable Xp Gain for a player, set a list with all creatures on which he now has possible Xp Gain /// enable Xp Gain for a player, set a list with all creatures on which he now has possible Xp Gain
void enableXpGainForPlayer(const NLMISC::CEntityId &playerId, uint16 skillValue, std::list<TDataSetRow> &enabledCreatures); void enableXpGainForPlayer(const NLMISC::CEntityId &playerId, uint16 skillValue, std::list<TDataSetRow> &enabledCreatures);
/// remove xp from a creature (so clear all references on it)
void removeXpCreature(TDataSetRow creature);
/// remove a creature (so clear all references on it) /// remove a creature (so clear all references on it)
void removeCreature(TDataSetRow creature); void removeCreature(TDataSetRow creature);
/// apply regen of a creature /// apply regen of a creature

View file

@ -827,6 +827,9 @@ void CRewardedKills::addRewardedKill(NLMISC::CEntityId victimId, const std::vect
for (uint i = 0; i < killers.size(); i++) for (uint i = 0; i < killers.size(); i++)
{ {
addRewardedKiller(CRewardedKiller(killers[i], currentDate), rewardedKillers); addRewardedKiller(CRewardedKiller(killers[i], currentDate), rewardedKillers);
CCharacter *killer = PlayerManager.getChar(killers[i]);
CMissionEventKillPlayer killevent( TheDataset.getDataSetRow(victimId) );
killer->processMissionEvent( killevent );
} }
} }

View file

@ -344,6 +344,42 @@ void CPVPManager2::updateFactionChannel(CCharacter * user, bool b )
*/ */
} }
void CPVPManager2::broadcastMessage(TChanID channel, const ucstring& speakerName, const ucstring& txt)
{
CMessage msgout("DYN_CHAT:SERVICE_CHAT");
msgout.serial(channel);
msgout.serial(const_cast<ucstring&>(speakerName));
msgout.serial(const_cast<ucstring&>(txt));
sendMessageViaMirror("IOS", msgout);
}
void CPVPManager2::sendChannelUsers(TChanID channel, CCharacter * user)
{
std::vector<NLMISC::CEntityId> lst;
TChannelsCharacter::iterator it = _UserChannelCharacters.find(channel);
if(it != _UserChannelCharacters.end())
{
lst = (*it).second;
string players = "";
for (uint i = 0; i < lst.size(); i++)
{
players += "\n"+CEntityIdTranslator::getInstance()->getByEntity(lst[i]).toString();
}
CMessage msgout("DYN_CHAT:SERVICE_TELL");
msgout.serial(channel);
ucstring users = ucstring("<USERS>");
msgout.serial(const_cast<ucstring&>(users));
TDataSetRow senderRow = TheDataset.getDataSetRow(user->getId());
msgout.serial(senderRow);
ucstring txt = ucstring(players);
msgout.serial(const_cast<ucstring&>(txt));
sendMessageViaMirror( "IOS", msgout);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight, bool userChannel) void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight, bool userChannel)
{ {
@ -361,6 +397,23 @@ void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * us
currentChannels.push_back(channel); currentChannels.push_back(channel);
_CharacterUserChannels.erase(user->getId()); _CharacterUserChannels.erase(user->getId());
_CharacterUserChannels.insert( make_pair(user->getId(), currentChannels) ); _CharacterUserChannels.insert( make_pair(user->getId(), currentChannels) );
TChannelsCharacter::iterator it = _UserChannelCharacters.find(channel);
if (it == _UserChannelCharacters.end())
{
std::vector<NLMISC::CEntityId> vect;
vect.push_back(user->getId());
_UserChannelCharacters[channel] = vect;
}
else
{
(*it).second.push_back(user->getId());
}
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(user->getId()).toString();
broadcastMessage(channel, string("<INFO>"), "<-- "+playerName);
sendChannelUsers(channel, user);
} }
} }
} }
@ -369,22 +422,40 @@ void CPVPManager2::addFactionChannelToCharacter(TChanID channel, CCharacter * us
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void CPVPManager2::removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel) void CPVPManager2::removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel)
{ {
std::vector<TChanID> currentChannels = getCharacterRegisteredChannels(user); std::vector<TChanID> currentChannels;
if (channel == DYN_CHAT_INVALID_CHAN) // Send leaves message to all user channels
{
currentChannels = getCharacterUserChannels(user);
for (uint i = 0; i < currentChannels.size(); i++)
{
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(user->getId()).toString();
broadcastMessage(currentChannels[i], string("<INFO>"), playerName+" -->[]");
}
}
if (userChannel)
{
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(user->getId()).toString();
broadcastMessage(channel, string("<INFO>"), playerName+" -->[]");
}
currentChannels = getCharacterRegisteredChannels(user);
for (uint i = 0; i < currentChannels.size(); i++) for (uint i = 0; i < currentChannels.size(); i++)
{ {
if (currentChannels[i] == channel) if ((currentChannels[i] == channel))
{ {
DynChatEGS.removeSession(channel, user->getEntityRowId()); DynChatEGS.removeSession(currentChannels[i], user->getEntityRowId());
if (userChannel && (DynChatEGS.getSessionCount(channel) == 0)) if (userChannel && (DynChatEGS.getSessionCount(currentChannels[i]) == 0))
{ {
DynChatEGS.removeChan(channel); DynChatEGS.removeChan(currentChannels[i]);
TMAPPassChannel::iterator it = _PassChannels.find(channel); TMAPPassChannel::iterator it = _PassChannels.find(currentChannels[i]);
if (it != _PassChannels.end()) if (it != _PassChannels.end())
_PassChannels.erase(it); _PassChannels.erase(it);
for (TMAPExtraFactionChannel::iterator it2 = _UserChannel.begin(); it2 != _UserChannel.end(); ++it2) for (TMAPExtraFactionChannel::iterator it2 = _UserChannel.begin(); it2 != _UserChannel.end(); ++it2)
{ {
if ((*it2).second == channel) if ((*it2).second == currentChannels[i])
_UserChannel.erase(it2); _UserChannel.erase(it2);
} }
} }
@ -416,6 +487,14 @@ void CPVPManager2::removeFactionChannelForCharacter(TChanID channel, CCharacter
_CharacterUserChannels.insert(make_pair(user->getId(), currentChannels)); _CharacterUserChannels.insert(make_pair(user->getId(), currentChannels));
} }
} }
TChannelsCharacter::iterator cit = _UserChannelCharacters.find(channel);
if (cit != _UserChannelCharacters.end())
{
std::vector<NLMISC::CEntityId> lst = _UserChannelCharacters[channel];
lst.erase(find(lst.begin(), lst.end(), user->getId()));
_UserChannelCharacters[channel] = lst;
}
} }
} }
} }
@ -437,6 +516,17 @@ void CPVPManager2::addRemoveFactionChannelToUserWithPriviledge(TChanID channel,
} }
//----------------------------------------------------------------------------
void CPVPManager2::playerConnects(CCharacter * user)
{
std::vector<TChanID> currentChannels = getCharacterUserChannels(user);
for (uint i = 0; i < currentChannels.size(); i++)
{
const string playerName = CEntityIdTranslator::getInstance()->getByEntity(user->getId()).toString();
broadcastMessage(currentChannels[i], string("<INFO>"), "<-- "+playerName);
}
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void CPVPManager2::playerDisconnects(CCharacter * user) void CPVPManager2::playerDisconnects(CCharacter * user)
{ {

View file

@ -88,12 +88,18 @@ public:
std::vector<TChanID> getCharacterRegisteredChannels(CCharacter * user); std::vector<TChanID> getCharacterRegisteredChannels(CCharacter * user);
/// return dynamic user channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no user channel /// return dynamic user channel TChanId subscribed by character, DYN_CHAT_INVALID_CHAN if character have no user channel
std::vector<TChanID> getCharacterUserChannels(CCharacter * user); std::vector<TChanID> getCharacterUserChannels(CCharacter * user);
// brodcast message to channel
void broadcastMessage(TChanID channel, const ucstring& speakerName ,const ucstring& txt);
// send list of users to player
void sendChannelUsers(TChanID channel, CCharacter * user);
// add faction channel to character if needed // add faction channel to character if needed
void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false); void addFactionChannelToCharacter(TChanID channel, CCharacter * user, bool writeRight = true, bool userChannel = false);
// remove faction channel for character // remove faction channel for character
void removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel = false); void removeFactionChannelForCharacter(TChanID channel, CCharacter * user, bool userChannel = false);
// add/remove faction channel to this character with privilege // add/remove faction channel to this character with privilege
void addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s = true ); void addRemoveFactionChannelToUserWithPriviledge(TChanID channel, CCharacter * user, bool s = true );
/// handle player connection
void playerConnects(CCharacter * user);
/// handle player disconnection /// handle player disconnection
void playerDisconnects(CCharacter * user); void playerDisconnects(CCharacter * user);
/// handle to add or remove faction channel to player of needed /// handle to add or remove faction channel to player of needed
@ -201,6 +207,8 @@ private:
TMAPFactionChannel _FactionChannel; TMAPFactionChannel _FactionChannel;
TMAPExtraFactionChannel _ExtraFactionChannel; TMAPExtraFactionChannel _ExtraFactionChannel;
TMAPExtraFactionChannel _UserChannel; TMAPExtraFactionChannel _UserChannel;
typedef std::map< TChanID, std::vector<NLMISC::CEntityId> > TChannelsCharacter;
TChannelsCharacter _UserChannelCharacters;
TMAPPassChannel _PassChannels; TMAPPassChannel _PassChannels;
/// character registered channel /// character registered channel
typedef std::map< NLMISC::CEntityId, std::vector<TChanID> > TCharacterChannels; typedef std::map< NLMISC::CEntityId, std::vector<TChanID> > TCharacterChannels;