Add infos into target window
[ryzomcore.git] / ryzom / server / src / sabrina / phrase_utilities_functions.cpp
blobf659f202f75ef291ed50144ccab9f1cd747e14df
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
22 #include "phrase_utilities_functions.h"
23 #include "egs_mirror.h"
25 // game share
26 #include "game_share/mode_and_behaviour.h"
27 #include "game_share/tick_event_handler.h"
28 #include "game_share/msg_combat_move_service.h"
29 #include "game_share/characteristics.h"
30 // georges
31 #include "nel/georges/u_form.h"
32 #include "nel/georges/u_form_elm.h"
33 #include "nel/georges/u_form_loader.h"
34 // misc
35 #include "nel/misc/command.h"
36 // std
37 #include <map>
40 #include "player_manager.h"
41 #include "phrase_manager.h"
42 #include "creature_manager.h"
43 #include "egs_globals.h"
46 extern uint8 CMSIsUp;
47 extern CPlayerManager PlayerManager;
48 extern CCreatureManager CreatureManager;
49 extern CGameItemManager GameItemManager;
50 extern CPhraseManager *PhraseManager;
51 extern bool AllowPVP;
54 extern uint8 EntityForcedDefaultLevel; // 0 by default, it's the level of an entity when it has a level 0 (for tests purposes only)
56 extern CGenericXmlMsgHeaderManager GenericMsgManager;
58 using namespace std;
59 using namespace NLGEORGES;
60 using namespace NLMISC;
61 using namespace NLNET;
64 bool VerboseBrickManagerInfo = false;
65 bool VerboseBrickManagerDbg = false;
66 bool AggroLog = false;
68 NLMISC_COMMAND(verboseBrickManagerInfo,"Turn on or off or check the state of verbose brick manager logging (for info)","")
70 if(args.size()>1)
71 return false;
72 if(args.size()==1)
74 if(args[0]==string("on")||args[0]==string("ON")||args[0]==string("true")||args[0]==string("TRUE")||args[0]==string("1"))
75 VerboseBrickManagerInfo=true;
77 if(args[0]==string("off")||args[0]==string("OFF")||args[0]==string("false")||args[0]==string("FALSE")||args[0]==string("0"))
78 VerboseBrickManagerInfo=false;
81 log.displayNL("VerboseBrickManagerInfo is %s",VerboseBrickManagerInfo?"ON":"OFF");
82 return true;
85 // debug msg
86 NLMISC_COMMAND(verboseBrickManagerDbg,"Turn on or off or check the state of verbose brick manager logging (for debug)","")
88 if(args.size()>1)
89 return false;
90 if(args.size()==1)
92 if(args[0]==string("on")||args[0]==string("ON")||args[0]==string("true")||args[0]==string("TRUE")||args[0]==string("1"))
93 VerboseBrickManagerDbg=true;
95 if(args[0]==string("off")||args[0]==string("OFF")||args[0]==string("false")||args[0]==string("FALSE")||args[0]==string("0"))
96 VerboseBrickManagerDbg=false;
99 log.displayNL("VerboseBrickManagerDbg is %s",VerboseBrickManagerDbg?"ON":"OFF");
100 return true;
103 // aggro msg
104 NLMISC_COMMAND(aggroLog,"Turn on or off aggro log display or check the state of the flag","")
106 if(args.size()>1)
107 return false;
108 if(args.size()==1)
110 if(args[0]==string("on")||args[0]==string("ON")||args[0]==string("true")||args[0]==string("TRUE")||args[0]==string("1"))
111 AggroLog=true;
113 if(args[0]==string("off")||args[0]==string("OFF")||args[0]==string("false")||args[0]==string("FALSE")||args[0]==string("0"))
114 AggroLog=false;
117 log.displayNL("AggroLog is %s",AggroLog?"ON":"OFF");
118 return true;
123 namespace PHRASE_UTILITIES
125 std::string toString(ERange range)
127 switch(range)
129 case POINT_BLANK:
130 return std::string("POINT_BLANK");
131 case SHORT_RANGE:
132 return std::string("SHORT_RANGE");
133 case MEDIUM_RANGE:
134 return std::string("MEDIUM_RANGE");
135 case LONG_RANGE:
136 return std::string("LONG_RANGE");
137 default:
138 return std::string("UNDEFINED");
142 typedef set< SLocalisation > TLocalisationSet;
144 /// table of damage localisation (take shield into account)
145 TLocalisationSet LocalisationTable;
147 /// the table giving the localisation adjustement for the specified attacker and defender size
148 sint8 LocalisationAdjustments[CREATURE_SIZE::NB_SIZE][CREATURE_SIZE::NB_SIZE];
151 static string OrientationStrings[]=
153 "W",
154 "WSW",
155 "SW",
156 "SSW",
157 "S",
158 "SSE",
159 "SE",
160 "ESE",
161 "E",
162 "ENE",
163 "NE",
164 "NNE",
165 "N",
166 "NNW",
167 "NW",
168 "WNW",
172 //--------------------------------------------------------------
173 // entityPtrFromId()
174 //--------------------------------------------------------------
175 CEntityBase* entityPtrFromId( const CEntityId &id )
177 switch( id.getType() )
179 case RYZOMID::player:
180 return PlayerManager.getChar( id );
181 break;
183 case RYZOMID::npc:
184 case RYZOMID::creature:
185 case RYZOMID::kami:
186 return CreatureManager.getCreature( id );
187 break;
189 default:
190 nlwarning( "<entityPtrFromId> entity type %d unknown", id.getType(), id.toString().c_str() );
191 return 0;
195 //--------------------------------------------------------------
196 // loadLocalisationTable()
197 //--------------------------------------------------------------
198 void loadLocalisationTable( const std::string &tableName )
200 UFormLoader *loader = UFormLoader::createLoader ();
202 CSmartPtr<UForm> form = loader->loadForm (tableName.c_str());
203 if ( !form)
205 nlwarning("<loadLocalisationTable> Failed to load the form %s", tableName.c_str() );
206 return;
209 // Get the root node, always exist
210 UFormElm &root = form->getRootNode ();
212 const UFormElm *array = NULL;
213 // lines
214 if (root.getNodeByName (&array, "Lines") && array)
216 // Get array size
217 uint size;
218 array->getArraySize (size);
220 // Get a array value
221 for (uint i=0; i<size; ++i)
223 const UFormElm *line = NULL;
224 if ( array->getArrayNode( &line, i) && line)
226 SLocalisation localisation;
227 // the localisation number
228 line->getValueByName( localisation.LocalisationNumber, "ValueNumber" );
230 string shield;
231 // the type of shield
232 line->getValueByName( shield, "ShieldType" );
233 localisation.ShieldType = SHIELDTYPE::stringToShieldType( shield );
235 string slot;
236 line->getValueByName( slot, "Localisation" );
237 localisation.Slot = SLOT_EQUIPMENT::stringToSlotEquipment( slot);
239 line->getValueByName( localisation.ShieldIsEffective, "ProtectionWorks" );
241 LocalisationTable.insert( localisation );
243 //nlinfo("loadLocalisationTable : for value %d and shield %s, localisation=%s, shield=%d",localisation.LocalisationNumber, shield.c_str(), slot.c_str(), localisation.ShieldIsEffective);
247 } // loadLocalisationTable //
253 //--------------------------------------------------------------
254 // loadLocalisationSizeAdjusmentTable()
255 //--------------------------------------------------------------
256 void loadLocalisationSizeAdjusmentTable( const std::string &tableName )
258 UFormLoader *loader = UFormLoader::createLoader ();
260 CSmartPtr<UForm> form = loader->loadForm (tableName.c_str());
261 if ( !form)
263 nlwarning("<loadLocalisationSizeAdjusmentTable> Failed to load the form %s", tableName.c_str() );
264 return;
267 // Get the root node, always exist
268 UFormElm &root = form->getRootNode ();
270 const UFormElm *array = NULL;
271 // lines
272 if (root.getNodeByName (&array, "Table") && array)
274 // Get array size
275 uint size;
276 array->getArraySize (size);
278 // Get a array value
279 for (uint i=0; i<size; ++i)
281 const UFormElm *line = NULL;
282 if ( array->getArrayNode( &line, i) && line)
284 string attacker;
285 line->getValueByName( attacker, "AttackerSize" );
286 CREATURE_SIZE::ECreatureSize attackerSize = CREATURE_SIZE::stringToCreatureSize( attacker );
288 string defender;
289 line->getValueByName( defender, "DefenderSize" );
290 CREATURE_SIZE::ECreatureSize defenderSize = CREATURE_SIZE::stringToCreatureSize( defender );
292 sint8 modifier;
293 line->getValueByName( modifier, "Adjustment" );
295 if ( attackerSize > CREATURE_SIZE::NB_SIZE || defenderSize > CREATURE_SIZE::NB_SIZE || attackerSize < 0 || defenderSize < 0)
297 nlwarning("<loadLocalisationSizeAdjusmentTable> Invalid line, attacker size = %s, defender size = %s", attacker.c_str(), defender.c_str() );
298 continue;
302 LocalisationAdjustments[attackerSize][defenderSize] = modifier;
306 } // loadLocalisationSizeAdjusmentTable //
309 //--------------------------------------------------------------
310 // getSuccessChance()
311 //--------------------------------------------------------------
312 uint8 getSuccessChance( sint32 playerRelativeLevel )
314 // clip delta level to min / max value
315 if( playerRelativeLevel > MAX_DELTA_LVL ) playerRelativeLevel = MAX_DELTA_LVL;
316 if( playerRelativeLevel < MIN_DELTA_LVL ) playerRelativeLevel = MIN_DELTA_LVL;
318 return (uint8) CEntityBaseManager::_SuccessXpTable[ MIDDLE_DELTA_LVL - playerRelativeLevel ].SuccessProbability;
319 } // getSuccessChance //
322 //--------------------------------------------------------------
323 // getSuccessFactor()
324 // Return SF (Success Factor) > 1 if critical success
325 // Return SF = 1 if success
326 // Return 1 < SF < 0 if partial success
327 // Return SF = 0 if Failure
328 // Return SF < 0 if Critical Failure
329 //--------------------------------------------------------------
330 float getSucessFactor( uint8 chances, uint8 tirage )
332 // Check if critical success
333 if( float(CEntityBaseManager::_SuccessTable.CriticalSuccess * chances) / float( CEntityBaseManager::_SuccessTable.CriticalSuccess + CEntityBaseManager::_SuccessTable.Success ) > float(tirage) ) return 1.1f;
335 // Check if Success
336 if( chances > tirage ) return 1.0f;
338 // Check if Partial Success
339 const uint8 pSChance = (uint8) (float(CEntityBaseManager::_SuccessTable.PartialSuccess) / float(CEntityBaseManager::_SuccessTable.PartialSuccess + CEntityBaseManager::_SuccessTable.Failure + CEntityBaseManager::_SuccessTable.CriticalFailure) * (100.0f-chances));
340 if ( pSChance > (tirage-chances) )
342 return ( float(pSChance - tirage + chances) / float(pSChance));
345 // Check if Failure
346 if( ( float(CEntityBaseManager::_SuccessTable.PartialSuccess + CEntityBaseManager::_SuccessTable.Failure ) / float(CEntityBaseManager::_SuccessTable.PartialSuccess + CEntityBaseManager::_SuccessTable.Failure + CEntityBaseManager::_SuccessTable.CriticalFailure ) * (100.0f-chances) ) > float(tirage-chances) )
347 return 0.0f;
349 // stay Critical Failure
350 return -1.0f;
354 //--------------------------------------------------------------
355 // testTargetValidityForCombat()
356 //--------------------------------------------------------------
357 bool testTargetValidityForCombat( const CEntityId &targetId, string &errorCode )
359 switch ( targetId.getType() )
361 case RYZOMID::player:
362 break;
364 case RYZOMID::creature:
365 case RYZOMID::kami:
366 case RYZOMID::npc:
367 case RYZOMID::mount:
369 CCreature* entity = CreatureManager.getCreature( targetId );
370 if (entity == NULL)
372 nlwarning("<testTargetValidityForCombat> Invalid entity Id %s", targetId.toString().c_str() );
373 errorCode = "BS_INVALID_TARGET";
374 return false;
378 // get creature form
379 const CSheetId &sheet = entity->getType();
381 const CStaticCreatures *creature = CSheets::getCreaturesForm( sheet );
382 if ( ! creature)
384 nlwarning("<testTargetValidityForCombat> can't found CStaticCreature for entity %s", targetId.toString().c_str() );
385 errorCode = "BS_INVALID_TARGET";
386 return false;
390 if ( ! entity->getContextualProperty().getValue().attackable() )
392 errorCode = "BS_TARGET_NOT_ATTACKABLE";
393 return false;
397 break;
399 default:
400 break;
404 return true;
405 } // testTargetValidityForCombat //
409 //--------------------------------------------------------------
410 // getLocalisation()
411 //--------------------------------------------------------------
412 TPairSlotShield getLocalisation( SHIELDTYPE::EShieldType shield, sint8 adjustement, SLOT_EQUIPMENT::TSlotEquipment forcedSlot)
414 TPairSlotShield slotShield;
415 SLocalisation local;
417 if ( forcedSlot == SLOT_EQUIPMENT::UNDEFINED)
419 sint32 randVal = RandomGenerator.rand() + adjustement;
420 if (randVal < 0)
421 randVal = 0;
423 local.LocalisationNumber = randVal%10 + 1;
424 local.ShieldType = shield;
426 TLocalisationSet::iterator it = LocalisationTable.find( local );
427 if (it != LocalisationTable.end() )
429 slotShield.first = (*it).Slot;
430 slotShield.second = (*it).ShieldIsEffective;
432 else
434 slotShield.first = SLOT_EQUIPMENT::UNDEFINED;
435 slotShield.second = false;
438 else
440 TLocalisationSet subTable;
441 TLocalisationSet::iterator it;
442 for (it = LocalisationTable.begin() ; it != LocalisationTable.end() ; ++it)
444 uint8 val = 0;
445 if ( (*it).ShieldType == shield && (*it).Slot == forcedSlot )
447 SLocalisation local;
448 local.LocalisationNumber = ++val;
449 local.ShieldType = shield;
450 local.ShieldIsEffective = (*it).ShieldIsEffective;
451 local.Slot = forcedSlot;
453 subTable.insert( local );
457 if ( subTable.empty() == true )
459 slotShield.first = SLOT_EQUIPMENT::UNDEFINED;
460 slotShield.second = false;
462 else
464 local.LocalisationNumber = 1 + (uint8)RandomGenerator.rand(subTable.size()-1);
465 local.ShieldType = shield;
467 it = subTable.find( local );
468 if (it != subTable.end() )
470 slotShield.first = (*it).Slot;
471 slotShield.second = (*it).ShieldIsEffective;
473 else
475 slotShield.first = SLOT_EQUIPMENT::UNDEFINED;
476 slotShield.second = false;
481 INFOLOG("<getLocalisation> with shield %d, with forced slot %d, localisation is slot %d, and shield is %d (0=inactive) (random value is %u)", shield, forcedSlot, slotShield.first, slotShield.second, local.LocalisationNumber );
483 return slotShield;
484 } // getLocalisation //
488 //--------------------------------------------------------------
489 // getLocalisationSizeAdjustement()
490 //--------------------------------------------------------------
491 sint8 getLocalisationSizeAdjustement( const CEntityId &attacker, const CEntityId &defender )
493 CREATURE_SIZE::ECreatureSize attackerSize, defenderSize;
495 CEntityBase* entity = entityPtrFromId( attacker );
496 if (entity == NULL)
498 nlwarning("<getLocalisationSizeAdjustement> Invalid entity Id %s", attacker.toString().c_str() );
499 return 0;
502 attackerSize = entity->getSize();
504 entity = entityPtrFromId( defender );
505 if (entity == NULL)
507 nlwarning("<getLocalisationSizeAdjustement> Invalid entity Id %s", defender.toString().c_str() );
508 return 0;
511 defenderSize = entity->getSize();
513 if ( attackerSize > CREATURE_SIZE::NB_SIZE || defenderSize > CREATURE_SIZE::NB_SIZE || attackerSize < 0 || defenderSize < 0)
515 return 0;
518 return LocalisationAdjustments[attackerSize][defenderSize];
519 } // getLocalisationSizeAdjustement //
522 //--------------------------------------------------------------
523 // getWeaponDamageFactor()
524 //--------------------------------------------------------------
525 float getWeaponDamageFactor( WEAPONTYPE::EWeaponType type, uint16 quality, uint16 entityLevel )
527 if (quality > 21)
528 quality = 21;
530 if (quality == 0)
531 return float(0);
533 switch(type)
535 case WEAPONTYPE::LIGHT:
536 case WEAPONTYPE::LIGHT_GUN:
538 if ( entityLevel > 0 && entityLevel > quality)
539 return TableLightMeleeWeaponGenerics[quality-1].secondaryDamageFactor;
540 else
541 return TableLightMeleeWeaponGenerics[quality-1].damageFactor;
543 break;
545 case WEAPONTYPE::MEDIUM:
546 case WEAPONTYPE::MEDIUM_GUN:
548 if ( entityLevel > 0 && entityLevel > quality)
549 return TableMediumMeleeWeaponGenerics[quality-1].secondaryDamageFactor;
550 else
551 return TableMediumMeleeWeaponGenerics[quality-1].damageFactor;
553 break;
555 case WEAPONTYPE::HEAVY:
556 case WEAPONTYPE::HEAVY_GUN:
558 if ( entityLevel > 0 && entityLevel > quality)
559 return TableHeavyMeleeWeaponGenerics[quality-1].secondaryDamageFactor;
560 else
561 return TableHeavyMeleeWeaponGenerics[quality-1].damageFactor;
563 break;
565 case WEAPONTYPE::HANDS:
566 return TableLightMeleeWeaponGenerics[quality-1].damageFactor * (float) HANDS_DAMAGE_FACTOR_MULTIPLIER;
568 default:
569 nlwarning("<getWeaponDamageFactor> Unknown weapon type %d, return 0", type);
570 return 0;
572 } // getWeaponDamageFactor //
579 //--------------------------------------------------------------
580 // getArmorCharacteristics()
581 //--------------------------------------------------------------
582 TPairUInt8UInt16 getArmorCharacteristics( ARMORTYPE::EArmorType type, uint16 quality )
584 if (quality > 21)
585 quality = 21;
587 TPairUInt8UInt16 ret;
589 switch(type)
591 case ARMORTYPE::LIGHT:
592 ret.first = TableLightArmorGenerics[quality-1].percentProtection;
593 ret.second = TableLightArmorGenerics[quality-1].maxProtection;
594 break;
596 case ARMORTYPE::MEDIUM:
597 ret.first = TableMediumArmorGenerics[quality-1].percentProtection;
598 ret.second = TableMediumArmorGenerics[quality-1].maxProtection;
599 break;
601 case ARMORTYPE::HEAVY:
602 ret.first = TableHeavyArmorGenerics[quality-1].percentProtection;
603 ret.second = TableHeavyArmorGenerics[quality-1].maxProtection;
604 break;
606 default:
607 nlwarning("<getArmorCharacteristics> Unknown armor type %d, return 0", type);
608 ret.first = 0;
609 ret.second = 0;
613 return ret;
614 } // getArmorCharacteristics //
617 //--------------------------------------------------------------
618 // getEntityLevel()
619 //--------------------------------------------------------------
620 uint32 getEntityLevel( const CEntityId &entityId, SKILLS::ESkills skill, sint32 skillModifier, float skillMultiplier )
622 CEntityBase* entity = entityPtrFromId( entityId );
623 if (entity == NULL)
625 nlwarning("<getEntityLevel> Invalid entity Id %s", entityId.toString().c_str() );
626 return 0;
629 sint32 level = 0;
631 // skillModifier += entity->getGlobalSkillModifier();
633 if ( skill < SKILLS::NUM_SKILLS )
635 level = (sint32) ( skillMultiplier * float(entity->getSkills()._Skills[ skill ].Current) );
636 level += skillModifier;
637 if (level < 0)
638 level = 0;
641 level = getLevelFromSkill(level);
643 if (level == 0 && EntityForcedDefaultLevel > 0)
645 DEBUGLOG("<getEntityLevel> ONLY DEBUG : For entity %s, returns a level of %d instead of 0 for skill %s", entityId.toString().c_str(),EntityForcedDefaultLevel, SKILLS::toString(skill).c_str());
646 return EntityForcedDefaultLevel;
649 return (uint32)level;
651 } // getEntityLevel //
653 //--------------------------------------------------------------
654 // getEntityLevel()
655 //--------------------------------------------------------------
656 uint32 getEntityLevel( const CEntityId &entityId, SCORES::TScores score, sint32 scoreModifier, float scoreMultiplier )
658 CEntityBase* entity = entityPtrFromId( entityId );
659 if (entity == NULL)
661 nlwarning("<getEntityLevel> Invalid entity Id %s", entityId.toString().c_str() );
662 return 0;
665 uint32 level = 0;
668 if ( score != SCORES::unknown )
670 level = (sint32) ( scoreMultiplier * float(entity->getScores()._PhysicalScores[ score ].Current ) );
671 level += scoreModifier;
672 if (score < 0)
673 level = 0;
676 level = getLevelFromScore(level);
678 if (level == 0 && EntityForcedDefaultLevel > 0)
680 DEBUGLOG("<getEntityLevel> ONLY DEBUG : For entity %s, returns a level of %d instead of 0 for score %s", entityId.toString().c_str(),EntityForcedDefaultLevel, SCORES::toString(score).c_str() );
681 return EntityForcedDefaultLevel;
684 return level;
686 } // getEntityLevel //
689 //--------------------------------------------------------------
690 // getDistance()
691 //--------------------------------------------------------------
692 double getDistance( const CEntityId &entity1, const CEntityId &entity2 )
694 TDataSetRow entityIndex1 = TheDataset.getDataSetRow( entity1 );
695 if ( !entityIndex1.isValid() || !TheDataset.isDataSetRowStillValid(entityIndex1) )
696 return -1;
697 CMirrorPropValueRO<TYPE_POSX> posX( TheDataset, entityIndex1, DSPropertyPOSX );
698 const double playerX = (double)posX / 1000.0f;
699 CMirrorPropValueRO<TYPE_POSY> posY( TheDataset, entityIndex1, DSPropertyPOSY );
700 const double playerY = (double)posY / 1000.0f;
702 double targetX, targetY;//, targetZ;
703 // get second entity position
704 /* if (entity2.Type != RYZOMID::position)
707 TDataSetRow entityIndex2 = TheDataset.getDataSetRow( entity2 );
708 if ( !entityIndex2.isValid() || !TheDataset.isDataSetRowStillValid(entityIndex2) )
709 return -1;
710 CMirrorPropValueRO<TYPE_POSX> targX( TheDataset, entityIndex2, DSPropertyPOSX );
711 targetX = (double)targX() / 1000.0f;
712 CMirrorPropValueRO<TYPE_POSY> targY( TheDataset, entityIndex2, DSPropertyPOSY );
713 targetY = (double)targY() / 1000.0f;
716 INFOLOG("Player position (in meters) : X = %g, Y = %g", playerX, playerY );
717 INFOLOG("Target position (in meters) : X = %g, Y = %g", targetX, targetY );
719 const double d = sqrt( sqr(playerX-targetX) + sqr(playerY-targetY) ); //+sqr (playerZ-targetZ) );
720 INFOLOG("Distance = %g meters", d);
722 return d;
723 } // getDistance //
726 //--------------------------------------------------------------
727 // sendUpdateBehaviour()
728 //--------------------------------------------------------------
729 void sendUpdateBehaviour( const CEntityId &entityId, const MBEHAV::CBehaviour &behaviour, bool forceUpdate )
731 MBEHAV::CBehaviour b = behaviour;
733 b.Combat.Time = uint16(CTickEventHandler::getGameCycle() >>3);
735 if (behaviour.Behaviour > MBEHAV::COMBAT_BEHAVIOUR_BEGIN && behaviour.Behaviour < MBEHAV::COMBAT_BEHAVIOUR_END)
737 INFOLOG("<sendUpdateBehaviour> entity %s param : attackintensity = %u, impact intensity = %u, behaviour %s",entityId.toString().c_str(), behaviour.Combat.AttackIntensity, behaviour.Combat.ImpactIntensity, MBEHAV::behaviourToString(behaviour.Behaviour).c_str() );
739 else if (behaviour.Behaviour > MBEHAV::MAGIC_CASTING_BEHAVIOUR_BEGIN && behaviour.Behaviour < MBEHAV::MAGIC_END_CASTING_BEHAVIOUR_END)
741 INFOLOG("<sendUpdateBehaviour> entity %s param : SpellPower = %u, resist = %d, impact intensity = %u, behaviour %s", entityId.toString().c_str(), behaviour.Magic.TargetResists, behaviour.Magic.SpellPower, behaviour.Magic.ImpactIntensity, MBEHAV::behaviourToString(behaviour.Behaviour).c_str() );
743 else
745 INFOLOG("<sendUpdateBehaviour> entity %s, behaviour %s",entityId.toString().c_str(), MBEHAV::behaviourToString(behaviour.Behaviour).c_str() );
748 /* switch( entityId.getType() )
750 case RYZOMID::player:
752 //CMessage msgout("SET_BEHAVIOUR");
753 //msgout.serial( const_cast<CEntityId&> (entityId) );
754 //msgout.serial( b );
755 //sendMessageViaMirror ("OPS", msgout);
757 break;
759 case RYZOMID::npc:
760 case RYZOMID::creature:
761 case RYZOMID::kami:
763 //----------TEMP
764 // CMessage msg("SET_BEHAVIOUR");
765 // msg.serial( const_cast<CEntityId&> (entityId) );
766 // msg.serial( b );
767 // sendMessageViaMirror ("OPS", msg);
768 //----------TEMP
770 // CMessage msgout("U_FIGHT_BEHAVIOUR");
771 // msgout.serial( const_cast<CEntityId&> (entityId) );
772 // string bes = MBEHAV::behaviourToString( behaviour.Behaviour );
773 //msgout.serialEnum( behaviour );
774 // msgout.serial( bes );
775 // sendMessageViaMirror ("AIS", msgout);
777 break;
779 default:
780 nlwarning( "<sendUpdateBehaviour> entity type %d unknown, fail to send update behaviour msg", entityId.getType() );
783 CEntityBase* entity = PHRASE_UTILITIES::entityPtrFromId( entityId );
784 if (entity == NULL)
786 nlwarning("<sendUpdateBehaviour> Invalid entity Id %s", entityId.toString().c_str() );
787 return;
790 entity->setBehaviour( b, forceUpdate );
791 } // sendUpdateBehaviour //
795 //--------------------------------------------------------------
796 // sendSimpleMessage()
797 //--------------------------------------------------------------
798 void sendSimpleMessage( const CEntityId &entityId, const std::string &msgName )
800 if ( entityId.getType() != RYZOMID::player && entityId.getType() != RYZOMID::chatGroup && entityId.getType() != RYZOMID::dynChatGroup )
801 return;
803 CMessage msg("STATIC_STRING");
805 msg.serial( const_cast<CEntityId&> (entityId) );
807 set<CEntityId> excluded;
808 msg.serialCont( excluded );
810 msg.serial( const_cast<string&> (msgName) );
812 sendMessageViaMirror ("IOS", msg);
814 INFOLOG("<sendSimpleMessage>send %s for entity %s",msgName.c_str(), entityId.toString().c_str());
815 } // sendSimpleMessage //
818 //--------------------------------------------------------------
819 // sendMessage()
820 //--------------------------------------------------------------
821 void sendMessage( const NLMISC::CEntityId &entityId, const std::string &msgName, const ucstring &txt )
823 if ( entityId.getType() != RYZOMID::player && entityId.getType() != RYZOMID::chatGroup && entityId.getType() != RYZOMID::dynChatGroup )
824 return;
826 /// TEMP : convert the uctring to a string
827 const string txtStr = txt.toString();
829 CMessage msg("STATIC_STRING");
831 msg.serial( const_cast<CEntityId&> (entityId) );
833 set<CEntityId> excluded;
834 msg.serialCont( excluded );
836 msg.serial( const_cast<string&> (msgName) );
837 msg.serial( const_cast<string&> (txtStr) );
839 sendMessageViaMirror ("IOS", msg);
841 INFOLOG("<sendMessage>send %s (param %s) for entity %s",msgName.c_str(), txt.toString().c_str(), entityId.toString().c_str());
842 } // sendMessage //
844 //--------------------------------------------------------------
845 // sendMessage()
846 //--------------------------------------------------------------
847 void sendMessage( const NLMISC::CEntityId &entityId, const std::string &msgName, const NLMISC::CEntityId &entityIdForText )
849 if ( entityId.getType() != RYZOMID::player && entityId.getType() != RYZOMID::chatGroup && entityId.getType() != RYZOMID::dynChatGroup )
850 return;
852 CMessage msg("STATIC_STRING");
854 msg.serial( const_cast<CEntityId&> (entityId) );
856 set<CEntityId> excluded;
857 msg.serialCont( excluded );
859 msg.serial( const_cast<string&> (msgName) );
860 msg.serial( const_cast<CEntityId&> (entityIdForText) );
862 sendMessageViaMirror ("IOS", msg);
864 INFOLOG("<sendMessage>send %s (param entity %s) for entity %s",msgName.c_str(), entityIdForText.toString().c_str(), entityId.toString().c_str());
865 } // sendMessage //
868 //--------------------------------------------------------------
869 // sendSimpleDynamicChatMessage()
870 //--------------------------------------------------------------
871 void sendDynamicChatMessage( const CEntityId &entityId, const string &msgText )
873 if ( msgText.empty() )
874 return;
876 if ( entityId.getType() != RYZOMID::player && entityId.getType() != RYZOMID::chatGroup && entityId.getType() != RYZOMID::dynChatGroup )
877 return;
879 CMessage msg("CHAT_MESSAGE");
881 TDataSetRow dsr = TheDataset.getDataSetRow(entityId)
882 msg.serial( dsr );
883 msg.serial( const_cast<string&> (msgText) );
885 sendMessageViaMirror ("IOS", msg);
887 INFOLOG("<sendSimpleDynamicChatMessage>send %s for entity %s",msgText.c_str(), entityId.toString().c_str());
888 } // sendSimpleDynamicChatMessage //
892 //--------------------------------------------------------------
893 // sendCombatResistMessages()
894 //--------------------------------------------------------------
895 void sendCombatResistMessages( const NLMISC::CEntityId &aggressorId, const NLMISC::CEntityId &victimId )
897 // at least the victim or the agressor must be a player, otherwise do not send any messages
898 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
899 return;
901 string msgName;
903 if ( victimId.getType() == RYZOMID::player)
905 msgName ="BS_MISSES_YOU_E";
906 CMessage msgVictim("STATIC_STRING");
908 msgVictim.serial( const_cast<CEntityId&> (victimId) );
909 set<CEntityId> excluded;
910 msgVictim.serialCont( excluded );
911 msgVictim.serial( msgName );
913 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
915 sendMessageViaMirror ("IOS", msgVictim);
917 INFOLOG("<sendCombatResistMessages>send BS_MISSES_YOU_E with param e=%s for entity %s",aggressorId.toString().c_str(), victimId.toString().c_str());
920 if ( aggressorId.getType() == RYZOMID::player)
922 msgName ="BS_YOU_MISS_E";
923 CMessage msgAggressor("STATIC_STRING");
925 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
926 set<CEntityId> excluded;
927 msgAggressor.serialCont( excluded );
928 msgAggressor.serial( msgName );
930 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
932 sendMessageViaMirror ("IOS", msgAggressor);
934 INFOLOG("<sendCombatResistMessages>send BS_YOU_MISS with for entity %s", aggressorId.toString().c_str());
937 // spectators
938 // Send to 'speech' group
939 msgName = "BS_MISSES_EE";
941 CEntityId speechGroupId;
942 if ( aggressorId.getType() == RYZOMID::player )
944 speechGroupId = aggressorId;
946 else if ( victimId.getType() == RYZOMID::player )
948 speechGroupId = victimId;
950 else
951 return;
953 speechGroupId.setType( RYZOMID::dynChatGroup );
955 CMessage msgVictim("STATIC_STRING");
956 msgVictim.serial( speechGroupId );
958 set<CEntityId> excluded;
959 excluded.insert( aggressorId );
960 excluded.insert( victimId );
962 msgVictim.serialCont( excluded );
963 msgVictim.serial( msgName );
964 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
965 msgVictim.serial( const_cast<CEntityId&> (victimId) );
967 sendMessageViaMirror ("IOS", msgVictim);
968 } // sendCombatResistMessages //
971 //--------------------------------------------------------------
972 // sendDeathMessages()
973 //--------------------------------------------------------------
974 void sendDeathMessages( const NLMISC::CEntityId &killerId, const NLMISC::CEntityId &deadId )
976 // at least the victim or the agressor must be a player, otherwise do not send any messages
977 if ( (killerId.getType() != RYZOMID::player) && ( deadId.getType() != RYZOMID::player ))
978 return;
980 string msgName;
982 if ( killerId.getType() == RYZOMID::player )
984 msgName = "OPS_DEATH_KILLER_E";
985 CMessage msgAggressor("STATIC_STRING");
987 msgAggressor.serial( const_cast<CEntityId&> (killerId) );
988 set<CEntityId> excluded;
989 msgAggressor.serialCont( excluded );
990 msgAggressor.serial( msgName );
992 msgAggressor.serial( const_cast<CEntityId&> (deadId) );
994 sendMessageViaMirror ("IOS", msgAggressor);
997 if ( deadId.getType() == RYZOMID::player )
999 msgName = "OPS_DEATH_KILLED_E";
1000 CMessage msgVictim("STATIC_STRING");
1002 msgVictim.serial( const_cast<CEntityId&> (deadId) );
1003 set<CEntityId> excluded;
1004 msgVictim.serialCont( excluded );
1005 msgVictim.serial( msgName );
1006 msgVictim.serial( const_cast<CEntityId&> (killerId) );
1007 sendMessageViaMirror ("IOS", msgVictim);
1010 // spectators
1011 // Send to 'speech' group
1012 msgName = "OPS_DEATH_KILL_EE";
1014 CEntityId speechGroupId;
1015 if ( deadId.getType() == RYZOMID::player )
1017 speechGroupId = deadId;
1019 else
1021 speechGroupId = killerId;
1023 speechGroupId.setType( RYZOMID::dynChatGroup );
1025 CMessage msgSpectators("STATIC_STRING");
1027 msgSpectators.serial( speechGroupId );
1029 set<CEntityId> excluded;
1030 excluded.insert( deadId );
1031 excluded.insert( killerId );
1032 msgSpectators.serialCont( excluded );
1033 msgSpectators.serial( msgName );
1035 msgSpectators.serial( const_cast<CEntityId&> (killerId) );
1036 msgSpectators.serial( const_cast<CEntityId&> (deadId) );
1037 sendMessageViaMirror ("IOS", msgSpectators);
1039 } // sendDeathMessages //
1041 //--------------------------------------------------------------
1042 // sendHitMessages()
1043 //--------------------------------------------------------------
1044 void sendHitMessages( const CEntityId &aggressorId, const CEntityId &victimId, sint32 amount, sint32 lostStamina, sint32 lostSap)
1046 // at least the victim or the agressor must be a player, otherwise do not send any messages
1047 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1048 return;
1050 if ( !amount && !lostStamina && !lostSap)
1051 return;
1053 amount = abs(amount);
1054 lostStamina = abs(lostStamina);
1055 lostSap = abs(lostSap);
1057 string msgName;
1059 if ( aggressorId.getType() == RYZOMID::player )
1061 msgName = "BS_YOU_HIT_EI";
1063 CMessage msgAggressor("STATIC_STRING");
1065 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1066 set<CEntityId> excluded;
1067 msgAggressor.serialCont( excluded );
1068 msgAggressor.serial( msgName );
1070 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1071 msgAggressor.serial( amount );
1073 sendMessageViaMirror ("IOS", msgAggressor);
1074 INFOLOG("<sendHitMessages>send BS_YOU_HIT_EI with param e=%s and i=%i for entity %s",victimId.toString().c_str(), amount, aggressorId.toString().c_str());
1076 // lost stamina
1077 if (lostStamina>0)
1079 msgName = "EGS_LOSE_STA_EI";
1080 CMessage msgSta("STATIC_STRING");
1081 msgSta.serial( const_cast<CEntityId&> (aggressorId) );
1082 msgSta.serialCont( excluded );
1083 msgSta.serial( msgName );
1084 msgSta.serial( const_cast<CEntityId&> (victimId) );
1085 msgSta.serial( lostStamina );
1086 sendMessageViaMirror ("IOS", msgSta);
1088 // lost sap
1089 if (lostSap>0)
1091 msgName = "EGS_LOSE_SAP_EI";
1092 CMessage msgSap("STATIC_STRING");
1093 msgSap.serial( const_cast<CEntityId&> (aggressorId) );
1094 msgSap.serialCont( excluded );
1095 msgSap.serial( msgName );
1096 msgSap.serial( const_cast<CEntityId&> (victimId) );
1097 msgSap.serial( lostSap );
1098 sendMessageViaMirror ("IOS", msgSap);
1102 if ( victimId.getType() == RYZOMID::player )
1104 msgName = "BS_HITS_YOU_EI";
1106 CMessage msgVictim("STATIC_STRING");
1108 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1109 set<CEntityId> excluded;
1110 msgVictim.serialCont( excluded );
1111 msgVictim.serial( msgName );
1112 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1113 msgVictim.serial( amount );
1115 sendMessageViaMirror ("IOS", msgVictim);
1117 INFOLOG("<sendHitMessages>send BS_HITS_YOU_EI with param e=%s and i=%i for entity %s",aggressorId.toString().c_str(), amount, victimId.toString().c_str());
1119 // lost stamina
1120 if (lostStamina>0)
1122 msgName = "EGS_U_LOSE_STA_EI";
1123 CMessage msgSta("STATIC_STRING");
1124 msgSta.serial( const_cast<CEntityId&> (victimId) );
1125 msgSta.serialCont( excluded );
1126 msgSta.serial( msgName );
1127 msgSta.serial( const_cast<CEntityId&> (aggressorId) );
1128 msgSta.serial( lostStamina );
1129 sendMessageViaMirror ("IOS", msgSta);
1131 // lost sap
1132 if (lostSap>0)
1134 msgName = "EGS_U_LOSE_SAP_EI";
1135 CMessage msgSap("STATIC_STRING");
1136 msgSap.serial( const_cast<CEntityId&> (victimId) );
1137 msgSap.serialCont( excluded );
1138 msgSap.serial( msgName );
1139 msgSap.serial( const_cast<CEntityId&> (aggressorId) );
1140 msgSap.serial( lostSap );
1141 sendMessageViaMirror ("IOS", msgSap);
1145 // spectators
1146 // Send to 'speech' group
1147 msgName = "BS_HIT_EEI";
1150 CEntityId speechGroupId;
1151 if ( aggressorId.getType() == RYZOMID::player )
1153 speechGroupId = aggressorId;
1155 else
1157 speechGroupId = victimId;
1159 speechGroupId.setType( RYZOMID::dynChatGroup );
1161 CMessage msgVictim("STATIC_STRING");
1163 msgVictim.serial( speechGroupId );
1165 set<CEntityId> excluded;
1166 excluded.insert( aggressorId );
1167 excluded.insert( victimId );
1168 msgVictim.serialCont( excluded );
1170 msgVictim.serial( msgName );
1172 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1173 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1174 msgVictim.serial( amount );
1176 sendMessageViaMirror ("IOS", msgVictim);
1177 } // sendHitMessages //
1181 //--------------------------------------------------------------
1182 // sendCriticalHitMessage()
1183 //--------------------------------------------------------------
1184 void sendCriticalHitMessage( const NLMISC::CEntityId &aggressorId, const NLMISC::CEntityId &victimId )
1186 // at least the victim or the agressor must be a player, otherwise do not send any messages
1187 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1188 return;
1190 string msgName;
1192 if ( aggressorId.getType() == RYZOMID::player )
1194 msgName = "EGS_YOU_CRITICAL_HIT_E";
1195 CMessage msgAggressor("STATIC_STRING");
1197 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1198 set<CEntityId> excluded;
1199 msgAggressor.serialCont( excluded );
1200 msgAggressor.serial( msgName );
1202 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1204 sendMessageViaMirror ("IOS", msgAggressor);
1207 if ( victimId.getType() == RYZOMID::player )
1209 msgName = "EGS_CRITICAL_HIT_YOU_E";
1210 CMessage msgVictim("STATIC_STRING");
1212 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1213 set<CEntityId> excluded;
1214 msgVictim.serialCont( excluded );
1215 msgVictim.serial( msgName );
1216 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1217 sendMessageViaMirror ("IOS", msgVictim);
1220 // spectators
1221 // Send to 'speech' group
1222 msgName = "EGS_CRITICAL_HIT_EE";
1224 CEntityId speechGroupId;
1225 if ( aggressorId.getType() == RYZOMID::player )
1227 speechGroupId = aggressorId;
1229 else
1231 speechGroupId = victimId;
1233 speechGroupId.setType( RYZOMID::dynChatGroup );
1235 CMessage msgVictim("STATIC_STRING");
1237 msgVictim.serial( speechGroupId );
1239 set<CEntityId> excluded;
1240 excluded.insert( aggressorId );
1241 excluded.insert( victimId );
1242 msgVictim.serialCont( excluded );
1244 msgVictim.serial( msgName );
1246 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1247 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1249 sendMessageViaMirror ("IOS", msgVictim);
1251 } // sendCriticalHitMessage //
1253 //--------------------------------------------------------------
1254 // sendHitNullMessages()
1255 //--------------------------------------------------------------
1256 void sendHitNullMessages( const CEntityId &aggressorId, const CEntityId &victimId )
1258 // at least the victim or the agressor must be a player, otherwise do not send any messages
1259 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1260 return;
1262 string msgName;
1264 if ( aggressorId.getType() == RYZOMID::player )
1266 msgName = "BS_YOU_HIT_NULL_E";
1267 CMessage msgAggressor("STATIC_STRING");
1269 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1270 set<CEntityId> excluded;
1271 msgAggressor.serialCont( excluded );
1272 msgAggressor.serial( msgName );
1274 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1276 sendMessageViaMirror ("IOS", msgAggressor);
1278 INFOLOG("<sendHitMessages>send BS_YOU_HIT_NULL_E with param e=%s for entity %s",victimId.toString().c_str(), aggressorId.toString().c_str());
1281 if ( victimId.getType() == RYZOMID::player )
1283 msgName = "BS_HITS_YOU_NULL_E";
1284 CMessage msgVictim("STATIC_STRING");
1286 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1287 set<CEntityId> excluded;
1288 msgVictim.serialCont( excluded );
1289 msgVictim.serial( msgName );
1290 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1291 sendMessageViaMirror ("IOS", msgVictim);
1293 INFOLOG("<sendHitMessages>send BS_HITS_YOU_EI with param e=%s for entity %s",aggressorId.toString().c_str(), victimId.toString().c_str());
1296 // spectators
1297 // Send to 'speech' group
1298 msgName = "BS_HIT_NULL_EE";
1300 CEntityId speechGroupId;
1301 if ( aggressorId.getType() == RYZOMID::player )
1303 speechGroupId = aggressorId;
1305 else
1307 speechGroupId = victimId;
1309 speechGroupId.setType( RYZOMID::dynChatGroup );
1311 CMessage msgVictim("STATIC_STRING");
1313 msgVictim.serial( speechGroupId );
1315 set<CEntityId> excluded;
1316 excluded.insert( aggressorId );
1317 excluded.insert( victimId );
1318 msgVictim.serialCont( excluded );
1320 msgVictim.serial( msgName );
1322 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1323 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1325 sendMessageViaMirror ("IOS", msgVictim);
1326 } // sendHitNullMessages //
1330 //--------------------------------------------------------------
1331 // sendFumbleMessage()
1332 //--------------------------------------------------------------
1333 void sendFumbleMessage( const NLMISC::CEntityId &aggressorId, const NLMISC::CEntityId &victimId )
1335 // at least the victim or the agressor must be a player, otherwise do not send any messages
1336 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1337 return;
1339 string msgName;
1341 if ( aggressorId.getType() == RYZOMID::player )
1343 msgName = "EGS_YOU_FUMBLE";
1344 CMessage msgAggressor("STATIC_STRING");
1346 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1347 set<CEntityId> excluded;
1348 msgAggressor.serialCont( excluded );
1349 msgAggressor.serial( msgName );
1351 sendMessageViaMirror ("IOS", msgAggressor);
1354 if ( victimId.getType() == RYZOMID::player )
1356 msgName = "EGS_ENEMY_FUMBLE_E";
1357 CMessage msgVictim("STATIC_STRING");
1359 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1360 set<CEntityId> excluded;
1361 msgVictim.serialCont( excluded );
1362 msgVictim.serial( msgName );
1363 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1364 sendMessageViaMirror ("IOS", msgVictim);
1367 // spectators
1368 // Send to 'speech' group
1369 msgName = "EGS_FUMBLE_E";
1371 CEntityId speechGroupId;
1372 if ( aggressorId.getType() == RYZOMID::player )
1374 speechGroupId = aggressorId;
1376 else
1378 speechGroupId = victimId;
1380 speechGroupId.setType( RYZOMID::dynChatGroup );
1382 CMessage msgVictim("STATIC_STRING");
1384 msgVictim.serial( speechGroupId );
1386 set<CEntityId> excluded;
1387 excluded.insert( aggressorId );
1388 excluded.insert( victimId );
1389 msgVictim.serialCont( excluded );
1391 msgVictim.serial( msgName );
1393 sendMessageViaMirror ("IOS", msgVictim);
1395 } // sendFumbleMessage //
1397 //--------------------------------------------------------------
1398 // sendEngageMessages()
1399 //--------------------------------------------------------------
1400 void sendEngageMessages( const NLMISC::CEntityId &aggressorId, const NLMISC::CEntityId &victimId )
1402 // at least the victim or the agressor must be a player, otherwise do not send any messages
1403 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1404 return;
1406 string msgName;
1408 if ( aggressorId.getType() == RYZOMID::player )
1410 msgName = "BS_YOU_ATTACK_E";
1411 CMessage msgAggressor("STATIC_STRING");
1413 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1414 set<CEntityId> excluded;
1415 msgAggressor.serialCont( excluded );
1416 msgAggressor.serial( msgName );
1418 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1420 sendMessageViaMirror ("IOS", msgAggressor);
1423 if ( victimId.getType() == RYZOMID::player )
1425 msgName = "BS_ATTACKS_YOU_E";
1426 CMessage msgVictim("STATIC_STRING");
1428 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1429 set<CEntityId> excluded;
1430 msgVictim.serialCont( excluded );
1431 msgVictim.serial( msgName );
1432 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1433 sendMessageViaMirror ("IOS", msgVictim);
1436 // spectators
1437 // Send to 'speech' group
1438 msgName = "BS_ATTACKS_EE";
1440 CEntityId speechGroupId;
1441 if ( aggressorId.getType() == RYZOMID::player )
1443 speechGroupId = aggressorId;
1445 else
1447 speechGroupId = victimId;
1449 speechGroupId.setType( RYZOMID::dynChatGroup );
1451 CMessage msgVictim("STATIC_STRING");
1453 msgVictim.serial( speechGroupId );
1455 set<CEntityId> excluded;
1456 excluded.insert( aggressorId );
1457 excluded.insert( victimId );
1458 msgVictim.serialCont( excluded );
1460 msgVictim.serial( msgName );
1462 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1463 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1465 sendMessageViaMirror ("IOS", msgVictim);
1467 } // sendEngageMessages //
1470 //--------------------------------------------------------------
1471 // sendDisengageMessages()
1472 //--------------------------------------------------------------
1473 void sendDisengageMessages( const NLMISC::CEntityId &aggressorId, const NLMISC::CEntityId &victimId )
1475 // at least the victim or the agressor must be a player, otherwise do not send any messages
1476 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1477 return;
1479 string msgName;
1481 if ( aggressorId.getType() == RYZOMID::player )
1483 msgName = "BS_YOU_END_ATTACK_E";
1484 CMessage msgAggressor("STATIC_STRING");
1486 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1487 set<CEntityId> excluded;
1488 msgAggressor.serialCont( excluded );
1489 msgAggressor.serial( msgName );
1491 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1493 sendMessageViaMirror ("IOS", msgAggressor);
1496 if ( victimId.getType() == RYZOMID::player )
1498 msgName = "BS_END_ATTACKS_YOU_E";
1499 CMessage msgVictim("STATIC_STRING");
1501 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1502 set<CEntityId> excluded;
1503 msgVictim.serialCont( excluded );
1504 msgVictim.serial( msgName );
1505 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1506 sendMessageViaMirror ("IOS", msgVictim);
1509 // spectators
1510 // Send to 'speech' group
1511 msgName = "BS_END_ATTACKS_EE";
1513 CEntityId speechGroupId;
1514 if ( aggressorId.getType() == RYZOMID::player )
1516 speechGroupId = aggressorId;
1518 else
1520 speechGroupId = victimId;
1522 speechGroupId.setType( RYZOMID::dynChatGroup );
1524 CMessage msgVictim("STATIC_STRING");
1526 msgVictim.serial( speechGroupId );
1528 set<CEntityId> excluded;
1529 excluded.insert( aggressorId );
1530 excluded.insert( victimId );
1531 msgVictim.serialCont( excluded );
1533 msgVictim.serial( msgName );
1535 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1536 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1538 sendMessageViaMirror ("IOS", msgVictim);
1540 } // sendDisengageMessages //
1543 //--------------------------------------------------------------
1544 // engageTargetInMelee()
1545 //--------------------------------------------------------------
1546 bool engageTargetInMelee( const CEntityId &entityId , const CEntityId &targetId , sint8 mode)
1548 if ( targetId == CEntityId::Unknown )
1550 return false;
1553 // check target is alive??
1555 // indicate the new engaged target (for player only)
1556 if ( entityId.getType() == RYZOMID::player)
1558 CCharacter *ch = PlayerManager.getChar( entityId );
1559 if (ch == NULL)
1561 nlwarning("<engageTargetInMelee> Invalid char Id %s", entityId.toString().c_str() );
1562 return false;
1564 ch->setFightingTarget( targetId );
1567 //CBrickSentenceManager::engageMelee( entityId, targetId );
1568 PhraseManager->engageMelee( TheDataset.getDataSetRow(entityId), TheDataset.getDataSetRow(targetId) );
1569 return true;
1571 } // engageTargetInMelee //
1577 //--------------------------------------------------------------
1578 // engageTargetRange()
1579 //--------------------------------------------------------------
1580 bool engageTargetRange( const CEntityId &entityId , const CEntityId &targetId )
1582 if ( targetId == CEntityId::Unknown )
1584 return false;
1587 // check target is alive??
1589 //CBrickSentenceManager::engageRange( entityId, targetId );
1590 PhraseManager->engageRange( TheDataset.getDataSetRow(entityId), TheDataset.getDataSetRow(targetId) );
1593 INFOLOG("<engageTargetRange> entity %s engage entity %s in range combat",entityId.toString().c_str(),targetId.toString().c_str() );
1595 // indicate the new engaged target (for player only)
1596 if ( entityId.getType() == RYZOMID::player)
1598 CCharacter *ch = PlayerManager.getChar( entityId );
1599 if (ch == NULL)
1601 nlwarning("<engageTargetRange> Invalid char Id %s", entityId.toString().c_str() );
1602 return false;
1604 ch->setFightingTarget( targetId );
1607 return true;
1608 } // engageTargetRange //
1612 //--------------------------------------------------------------
1613 // getImpactIntensity()
1614 //--------------------------------------------------------------
1615 INTENSITY_TYPE::TImpactIntensity getImpactIntensity( sint32 impact, const TDataSetRow &victimRowId, SCORES::TScores score )
1617 if (impact == 0)
1618 return INTENSITY_TYPE::IMPACT_NONE;
1620 if (impact < 0)
1621 impact = impact * (-1);
1623 if ( score >= SCORES::NUM_SCORES)
1625 nlwarning("<getImpactIntensity> Unknown score %d", score);
1626 return INTENSITY_TYPE::IMPACT_NONE;
1629 CEntityBase* entity = CEntityBaseManager::getEntityBasePtr( victimRowId );
1630 if (entity == NULL)
1632 nlwarning("<getImpactIntensity> Invalid entity row %u", victimRowId.getIndex() );
1633 return INTENSITY_TYPE::IMPACT_NONE;
1636 const sint32 scoreMax = entity->getScores()._PhysicalScores[ score ].Max;
1638 // percentage
1639 uint32 percent = (uint32) fabs(100 * (double)impact / (double)scoreMax );
1641 if (percent < 2)
1642 return INTENSITY_TYPE::IMPACT_INSIGNIFICANT;
1643 else if (percent < 5)
1644 return INTENSITY_TYPE::IMPACT_VERY_WEAK;
1645 else if (percent < 10)
1646 return INTENSITY_TYPE::IMPACT_WEAK;
1647 else if (percent < 20)
1648 return INTENSITY_TYPE::IMPACT_AVERAGE;
1649 else if (percent < 30)
1650 return INTENSITY_TYPE::IMPACT_STRONG;
1651 else if (percent < 40)
1652 return INTENSITY_TYPE::IMPACT_VERY_STRONG;
1653 else
1654 return INTENSITY_TYPE::IMPACT_HUGE;
1655 } // getImpactIntensity //
1658 //--------------------------------------------------------------
1659 // getAttackIntensity()
1660 //--------------------------------------------------------------
1661 INTENSITY_TYPE::TAttackIntensity getAttackIntensity( uint32 attackLevel )
1663 if (attackLevel < 2)
1664 return INTENSITY_TYPE::NONE;
1665 else if (attackLevel < 5)
1666 return INTENSITY_TYPE::WEAK;
1667 else if (attackLevel < 10)
1668 return INTENSITY_TYPE::STANDARD;
1669 else
1670 return INTENSITY_TYPE::STRONG;
1671 } // getAttackIntensity //
1673 //--------------------------------------------------------------
1674 // getOrientationString()
1675 //--------------------------------------------------------------
1676 std::string getOrientationString( const NLMISC::CVector &dir)
1678 return getOrientationString( (sint32)dir.x, (sint32)dir.y );
1679 } // getOrientationString //
1682 //--------------------------------------------------------------
1683 // getOrientationString()
1684 //--------------------------------------------------------------
1685 std::string getOrientationString( sint32 x, sint32 y)
1687 float angle = (float)(atan2(y, x));
1689 //get the direction
1690 uint direction =(uint) ( 8.0f* (angle + Pi)/(Pi) );
1692 if (direction>15)
1694 nlwarning("Direction for compass should never be >15");
1695 return "";
1698 return OrientationStrings[direction];
1699 } // getOrientationString //
1702 //--------------------------------------------------------------
1703 // getEntityCurrentAction()
1704 //--------------------------------------------------------------
1705 ENTITY_ACTION::EEntityAction getEntityCurrentAction( const NLMISC::CEntityId &entityId)
1707 // test melee combat
1708 TDataSetRow targetRowId = PhraseManager->getEntityEngagedMeleeBy( TheDataset.getDataSetRow(entityId) );
1709 //if (targetId != CEntityId::Unknown )
1710 if (targetRowId.isValid() && TheDataset.isDataSetRowStillValid(targetRowId))
1712 return ENTITY_ACTION::MELEE_COMBAT;
1715 // test range combat
1716 //targetId = CBrickSentenceManager::getEntityEngagedRangeBy( targetId );
1717 targetRowId = PhraseManager->getEntityEngagedRangeBy( TheDataset.getDataSetRow(entityId) );
1718 //if (targetId != CEntityId::Unknown )
1719 if (targetRowId.isValid() && TheDataset.isDataSetRowStillValid(targetRowId))
1721 return ENTITY_ACTION::RANGE_COMBAT;
1725 /// \todo Malkav : test faber/tracking/casting/walking and running
1726 CEntityBase* entity = entityPtrFromId( entityId );
1727 if (entity == NULL)
1729 nlwarning("<getEntityCurrentAction> Invalid entity Id %s", entityId.toString().c_str() );
1730 return ENTITY_ACTION::IDLE;
1733 const MBEHAV::CBehaviour &behaviour = entity->getBehaviour();
1734 switch( behaviour.Behaviour )
1736 case MBEHAV::HARVESTING:
1737 return ENTITY_ACTION::HARVESTING;
1738 break;
1740 case MBEHAV::FABER:
1741 case MBEHAV::REPAIR:
1742 case MBEHAV::REFINE:
1743 return ENTITY_ACTION::DOING_FABER;
1744 break;
1746 default:
1748 /// Problem : how to detect a casting entity when this entity use the suffix tryker brick 'hide' ??? :'(
1749 if (behaviour.Behaviour >= MBEHAV::MAGIC_CASTING_BEHAVIOUR_BEGIN && behaviour.Behaviour < MBEHAV::MAGIC_END_CASTING_BEHAVIOUR_BEGIN)
1750 return ENTITY_ACTION::CASTING;
1752 break;
1756 // by default : return IDLE
1757 return ENTITY_ACTION::IDLE;
1759 } // getEntityCurrentAction //
1762 //--------------------------------------------------------------
1763 // testOffensiveActionAllowed
1764 //--------------------------------------------------------------
1765 bool testOffensiveActionAllowed( const NLMISC::CEntityId &actorId, const NLMISC::CEntityId &targetId, string &errorCode )
1767 switch ( targetId.getType() )
1769 case RYZOMID::player:
1771 if (actorId.getType() == RYZOMID::player)
1773 if (!AllowPVP)
1774 errorCode = "EGS_PVP_NOT_ALLOWED";
1776 return AllowPVP;
1779 break;
1781 case RYZOMID::creature:
1782 case RYZOMID::mount:
1783 case RYZOMID::kami:
1784 case RYZOMID::npc:
1786 CEntityBase* entity = CreatureManager.getCreature( targetId );
1787 if (entity == NULL)
1789 nlwarning("<testOffensiveActionAllowed> Invalid entity Id %s", targetId.toString().c_str() );
1790 errorCode = "BS_INVALID_TARGET";
1791 return false;
1794 /*// get creature form
1795 const CSheetId &sheet = entity->getType();
1797 const CStaticCreatures *creature = CSheets::getCreaturesForm( sheet );
1798 if ( ! creature)
1800 nlwarning("<testOffensiveActionAllowed> can't found CStaticCreature for entity %s", targetId.toString().c_str() );
1801 errorCode = "BS_INVALID_TARGET";
1802 return false;
1805 if ( ! creature->properties.attackable() )
1807 errorCode = "BS_TARGET_NOT_ATTACKABLE";
1808 return false;
1812 if (!entity->getContextualProperty().getValue().attackable())
1814 errorCode = "BS_TARGET_NOT_ATTACKABLE";
1815 return false;
1818 break;
1820 default:
1821 break;
1824 return true;
1825 } // testOffensiveActionAllowed //
1827 //--------------------------------------------------------------
1828 // sendScoreModifierSpellMessage
1829 //--------------------------------------------------------------
1830 void sendScoreModifierSpellMessage( CEntityBase * aggressor, CEntityBase* victim, sint32 value, SCORES::TScores score, ACTNATURE::EActionNature nature )
1832 nlassert(aggressor);
1833 nlassert(victim);
1835 // at least the victim or the agressor must be a player, otherwise do not send any messages
1836 if ( (aggressor->getId().getType() != RYZOMID::player) && ( victim->getId().getType() != RYZOMID::player ))
1837 return;
1839 string msgAgressor;
1840 string msgVictim;
1842 switch (nature )
1844 case ACTNATURE::OFFENSIVE:
1845 switch(score)
1847 case SCORES::sap:
1848 msgVictim = "MAGIC_U_SUFFER_OFFENSIVE_SPELL_E_SAP";
1849 msgAgressor = "MAGIC_U_CAST_OFFENSIVE_SPELL_E_SAP";
1850 break;
1851 case SCORES::stamina:
1852 msgVictim = "MAGIC_U_SUFFER_OFFENSIVE_SPELL_E_STA";
1853 msgAgressor = "MAGIC_U_CAST_OFFENSIVE_SPELL_E_STA";
1854 break;
1855 case SCORES::hit_points:
1856 msgVictim = "MAGIC_U_SUFFER_OFFENSIVE_SPELL_E_HP";
1857 msgAgressor = "MAGIC_U_CAST_OFFENSIVE_SPELL_E_HP";
1858 break;
1859 default:
1860 nlwarning("<PHRASE_UTILITIES sendScoreModifierSpellMessage> invalid scrore %s", SCORES::toString(score).c_str() );
1862 break;
1863 case ACTNATURE::DEFENSIVE:
1864 switch(score)
1866 case SCORES::sap:
1867 msgVictim = "MAGIC_U_SUFFER_HEAL_SPELL_E_SAP";
1868 msgAgressor = "MAGIC_U_CAST_HEAL_SPELL_E_SAP";
1869 break;
1870 case SCORES::stamina:
1871 msgVictim = "MAGIC_U_SUFFER_HEAL_SPELL_E_STA";
1872 msgAgressor = "MAGIC_U_CAST_HEAL_SPELL_E_STA";
1873 break;
1874 case SCORES::hit_points:
1875 msgVictim = "MAGIC_U_SUFFER_HEAL_SPELL_E_HP";
1876 msgAgressor = "MAGIC_U_CAST_HEAL_SPELL_E_HP";
1877 break;
1878 default:
1879 nlwarning("<PHRASE_UTILITIES sendScoreModifierSpellMessage> invalid scrore %s", SCORES::toString(score).c_str() );
1881 break;
1884 if ( aggressor->getId().getType() == RYZOMID::player )
1886 CCharacter::sendMessageToClient(aggressor->getId(),msgAgressor,victim->getId(),(uint32)value );
1888 if ( victim->getId().getType() == RYZOMID::player )
1890 CCharacter::sendMessageToClient(victim->getId(),msgVictim,aggressor->getId(),(uint32)value );
1892 } // sendScoreModifierSpellMessage //
1897 //--------------------------------------------------------------
1898 // sendSpellResistMessages()
1899 //--------------------------------------------------------------
1900 void sendSpellResistMessages( const TDataSetRow &aggressorRowId, const TDataSetRow &victimRowId )
1902 if ( !aggressorRowId.isValid() || !TheDataset.isDataSetRowStillValid(aggressorRowId) || !victimRowId.isValid() || !TheDataset.isDataSetRowStillValid(victimRowId) )
1903 return;
1905 CEntityId victimId = TheDataset.getEntityId(victimRowId);
1906 CEntityId aggressorId = TheDataset.getEntityId(aggressorRowId);
1908 // at least the victim or the agressor must be a player, otherwise do not send any messages
1909 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1910 return;
1912 string msgName;
1914 if ( victimId.getType() == RYZOMID::player)
1916 msgName ="EGS_TARGET_CASTING_RESIST_E";
1917 CMessage msgVictim("STATIC_STRING");
1919 msgVictim.serial( const_cast<CEntityId&> (victimId) );
1920 set<CEntityId> excluded;
1921 msgVictim.serialCont( excluded );
1922 msgVictim.serial( msgName );
1923 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
1924 sendMessageViaMirror ("IOS", msgVictim);
1927 if ( aggressorId.getType() == RYZOMID::player)
1929 msgName ="EGS_ACTOR_CASTING_RESIST_E";
1930 CMessage msgAggressor("STATIC_STRING");
1932 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
1933 set<CEntityId> excluded;
1934 msgAggressor.serialCont( excluded );
1935 msgAggressor.serial( msgName );
1936 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
1937 sendMessageViaMirror ("IOS", msgAggressor);
1940 // send message to spectators
1941 // Send to 'speech' group
1942 msgName ="EGS_SPECT_CASTING_RESIST_EE";
1944 CEntityId speechGroupId;
1945 if ( victimId.getType() == RYZOMID::player )
1947 speechGroupId = victimId;
1949 else
1951 speechGroupId = aggressorId;
1953 speechGroupId.setType( RYZOMID::dynChatGroup );
1955 CMessage msg("STATIC_STRING");
1957 msg.serial( speechGroupId );
1959 set<CEntityId> excluded;
1960 excluded.insert( aggressorId );
1961 excluded.insert( victimId );
1963 msg.serialCont( excluded );
1964 msg.serial( msgName );
1966 msg.serial( const_cast<CEntityId&> (victimId) );
1967 msg.serial( const_cast<CEntityId&> (aggressorId) );
1969 sendMessageViaMirror ("IOS", msg);
1970 } // sendSpellResistMessages //
1973 //--------------------------------------------------------------
1974 // sendSpellBeginCastMessages()
1975 //--------------------------------------------------------------
1976 void sendSpellBeginCastMessages( const TDataSetRow &aggressorRowId, const TDataSetRow &victimRowId, ACTNATURE::EActionNature nature )
1978 if ( !aggressorRowId.isValid() || !TheDataset.isDataSetRowStillValid(aggressorRowId) || !victimRowId.isValid() || !TheDataset.isDataSetRowStillValid(victimRowId) )
1979 return;
1981 CEntityId victimId = TheDataset.getEntityId(victimRowId);
1982 CEntityId aggressorId = TheDataset.getEntityId(aggressorRowId);
1984 // at least the victim or the agressor must be a player, otherwise do not send any messages
1985 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
1986 return;
1988 string msgName;
1989 bool self = (aggressorId == victimId);
1991 if ( aggressorId.getType() == RYZOMID::player)
1993 switch( nature )
1995 case ACTNATURE::NEUTRAL:
1996 msgName = self ? "EGS_ACTOR_BEGIN_SELFCAST_NEUTRAL" : "EGS_ACTOR_BEGIN_CASTING_NEUTRAL_E";
1997 break;
1998 case ACTNATURE::DEFENSIVE:
1999 msgName = self ? "EGS_ACTOR_BEGIN_SELFCAST_GOOD" : "EGS_ACTOR_BEGIN_CASTING_GOOD_E";
2000 break;
2001 case ACTNATURE::OFFENSIVE:
2002 default:
2003 msgName ="EGS_ACTOR_BEGIN_CASTING_BAD_E";
2006 CMessage msgVictim("STATIC_STRING");
2008 msgVictim.serial( const_cast<CEntityId&> (aggressorId) );
2009 set<CEntityId> excluded;
2010 msgVictim.serialCont( excluded );
2011 msgVictim.serial( msgName );
2013 if (!self)
2014 msgVictim.serial( const_cast<CEntityId&> (victimId) );
2016 sendMessageViaMirror ("IOS", msgVictim);
2019 if (self)
2020 return;
2022 if ( victimId.getType() == RYZOMID::player)
2024 switch( nature )
2026 case ACTNATURE::NEUTRAL:
2027 msgName = "EGS_TARGET_BEGIN_CASTING_NEUTRAL_E";
2028 break;
2029 case ACTNATURE::DEFENSIVE:
2030 msgName = "EGS_TARGET_BEGIN_CASTING_GOOD_E";
2031 break;
2032 case ACTNATURE::OFFENSIVE:
2033 default:
2034 msgName ="EGS_TARGET_BEGIN_CASTING_BAD_E";
2037 CMessage msgAggressor("STATIC_STRING");
2039 msgAggressor.serial( const_cast<CEntityId&> (victimId) );
2040 set<CEntityId> excluded;
2041 msgAggressor.serialCont( excluded );
2042 msgAggressor.serial( msgName );
2043 msgAggressor.serial( const_cast<CEntityId&> (aggressorId) );
2044 sendMessageViaMirror ("IOS", msgAggressor);
2047 // send message to spectators
2048 // Send to 'speech' group
2049 switch( nature )
2051 case ACTNATURE::NEUTRAL:
2052 msgName = "EGS_SPECT_BEGIN_CASTING_NEUTRAL_EE";
2053 break;
2054 case ACTNATURE::DEFENSIVE:
2055 msgName = "EGS_SPECT_BEGIN_CASTING_GOOD_EE";
2056 break;
2057 case ACTNATURE::OFFENSIVE:
2058 default:
2059 msgName ="EGS_SPECT_BEGIN_CASTING_BAD_EE";
2062 CEntityId speechGroupId;
2063 if ( victimId.getType() == RYZOMID::player )
2065 speechGroupId = victimId;
2067 else
2069 speechGroupId = aggressorId;
2071 speechGroupId.setType( RYZOMID::dynChatGroup );
2073 CMessage msg("STATIC_STRING");
2075 msg.serial( speechGroupId );
2077 set<CEntityId> excluded;
2078 excluded.insert( aggressorId );
2079 excluded.insert( victimId );
2081 msg.serialCont( excluded );
2082 msg.serial( msgName );
2084 msg.serial( const_cast<CEntityId&> (aggressorId) );
2085 msg.serial( const_cast<CEntityId&> (victimId) );
2087 sendMessageViaMirror ("IOS", msg);
2088 } // sendSpellBeginCastMessages //
2091 //--------------------------------------------------------------
2092 // sendSpellSuccessMessages()
2093 //--------------------------------------------------------------
2094 void sendSpellSuccessMessages( const TDataSetRow &aggressorRowId, const TDataSetRow &victimRowId )
2096 if ( !aggressorRowId.isValid() || !TheDataset.isDataSetRowStillValid(aggressorRowId) || !victimRowId.isValid() || !TheDataset.isDataSetRowStillValid(victimRowId) )
2097 return;
2099 CEntityId victimId = TheDataset.getEntityId(victimRowId);
2100 CEntityId aggressorId = TheDataset.getEntityId(aggressorRowId);
2102 // at least the victim or the agressor must be a player, otherwise do not send any messages
2103 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
2104 return;
2106 sendSimpleMessage(aggressorRowId, "EGS_ACTOR_CAST_END_SUCCESS");
2108 if ( aggressorRowId == victimRowId)
2109 return;
2111 sendMessage(victimRowId, "EGS_TARGET_CAST_END_SUCCESS_E", aggressorRowId);
2114 // send message to spectators
2115 // Send to 'speech' group
2116 string msgName ="EGS_SPECT_CAST_END_SUCCESS_EE";
2117 CEntityId speechGroupId;
2118 if ( victimId.getType() == RYZOMID::player )
2119 speechGroupId = victimId;
2120 else
2121 speechGroupId = aggressorId;
2123 speechGroupId.setType( RYZOMID::dynChatGroup );
2125 CMessage msg("STATIC_STRING");
2126 msg.serial( speechGroupId );
2127 set<CEntityId> excluded;
2128 excluded.insert( aggressorId );
2129 excluded.insert( victimId );
2130 msg.serialCont( excluded );
2131 msg.serial( msgName );
2132 msg.serial( const_cast<CEntityId&> (victimId) );
2133 msg.serial( const_cast<CEntityId&> (aggressorId) );
2134 sendMessageViaMirror ("IOS", msg);
2135 } // sendSpellSuccessMessages //
2138 //--------------------------------------------------------------
2139 // sendSpellFailedMessages()
2140 //--------------------------------------------------------------
2141 void sendSpellFailedMessages( const TDataSetRow &aggressorRowId, const TDataSetRow &victimRowId )
2143 if ( !aggressorRowId.isValid() || !TheDataset.isDataSetRowStillValid(aggressorRowId) || !victimRowId.isValid() || !TheDataset.isDataSetRowStillValid(victimRowId) )
2144 return;
2146 CEntityId victimId = TheDataset.getEntityId(victimRowId);
2147 CEntityId aggressorId = TheDataset.getEntityId(aggressorRowId);
2149 // at least the victim or the agressor must be a player, otherwise do not send any messages
2150 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
2151 return;
2153 sendSimpleMessage(aggressorRowId, "EGS_ACTOR_CAST_END_FAILED");
2155 if ( aggressorRowId == victimRowId)
2156 return;
2158 sendMessage(victimRowId, "EGS_TARGET_CAST_END_FAILED_E", aggressorRowId);
2161 // send message to spectators
2162 // Send to 'speech' group
2163 string msgName ="EGS_SPECT_CAST_END_FAILED_E";
2164 CEntityId speechGroupId;
2165 if ( victimId.getType() == RYZOMID::player )
2166 speechGroupId = victimId;
2167 else
2168 speechGroupId = aggressorId;
2170 speechGroupId.setType( RYZOMID::dynChatGroup );
2172 CMessage msg("STATIC_STRING");
2173 msg.serial( speechGroupId );
2174 set<CEntityId> excluded;
2175 excluded.insert( aggressorId );
2176 excluded.insert( victimId );
2177 msg.serialCont( excluded );
2178 msg.serial( msgName );
2179 msg.serial( const_cast<CEntityId&> (aggressorId) );
2180 sendMessageViaMirror ("IOS", msg);
2181 } // sendSpellFailedMessages //
2183 //--------------------------------------------------------------
2184 // sendSpellFumbleMessages()
2185 //--------------------------------------------------------------
2186 void sendSpellFumbleMessages( const TDataSetRow &aggressorRowId, const TDataSetRow &victimRowId )
2188 if ( !aggressorRowId.isValid() || !TheDataset.isDataSetRowStillValid(aggressorRowId) || !victimRowId.isValid() || !TheDataset.isDataSetRowStillValid(victimRowId) )
2189 return;
2191 CEntityId victimId = TheDataset.getEntityId(victimRowId);
2192 CEntityId aggressorId = TheDataset.getEntityId(aggressorRowId);
2194 // at least the victim or the agressor must be a player, otherwise do not send any messages
2195 if ( (aggressorId.getType() != RYZOMID::player) && ( victimId.getType() != RYZOMID::player ))
2196 return;
2198 sendSimpleMessage(aggressorRowId, "EGS_ACTOR_CAST_END_FUMBLE");
2200 if ( aggressorRowId == victimRowId)
2201 return;
2203 sendMessage(victimRowId, "EGS_TARGET_CAST_END_FUMBLE_E", aggressorRowId);
2206 // send message to spectators
2207 // Send to 'speech' group
2208 string msgName ="EGS_SPECT_CAST_END_FUMBLE_E";
2209 CEntityId speechGroupId;
2210 if ( victimId.getType() == RYZOMID::player )
2211 speechGroupId = victimId;
2212 else
2213 speechGroupId = aggressorId;
2215 speechGroupId.setType( RYZOMID::dynChatGroup );
2217 CMessage msg("STATIC_STRING");
2218 msg.serial( speechGroupId );
2219 set<CEntityId> excluded;
2220 excluded.insert( aggressorId );
2221 excluded.insert( victimId );
2222 msg.serialCont( excluded );
2223 msg.serial( msgName );
2224 msg.serial( const_cast<CEntityId&> (aggressorId) );
2225 sendMessageViaMirror ("IOS", msg);
2226 } // sendSpellFumbleMessages //
2228 }; // namespace PHRASE_UTILITIES