Changeset 28 for trunk/src/bindings
- Timestamp:
- 11/19/08 13:24:39 (17 years ago)
- Location:
- trunk/src/bindings/scripts
- Files:
-
- 8 modified
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bindings/scripts/ScriptMgr.cpp
r12 r28 1 /* Copyright (C) 2006 - 2008 ScriptDev2<https://scriptdev2.svn.sourceforge.net/>1 /* Copyright (C) 2006 - 2008 TrinityScript <https://scriptdev2.svn.sourceforge.net/> 2 2 * This program is free software licensed under GPL version 2 3 3 * Please see the included DOCS/LICENSE.TXT for more information */ … … 5 5 #include "precompiled.h" 6 6 #include "Config/Config.h" 7 #include "Database/DatabaseEnv.h" 8 #include "Database/DBCStores.h" 9 #include "ObjectMgr.h" 7 10 #include "ProgressBar.h" 8 #include "Database/DBCStores.h"9 #include "Database/DatabaseMysql.h"10 #include "ObjectMgr.h"11 11 #include "scripts/creature/mob_event_ai.h" 12 12 … … 25 25 Script *m_scripts[MAX_SCRIPTS]; 26 26 27 // Text Map for Event AI 28 HM_NAMESPACE::hash_map<uint32, std::string> EventAI_Text_Map; 29 30 // Script Text used as says / yells / text emotes / whispers in scripts. 31 struct ScriptText 27 DatabaseType TScriptDB; 28 Config TScriptConfig; 29 uint32 Locale; 30 31 // String text additional data, used in TextMap 32 struct StringTextData 32 33 { 33 34 uint32 SoundId; 34 35 uint8 Type; 35 36 uint32 Language; 36 std::string Text;37 37 }; 38 38 39 // Enums used by S criptText::Type39 // Enums used by StringTextData::Type 40 40 enum ChatType 41 41 { … … 48 48 }; 49 49 50 HM_NAMESPACE::hash_map<uint32, ScriptText> Script_TextMap; 50 #define TEXT_SOURCE_RANGE -100000 //the amount of entries each text source has available 51 52 // Text Maps 53 HM_NAMESPACE::hash_map<uint32, std::string> EventAI_Text_Map; 54 HM_NAMESPACE::hash_map<int32, StringTextData> TextMap; 51 55 52 56 // Localized Text structure for storing locales (for EAI and SD2 scripts). … … 62 66 std::string locale_8; 63 67 }; 68 //*** End Global data *** 69 70 //*** EventAI data *** 64 71 HM_NAMESPACE::hash_map<uint32, Localized_Text> EventAI_LocalizedTextMap; 65 HM_NAMESPACE::hash_map<uint32, Localized_Text> Script_LocalizedTextMap; 66 67 //*** End Global data *** 68 69 //*** EventAI data *** 72 70 73 //Event AI structure. Used exclusivly by mob_event_ai.cpp (60 bytes each) 71 74 std::list<EventAI_Event> EventAI_Event_List; … … 78 81 79 82 uint32 EAI_ErrorLevel; 80 81 83 //*** End EventAI data *** 82 83 DatabaseMysql TScriptDB;84 Config TScriptConfig;85 uint32 Locale;86 84 87 85 void FillSpellSummary(); … … 598 596 //Get db string from file 599 597 char const* dbstring = NULL; 600 if(!TScriptConfig.GetString("TScriptDatabaseInfo", &dbstring)) 601 error_log("TSCR: Missing Trinity Script Database Info in configuration file"); 602 603 //Initilize connection to DB 604 if(!dbstring || !TScriptDB.Initialize(dbstring)) 605 error_db_log("TSCR: Unable to connect to Database"); 598 599 if( !TScriptConfig.GetString("TScriptDatabaseInfo", &dbstring) ) 600 { 601 error_log("TSCR: Missing Trinity Script database info from configuration file. Load database aborted."); 602 return; 603 } 604 605 //Initialize connection to DB 606 if( dbstring && TScriptDB.Initialize(dbstring) ) 607 outstring_log("TSCR: TrinityScript database: %s",dbstring); 606 608 else 607 609 { 608 //***Preform all DB queries here*** 609 QueryResult *result; 610 611 //Get Version information 612 result = TScriptDB.PQuery("SELECT `version`" 613 "FROM `script_db_version`"); 614 615 if (result) 610 error_log("TSCR: Unable to connect to Database. Load database aborted."); 611 return; 612 } 613 614 //***Preform all DB queries here*** 615 QueryResult *result; 616 617 //Get Version information 618 result = TScriptDB.PQuery("SELECT version FROM script_db_version"); 619 620 if (result) 621 { 622 Field *fields = result->Fetch(); 623 outstring_log("TSCR: Database version is: %s", fields[0].GetString()); 624 outstring_log(""); 625 delete result; 626 627 }else 628 { 629 error_log("TSCR: Missing `script_db_version` information."); 630 outstring_log(""); 631 } 632 633 // Drop Existing Text Map, only done once and we are ready to add data from multiple sources. 634 TextMap.clear(); 635 636 //TODO: Add load from eventai_texts here 637 638 // Load Script Text 639 outstring_log("TSCR: Loading Script Texts..."); 640 LoadMangosStrings(TScriptDB,"script_texts",TEXT_SOURCE_RANGE,(TEXT_SOURCE_RANGE*2)+1); 641 642 // Gather Additional data from Script Texts 643 result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM script_texts"); 644 645 outstring_log("TSCR: Loading Script Texts additional data..."); 646 if (result) 647 { 648 barGoLink bar(result->GetRowCount()); 649 uint32 count = 0; 650 651 do 616 652 { 653 bar.step(); 654 Field* fields = result->Fetch(); 655 StringTextData temp; 656 657 int32 i = fields[0].GetInt32(); 658 temp.SoundId = fields[1].GetInt32(); 659 temp.Type = fields[2].GetInt32(); 660 temp.Language = fields[3].GetInt32(); 661 662 if (i >= 0) 663 { 664 error_db_log("TSCR: Entry %i in table `script_texts` is not a negative value.",i); 665 continue; 666 } 667 668 if (i > TEXT_SOURCE_RANGE || i <= TEXT_SOURCE_RANGE*2) 669 { 670 error_db_log("TSCR: Entry %i in table `script_texts` is out of accepted entry range for table.",i); 671 continue; 672 } 673 674 if (temp.SoundId) 675 { 676 if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId)) 677 error_db_log("TSCR: Entry %i in table `script_texts` has soundId %u but sound does not exist.",i,temp.SoundId); 678 } 679 680 if (!GetLanguageDescByID(temp.Language)) 681 error_db_log("TSCR: Entry %i in table `script_texts` using Language %u but Language does not exist.",i,temp.Language); 682 683 if (temp.Type > CHAT_TYPE_BOSS_WHISPER) 684 error_db_log("TSCR: Entry %i in table `script_texts` has Type %u but this Chat Type does not exist.",i,temp.Type); 685 686 TextMap[i] = temp; 687 ++count; 688 } while (result->NextRow()); 689 690 delete result; 691 692 outstring_log(""); 693 outstring_log(">> TSCR: Loaded %u additional Script Texts data.", count); 694 }else 695 { 696 barGoLink bar(1); 697 bar.step(); 698 outstring_log(""); 699 outstring_log(">> Loaded 0 additional Script Texts data. DB table `script_texts` is empty."); 700 } 701 702 // Load Custom Text 703 outstring_log("TSCR: Loading Custom Texts..."); 704 LoadMangosStrings(TScriptDB,"custom_texts",TEXT_SOURCE_RANGE*2,(TEXT_SOURCE_RANGE*3)+1); 705 706 // Gather Additional data from Custom Texts 707 result = TScriptDB.PQuery("SELECT entry, sound, type, language FROM custom_texts"); 708 709 outstring_log("TSCR: Loading Custom Texts additional data..."); 710 if (result) 711 { 712 barGoLink bar(result->GetRowCount()); 713 uint32 count = 0; 714 715 do 716 { 717 bar.step(); 718 Field* fields = result->Fetch(); 719 StringTextData temp; 720 721 int32 i = fields[0].GetInt32(); 722 temp.SoundId = fields[1].GetInt32(); 723 temp.Type = fields[2].GetInt32(); 724 temp.Language = fields[3].GetInt32(); 725 726 if (i >= 0) 727 { 728 error_db_log("TSCR: Entry %i in table `custom_texts` is not a negative value.",i); 729 continue; 730 } 731 732 if (i > TEXT_SOURCE_RANGE*2 || i <= TEXT_SOURCE_RANGE*3) 733 { 734 error_db_log("TSCR: Entry %i in table `custom_texts` is out of accepted entry range for table.",i); 735 continue; 736 } 737 738 if (temp.SoundId) 739 { 740 if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId)) 741 error_db_log("TSCR: Entry %i in table `custom_texts` has soundId %u but sound does not exist.",i,temp.SoundId); 742 } 743 744 if (!GetLanguageDescByID(temp.Language)) 745 error_db_log("TSCR: Entry %i in table `custom_texts` using Language %u but Language does not exist.",i,temp.Language); 746 747 if (temp.Type > CHAT_TYPE_BOSS_WHISPER) 748 error_db_log("TSCR: Entry %i in table `custom_texts` has Type %u but this Chat Type does not exist.",i,temp.Type); 749 750 TextMap[i] = temp; 751 ++count; 752 } while (result->NextRow()); 753 754 delete result; 755 756 outstring_log(""); 757 outstring_log(">> Loaded %u additional Custom Texts data.", count); 758 }else 759 { 760 barGoLink bar(1); 761 bar.step(); 762 outstring_log(""); 763 outstring_log(">> Loaded 0 additional Custom Texts data. DB table `custom_texts` is empty."); 764 } 765 766 // Drop existing Event AI Localized Text hash map 767 EventAI_LocalizedTextMap.clear(); 768 769 // Gather EventAI Localized Texts 770 result = TScriptDB.PQuery("SELECT id, locale_1, locale_2, locale_3, locale_4, locale_5, locale_6, locale_7, locale_8 " 771 "FROM eventai_localized_texts"); 772 773 outstring_log("TSCR: Loading EventAI Localized Texts..."); 774 if(result) 775 { 776 barGoLink bar(result->GetRowCount()); 777 uint32 count = 0; 778 779 do 780 { 781 Localized_Text temp; 782 bar.step(); 783 617 784 Field *fields = result->Fetch(); 618 outstring_log(" "); 619 outstring_log("TSCR: Database version is: %s", fields[0].GetString()); 620 outstring_log(" "); 621 delete result; 622 623 }else error_db_log("TSCR: Missing script_db_version information."); 624 625 // Drop existing Event AI Localized Text hash map 626 EventAI_LocalizedTextMap.clear(); 627 628 // Gather EventAI Localized Texts 629 result = TScriptDB.PQuery("SELECT `id`,`locale_1`,`locale_2`,`locale_3`,`locale_4`,`locale_5`,`locale_6`,`locale_7`,`locale_8`" 630 "FROM `eventai_localized_texts`"); 631 632 if(result) 785 786 uint32 i = fields[0].GetInt32(); 787 788 temp.locale_1 = fields[1].GetString(); 789 temp.locale_2 = fields[2].GetString(); 790 temp.locale_3 = fields[3].GetString(); 791 temp.locale_4 = fields[4].GetString(); 792 temp.locale_5 = fields[5].GetString(); 793 temp.locale_6 = fields[6].GetString(); 794 temp.locale_7 = fields[7].GetString(); 795 temp.locale_8 = fields[8].GetString(); 796 797 EventAI_LocalizedTextMap[i] = temp; 798 ++count; 799 800 }while(result->NextRow()); 801 802 delete result; 803 804 outstring_log(""); 805 outstring_log(">> Loaded %u EventAI Localized Texts", count); 806 }else 807 { 808 barGoLink bar(1); 809 bar.step(); 810 outstring_log(""); 811 outstring_log(">> Loaded 0 EventAI Localized Texts. DB table `eventai_localized_texts` is empty"); 812 } 813 814 //Drop existing EventAI Text hash map 815 EventAI_Text_Map.clear(); 816 817 //Gather EventAI Text Entries 818 result = TScriptDB.PQuery("SELECT id, text FROM eventai_texts"); 819 820 outstring_log("TSCR: Loading EventAI_Texts..."); 821 if (result) 822 { 823 barGoLink bar(result->GetRowCount()); 824 uint32 Count = 0; 825 826 do 633 827 { 634 outstring_log("TSCR: Loading EAI Localized Texts...."); 635 barGoLink bar(result->GetRowCount()); 636 uint32 count = 0; 637 638 do 828 bar.step(); 829 Field *fields = result->Fetch(); 830 831 uint32 i = fields[0].GetInt32(); 832 833 std::string text = fields[1].GetString(); 834 835 if (!strlen(text.c_str())) 836 error_db_log("TSCR: EventAI text %u is empty", i); 837 838 EventAI_Text_Map[i] = text; 839 ++Count; 840 841 }while (result->NextRow()); 842 843 delete result; 844 845 outstring_log(""); 846 outstring_log(">> Loaded %u EventAI texts", Count); 847 }else 848 { 849 barGoLink bar(1); 850 bar.step(); 851 outstring_log(""); 852 outstring_log(">> Loaded 0 EventAI texts. DB table `eventai_texts` is empty."); 853 } 854 855 //Gather event data 856 result = TScriptDB.PQuery("SELECT id, position_x, position_y, position_z, orientation, spawntimesecs FROM eventai_summons"); 857 858 //Drop Existing EventSummon Map 859 EventAI_Summon_Map.clear(); 860 861 outstring_log("TSCR: Loading EventAI_Summons..."); 862 if (result) 863 { 864 barGoLink bar(result->GetRowCount()); 865 uint32 Count = 0; 866 867 do 868 { 869 bar.step(); 870 Field *fields = result->Fetch(); 871 872 EventAI_Summon temp; 873 874 uint32 i = fields[0].GetUInt32(); 875 temp.position_x = fields[1].GetFloat(); 876 temp.position_y = fields[2].GetFloat(); 877 temp.position_z = fields[3].GetFloat(); 878 temp.orientation = fields[4].GetFloat(); 879 temp.SpawnTimeSecs = fields[5].GetUInt32(); 880 881 //Add to map 882 EventAI_Summon_Map[i] = temp; 883 ++Count; 884 }while (result->NextRow()); 885 886 delete result; 887 888 outstring_log(""); 889 outstring_log(">> Loaded %u EventAI summon definitions", Count); 890 }else 891 { 892 barGoLink bar(1); 893 bar.step(); 894 outstring_log(""); 895 outstring_log(">> Loaded 0 EventAI Summon definitions. DB table `eventai_summons` is empty."); 896 } 897 898 //Gather event data 899 result = TScriptDB.PQuery("SELECT id, creature_id, event_type, event_inverse_phase_mask, event_chance, event_flags, " 900 "event_param1, event_param2, event_param3, event_param4, " 901 "action1_type, action1_param1, action1_param2, action1_param3, " 902 "action2_type, action2_param1, action2_param2, action2_param3, " 903 "action3_type, action3_param1, action3_param2, action3_param3 " 904 "FROM eventai_scripts"); 905 906 //Drop Existing EventAI List 907 EventAI_Event_List.clear(); 908 909 outstring_log("TSCR: Loading EventAI_Scripts..."); 910 if (result) 911 { 912 barGoLink bar(result->GetRowCount()); 913 uint32 Count = 0; 914 915 do 916 { 917 bar.step(); 918 Field *fields = result->Fetch(); 919 920 EventAI_Event temp; 921 922 temp.event_id = fields[0].GetUInt32(); 923 uint32 i = temp.event_id; 924 temp.creature_id = fields[1].GetUInt32(); 925 temp.event_type = fields[2].GetUInt16(); 926 temp.event_inverse_phase_mask = fields[3].GetUInt32(); 927 temp.event_chance = fields[4].GetUInt8(); 928 temp.event_flags = fields[5].GetUInt8(); 929 temp.event_param1 = fields[6].GetUInt32(); 930 temp.event_param2 = fields[7].GetUInt32(); 931 temp.event_param3 = fields[8].GetUInt32(); 932 temp.event_param4 = fields[9].GetUInt32(); 933 934 //Report any errors in event 935 if (temp.event_type >= EVENT_T_END) 936 error_db_log("TSCR: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i); 937 938 //No chance of this event occuring 939 if (temp.event_chance == 0) 940 error_db_log("TSCR: Event %u has 0 percent chance. Event will never trigger!", i); 941 942 //Chance above 100, force it to be 100 943 if (temp.event_chance > 100) 639 944 { 640 Localized_Text temp; 641 bar.step(); 642 643 Field *fields = result->Fetch(); 644 645 uint32 i = fields[0].GetInt32(); 646 647 temp.locale_1 = fields[1].GetString(); 648 temp.locale_2 = fields[2].GetString(); 649 temp.locale_3 = fields[3].GetString(); 650 temp.locale_4 = fields[4].GetString(); 651 temp.locale_5 = fields[5].GetString(); 652 temp.locale_6 = fields[6].GetString(); 653 temp.locale_7 = fields[7].GetString(); 654 temp.locale_8 = fields[8].GetString(); 655 656 EventAI_LocalizedTextMap[i] = temp; 657 ++count; 658 659 }while(result->NextRow()); 660 661 delete result; 662 663 outstring_log(""); 664 outstring_log("TSCR: Loaded %u EventAI Localized Texts", count); 665 }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI Localized Texts. Database table `eventai_localized_texts` is empty"); 666 667 // Drop Existing Script Localized Text Hash Map 668 Script_LocalizedTextMap.clear(); 669 670 // Gather Script Localized Texts 671 result = TScriptDB.PQuery("SELECT `id`,`locale_1`,`locale_2`,`locale_3`,`locale_4`,`locale_5`,`locale_6`,`locale_7`,`locale_8`" 672 "FROM `script_localized_texts`"); 673 674 if(result) 675 { 676 outstring_log("TSCR: Loading Script Localized Texts...."); 677 barGoLink bar(result->GetRowCount()); 678 uint32 count = 0; 679 680 do 945 error_db_log("TSCR: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i); 946 temp.event_chance = 100; 947 } 948 949 //Individual event checks 950 switch (temp.event_type) 681 951 { 682 Localized_Text temp; 683 bar.step(); 684 685 Field *fields = result->Fetch(); 686 687 uint32 i = fields[0].GetInt32(); 688 689 temp.locale_1 = fields[1].GetString(); 690 temp.locale_2 = fields[2].GetString(); 691 temp.locale_3 = fields[3].GetString(); 692 temp.locale_4 = fields[4].GetString(); 693 temp.locale_5 = fields[5].GetString(); 694 temp.locale_6 = fields[6].GetString(); 695 temp.locale_7 = fields[7].GetString(); 696 temp.locale_8 = fields[8].GetString(); 697 698 Script_LocalizedTextMap[i] = temp; 699 ++count; 700 701 }while(result->NextRow()); 702 703 delete result; 704 705 outstring_log(""); 706 outstring_log("TSCR: Loaded %u Script Localized Texts", count); 707 }else outstring_log("TSCR: WARNING >> Loaded 0 Script Localized Texts. Database table `script_localized_texts` is empty"); 708 709 //Drop existing EventAI Text hash map 710 EventAI_Text_Map.clear(); 711 712 //Gather EventAI Text Entries 713 result = TScriptDB.PQuery("SELECT `id`,`text` FROM `eventai_texts`"); 714 715 if (result) 716 { 717 outstring_log( "TSCR: Loading EventAI_Texts..."); 718 barGoLink bar(result->GetRowCount()); 719 uint32 Count = 0; 720 721 do 952 case EVENT_T_HP: 953 case EVENT_T_MANA: 954 case EVENT_T_TARGET_HP: 955 { 956 if (temp.event_param2 > 100) 957 error_db_log("TSCR: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i); 958 959 if (temp.event_param1 <= temp.event_param2) 960 error_db_log("TSCR: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i); 961 962 if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4) 963 { 964 error_db_log("TSCR: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i); 965 temp.event_flags &= ~EFLAG_REPEATABLE; 966 } 967 } 968 break; 969 970 case EVENT_T_SPELLHIT: 971 { 972 if (temp.event_param1) 973 { 974 SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1); 975 if (!pSpell) 976 { 977 error_db_log("TSCR: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i); 978 continue; 979 } 980 981 if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask) 982 error_db_log("TSCR: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i); 983 } 984 985 //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0 986 //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit() 987 if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL) 988 error_db_log("TSCR: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i); 989 990 if (temp.event_param4 < temp.event_param3) 991 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 992 } 993 break; 994 995 case EVENT_T_RANGE: 996 case EVENT_T_OOC_LOS: 997 case EVENT_T_FRIENDLY_HP: 998 case EVENT_T_FRIENDLY_IS_CC: 999 case EVENT_T_FRIENDLY_MISSING_BUFF: 1000 { 1001 if (temp.event_param4 < temp.event_param3) 1002 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 1003 } 1004 break; 1005 1006 case EVENT_T_TIMER: 1007 case EVENT_T_TIMER_OOC: 1008 { 1009 if (temp.event_param2 < temp.event_param1) 1010 error_db_log("TSCR: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i); 1011 1012 if (temp.event_param4 < temp.event_param3) 1013 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 1014 } 1015 break; 1016 1017 case EVENT_T_KILL: 1018 case EVENT_T_TARGET_CASTING: 1019 { 1020 if (temp.event_param2 < temp.event_param1) 1021 error_db_log("TSCR: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 1022 } 1023 break; 1024 1025 case EVENT_T_AGGRO: 1026 case EVENT_T_DEATH: 1027 case EVENT_T_EVADE: 1028 case EVENT_T_SPAWNED: 1029 { 1030 if (temp.event_flags & EFLAG_REPEATABLE) 1031 { 1032 error_db_log("TSCR: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i); 1033 temp.event_flags &= ~EFLAG_REPEATABLE; 1034 } 1035 } 1036 break; 1037 } 1038 1039 for (uint32 j = 0; j < MAX_ACTIONS; j++) 722 1040 { 723 bar.step(); 724 Field *fields = result->Fetch(); 725 726 uint32 i = fields[0].GetInt32(); 727 728 std::string text = fields[1].GetString(); 729 730 if (!strlen(text.c_str())) 731 error_db_log("TSCR: EventAI text %u is empty", i); 732 733 EventAI_Text_Map[i] = text; 734 ++Count; 735 736 }while (result->NextRow()); 737 738 delete result; 739 740 outstring_log(""); 741 outstring_log("TSCR: >> Loaded %u EventAI_Texts", Count); 742 743 }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Texts. DB table `EventAI_Texts` is empty."); 744 745 //Gather event data 746 result = TScriptDB.PQuery("SELECT `id`,`position_x`,`position_y`,`position_z`,`orientation`,`spawntimesecs`" 747 "FROM `eventai_summons`"); 748 749 //Drop Existing EventSummon Map 750 EventAI_Summon_Map.clear(); 751 752 if (result) 753 { 754 outstring_log( "TSCR: Loading EventAI_Summons..."); 755 barGoLink bar(result->GetRowCount()); 756 uint32 Count = 0; 757 758 do 759 { 760 bar.step(); 761 Field *fields = result->Fetch(); 762 763 EventAI_Summon temp; 764 765 uint32 i = fields[0].GetUInt32(); 766 temp.position_x = fields[1].GetFloat(); 767 temp.position_y = fields[2].GetFloat(); 768 temp.position_z = fields[3].GetFloat(); 769 temp.orientation = fields[4].GetFloat(); 770 temp.SpawnTimeSecs = fields[5].GetUInt32(); 771 772 //Add to map 773 EventAI_Summon_Map[i] = temp; 774 ++Count; 775 776 }while (result->NextRow()); 777 778 delete result; 779 outstring_log(""); 780 outstring_log("TSCR: >> Loaded %u EventAI_Summons", Count); 781 782 }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Summons. DB table `EventAI_Summons` is empty."); 783 784 //Gather event data 785 result = TScriptDB.PQuery("SELECT `id`,`creature_id`,`event_type`,`event_inverse_phase_mask`,`event_chance`,`event_flags`,`event_param1`,`event_param2`,`event_param3`,`event_param4`,`action1_type`,`action1_param1`,`action1_param2`,`action1_param3`,`action2_type`,`action2_param1`,`action2_param2`,`action2_param3`,`action3_type`,`action3_param1`,`action3_param2`,`action3_param3`" 786 "FROM `eventai_scripts`"); 787 788 //Drop Existing EventAI List 789 EventAI_Event_List.clear(); 790 791 if (result) 792 { 793 outstring_log( "TSCR: Loading EventAI_Scripts..."); 794 barGoLink bar(result->GetRowCount()); 795 uint32 Count = 0; 796 797 do 798 { 799 bar.step(); 800 Field *fields = result->Fetch(); 801 802 EventAI_Event temp; 803 804 temp.event_id = fields[0].GetUInt32(); 805 uint32 i = temp.event_id; 806 temp.creature_id = fields[1].GetUInt32(); 807 temp.event_type = fields[2].GetUInt16(); 808 temp.event_inverse_phase_mask = fields[3].GetUInt32(); 809 temp.event_chance = fields[4].GetUInt8(); 810 temp.event_flags = fields[5].GetUInt8(); 811 temp.event_param1 = fields[6].GetUInt32(); 812 temp.event_param2 = fields[7].GetUInt32(); 813 temp.event_param3 = fields[8].GetUInt32(); 814 temp.event_param4 = fields[9].GetUInt32(); 815 816 //Report any errors in event 817 if (temp.event_type >= EVENT_T_END) 818 error_db_log("TSCR: Event %u has incorrect event type. Maybe DB requires updated version of SD2.", i); 819 820 //No chance of this event occuring 821 if (temp.event_chance == 0) 822 error_db_log("TSCR: Event %u has 0 percent chance. Event will never trigger!", i); 823 //Chance above 100, force it to be 100 824 if (temp.event_chance > 100) 1041 temp.action[j].type = fields[10+(j*4)].GetUInt16(); 1042 temp.action[j].param1 = fields[11+(j*4)].GetUInt32(); 1043 temp.action[j].param2 = fields[12+(j*4)].GetUInt32(); 1044 temp.action[j].param3 = fields[13+(j*4)].GetUInt32(); 1045 1046 //Report any errors in actions 1047 switch (temp.action[j].type) 825 1048 { 826 error_db_log("TSCR: Creature %u are using event %u with more than 100 percent chance. Adjusting to 100 percent.", temp.creature_id, i); 827 temp.event_chance = 100; 828 } 829 830 //Individual event checks 831 switch (temp.event_type) 832 { 833 case EVENT_T_HP: 834 case EVENT_T_MANA: 835 case EVENT_T_TARGET_HP: 1049 case ACTION_T_SAY: 1050 case ACTION_T_YELL: 1051 case ACTION_T_TEXTEMOTE: 1052 if (GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) 1053 error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1); 1054 break; 1055 1056 case ACTION_T_SOUND: 1057 if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1)) 1058 error_db_log("TSCR: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1); 1059 break; 1060 1061 case ACTION_T_RANDOM_SAY: 1062 case ACTION_T_RANDOM_YELL: 1063 case ACTION_T_RANDOM_TEXTEMOTE: 1064 if ((temp.action[j].param1 != 0xffffffff && GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) || 1065 (temp.action[j].param2 != 0xffffffff && GetEventAIText(temp.action[j].param2) == DEFAULT_TEXT) || 1066 (temp.action[j].param3 != 0xffffffff && GetEventAIText(temp.action[j].param3) == DEFAULT_TEXT)) 1067 error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1); 1068 break; 1069 1070 case ACTION_T_CAST: 836 1071 { 837 if (temp.event_param2 > 100) 838 error_db_log("TSCR: Creature %u are using percentage event(%u) with param2 (MinPercent) > 100. Event will never trigger! ", temp.creature_id, i); 839 840 if (temp.event_param1 <= temp.event_param2) 841 error_db_log("TSCR: Creature %u are using percentage event(%u) with param1 <= param2 (MaxPercent <= MinPercent). Event will never trigger! ", temp.creature_id, i); 842 843 if (temp.event_flags & EFLAG_REPEATABLE && !temp.event_param3 && !temp.event_param4) 844 { 845 error_db_log("TSCR: Creature %u has param3 and param4=0 (RepeatMin/RepeatMax) but cannot be repeatable without timers. Removing EFLAG_REPEATABLE for event %u.", temp.creature_id, i); 846 temp.event_flags &= ~EFLAG_REPEATABLE; 847 } 1072 if (!GetSpellStore()->LookupEntry(temp.action[j].param1)) 1073 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1); 1074 1075 if (temp.action[j].param2 >= TARGET_T_END) 1076 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 848 1077 } 849 1078 break; 850 1079 851 case EVENT_T_SPELLHIT:1080 case ACTION_T_REMOVEAURASFROMSPELL: 852 1081 { 853 if (temp.event_param1) 854 { 855 SpellEntry const* pSpell = GetSpellStore()->LookupEntry(temp.event_param1); 856 if (!pSpell) 857 { 858 error_db_log("TSCR: Creature %u has non-existant SpellID(%u) defined in event %u.", temp.creature_id, temp.event_param1, i); 859 continue; 860 } 861 862 if (temp.event_param2_s != -1 && temp.event_param2 != pSpell->SchoolMask) 863 error_db_log("TSCR: Creature %u has param1(spellId %u) but param2 is not -1 and not equal to spell's school mask. Event %u can never trigger.", temp.creature_id, temp.event_param1, i); 864 } 865 866 //TODO: fix this system with SPELL_SCHOOL_MASK. Current complicate things, using int32(-1) instead of just 0 867 //SPELL_SCHOOL_MASK_NONE = 0 and does not exist, thus it can not ever trigger or be used in SpellHit() 868 if (temp.event_param2_s != -1 && temp.event_param2_s > SPELL_SCHOOL_MASK_ALL) 869 error_db_log("TSCR: Creature %u is using invalid SpellSchoolMask(%u) defined in event %u.", temp.creature_id, temp.event_param2, i); 870 871 if (temp.event_param4 < temp.event_param3) 872 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 1082 if (!GetSpellStore()->LookupEntry(temp.action[j].param2)) 1083 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); 1084 1085 if (temp.action[j].param1 >= TARGET_T_END) 1086 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 873 1087 } 874 1088 break; 875 1089 876 case EVENT_T_RANGE: 877 case EVENT_T_OOC_LOS: 878 case EVENT_T_FRIENDLY_HP: 879 case EVENT_T_FRIENDLY_IS_CC: 880 case EVENT_T_FRIENDLY_MISSING_BUFF: 1090 case ACTION_T_CASTCREATUREGO: 881 1091 { 882 if (temp.event_param4 < temp.event_param3) 883 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 1092 if (!GetSpellStore()->LookupEntry(temp.action[j].param2)) 1093 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); 1094 1095 if (temp.action[j].param3 >= TARGET_T_END) 1096 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 884 1097 } 885 1098 break; 886 1099 887 case EVENT_T_TIMER:888 case EVENT_T_TIMER_OOC:1100 //2nd param target 1101 case ACTION_T_SUMMON_ID: 889 1102 { 890 if ( temp.event_param2 < temp.event_param1)891 error_db_log("TSCR: Creature %u are using timed event(%u) with param2 < param1 (InitialMax < InitialMin). Event will never repeat.", temp.creature_id, i);892 893 if (temp. event_param4 < temp.event_param3)894 error_db_log("TSCR: Creature %u are using repeatable event(%u) with param4 < param3 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i);1103 if (EventAI_Summon_Map.find(temp.action[j].param3) == EventAI_Summon_Map.end()) 1104 error_db_log("TSCR: Event %u Action %u summons missing EventAI_Summon %u", i, j+1, temp.action[j].param3); 1105 1106 if (temp.action[j].param2 >= TARGET_T_END) 1107 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 895 1108 } 896 1109 break; 897 1110 898 case EVENT_T_KILL: 899 case EVENT_T_TARGET_CASTING: 900 { 901 if (temp.event_param2 < temp.event_param1) 902 error_db_log("TSCR: Creature %u are using event(%u) with param2 < param1 (RepeatMax < RepeatMin). Event will never repeat.", temp.creature_id, i); 903 } 1111 case ACTION_T_SUMMON: 1112 case ACTION_T_THREAT_SINGLE_PCT: 1113 case ACTION_T_QUEST_EVENT: 1114 case ACTION_T_SET_UNIT_FLAG: 1115 case ACTION_T_REMOVE_UNIT_FLAG: 1116 case ACTION_T_SET_INST_DATA64: 1117 if (temp.action[j].param2 >= TARGET_T_END) 1118 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 904 1119 break; 905 1120 906 case EVENT_T_AGGRO: 907 case EVENT_T_DEATH: 908 case EVENT_T_EVADE: 909 case EVENT_T_SPAWNED: 910 { 911 if (temp.event_flags & EFLAG_REPEATABLE) 912 { 913 error_db_log("TSCR: Creature %u has EFLAG_REPEATABLE set. Event can never be repeatable. Removing flag for event %u.", temp.creature_id, i); 914 temp.event_flags &= ~EFLAG_REPEATABLE; 915 } 916 } 1121 //3rd param target 1122 case ACTION_T_SET_UNIT_FIELD: 1123 if (temp.action[j].param3 >= TARGET_T_END) 1124 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 917 1125 break; 918 }; 919 920 for (uint32 j = 0; j < MAX_ACTIONS; j++) 921 { 922 temp.action[j].type = fields[10+(j*4)].GetUInt16(); 923 temp.action[j].param1 = fields[11+(j*4)].GetUInt32(); 924 temp.action[j].param2 = fields[12+(j*4)].GetUInt32(); 925 temp.action[j].param3 = fields[13+(j*4)].GetUInt32(); 926 927 //Report any errors in actions 928 switch (temp.action[j].type) 929 { 930 case ACTION_T_SAY: 931 case ACTION_T_YELL: 932 case ACTION_T_TEXTEMOTE: 933 if (GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) 934 error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1); 935 break; 936 937 case ACTION_T_SOUND: 938 if (!GetSoundEntriesStore()->LookupEntry(temp.action[j].param1)) 939 error_db_log("TSCR: Event %u Action %u uses non-existant SoundID %u.", i, j+1, temp.action[j].param1); 940 break; 941 942 case ACTION_T_RANDOM_SAY: 943 case ACTION_T_RANDOM_YELL: 944 case ACTION_T_RANDOM_TEXTEMOTE: 945 if ((temp.action[j].param1 != 0xffffffff && GetEventAIText(temp.action[j].param1) == DEFAULT_TEXT) || 946 (temp.action[j].param2 != 0xffffffff && GetEventAIText(temp.action[j].param2) == DEFAULT_TEXT) || 947 (temp.action[j].param3 != 0xffffffff && GetEventAIText(temp.action[j].param3) == DEFAULT_TEXT)) 948 error_db_log("TSCR: Event %u Action %u refrences missing Localized_Text entry", i, j+1); 949 break; 950 951 case ACTION_T_CAST: 952 { 953 if (!GetSpellStore()->LookupEntry(temp.action[j].param1)) 954 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param1); 955 956 if (temp.action[j].param2 >= TARGET_T_END) 957 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 958 } 959 break; 960 961 case ACTION_T_REMOVEAURASFROMSPELL: 962 { 963 if (!GetSpellStore()->LookupEntry(temp.action[j].param2)) 964 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); 965 966 if (temp.action[j].param1 >= TARGET_T_END) 967 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 968 } 969 break; 970 971 case ACTION_T_CASTCREATUREGO: 972 { 973 if (!GetSpellStore()->LookupEntry(temp.action[j].param2)) 974 error_db_log("TSCR: Event %u Action %u uses non-existant SpellID %u.", i, j+1, temp.action[j].param2); 975 976 if (temp.action[j].param3 >= TARGET_T_END) 977 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 978 } 979 break; 980 981 //2nd param target 982 case ACTION_T_SUMMON_ID: 983 { 984 if (EventAI_Summon_Map.find(temp.action[j].param3) == EventAI_Summon_Map.end()) 985 error_db_log("TSCR: Event %u Action %u summons missing EventAI_Summon %u", i, j+1, temp.action[j].param3); 986 987 if (temp.action[j].param2 >= TARGET_T_END) 988 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 989 } 990 break; 991 992 case ACTION_T_SUMMON: 993 case ACTION_T_THREAT_SINGLE_PCT: 994 case ACTION_T_QUEST_EVENT: 995 case ACTION_T_SET_UNIT_FLAG: 996 case ACTION_T_REMOVE_UNIT_FLAG: 997 case ACTION_T_SET_INST_DATA64: 998 if (temp.action[j].param2 >= TARGET_T_END) 999 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 1000 break; 1001 1002 //3rd param target 1003 case ACTION_T_SET_UNIT_FIELD: 1004 if (temp.action[j].param3 >= TARGET_T_END) 1005 error_db_log("TSCR: Event %u Action %u uses incorrect Target type", i, j+1); 1006 break; 1007 1008 case ACTION_T_SET_PHASE: 1009 if (temp.action[j].param1 > 31) 1010 error_db_log("TSCR: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1); 1011 break; 1012 1013 case ACTION_T_INC_PHASE: 1014 if (!temp.action[j].param1) 1015 error_db_log("TSCR: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1); 1016 break; 1017 1018 case ACTION_T_KILLED_MONSTER: 1019 if (temp.event_type != EVENT_T_DEATH) 1020 outstring_log("TSCR WARNING: Event %u Action %u calling ACTION_T_KILLED_MONSTER outside of EVENT_T_DEATH", i, j+1); 1021 break; 1022 1023 case ACTION_T_SET_INST_DATA: 1024 if (temp.action[j].param2 > 3) 1025 error_db_log("TSCR: Event %u Action %u attempts to set instance data above encounter state 3. Custom case?", i, j+1); 1026 break; 1027 1028 default: 1029 break; 1030 } 1031 1032 if (temp.action[j].type >= ACTION_T_END) 1033 error_db_log("TSCR: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1); 1126 1127 case ACTION_T_SET_PHASE: 1128 if (temp.action[j].param1 > 31) 1129 error_db_log("TSCR: Event %u Action %u attempts to set phase > 31. Phase mask cannot be used past phase 31.", i, j+1); 1130 break; 1131 1132 case ACTION_T_INC_PHASE: 1133 if (!temp.action[j].param1) 1134 error_db_log("TSCR: Event %u Action %u is incrementing phase by 0. Was this intended?", i, j+1); 1135 break; 1136 1137 case ACTION_T_KILLED_MONSTER: 1138 if (temp.event_type != EVENT_T_DEATH) 1139 outstring_log("SD2 WARNING: Event %u Action %u calling ACTION_T_KILLED_MONSTER outside of EVENT_T_DEATH", i, j+1); 1140 break; 1141 1142 case ACTION_T_SET_INST_DATA: 1143 if (temp.action[j].param2 > 3) 1144 error_db_log("TSCR: Event %u Action %u attempts to set instance data above encounter state 3. Custom case?", i, j+1); 1145 break; 1146 1147 default: 1148 if (temp.action[j].type >= ACTION_T_END) 1149 error_db_log("TSCR: Event %u Action %u has incorrect action type. Maybe DB requires updated version of SD2.", i, j+1); 1150 break; 1034 1151 } 1035 1036 //Add to list 1037 EventAI_Event_List.push_back(temp); 1038 ++Count; 1039 1040 }while (result->NextRow()); 1041 1042 delete result; 1043 outstring_log(""); 1044 outstring_log("TSCR: >> Loaded %u EventAI_Events", Count); 1045 1046 }else outstring_log("TSCR: WARNING >> Loaded 0 EventAI_Scripts. DB table `EventAI_Scripts` is empty."); 1047 1048 // Gather Script Text 1049 result = TScriptDB.PQuery("SELECT `id`, `sound`, `type`, `language`, `text`" 1050 "FROM `script_texts`;"); 1051 1052 // Drop Existing Script Text Map 1053 Script_TextMap.clear(); 1054 1055 if(result) 1056 { 1057 outstring_log("TSCR: Loading Script Text..."); 1058 barGoLink bar(result->GetRowCount()); 1059 uint32 count = 0; 1060 1061 do 1062 { 1063 bar.step(); 1064 Field* fields = result->Fetch(); 1065 ScriptText temp; 1066 1067 uint32 i = fields[0].GetInt32(); 1068 temp.SoundId = fields[1].GetInt32(); 1069 temp.Type = fields[2].GetInt32(); 1070 temp.Language = fields[3].GetInt32(); 1071 temp.Text = fields[4].GetString(); 1072 1073 if (temp.SoundId) 1074 { 1075 if (!GetSoundEntriesStore()->LookupEntry(temp.SoundId)) 1076 error_db_log("TSCR: Id %u in table script_texts has soundid %u but sound does not exist.",i,temp.SoundId); 1077 } 1078 1079 if(!strlen(temp.Text.c_str())) 1080 error_db_log("TSCR: Id %u in table script_texts has no text.", i); 1081 1082 Script_TextMap[i] = temp; 1083 ++count; 1084 1085 }while(result->NextRow()); 1086 1087 delete result; 1088 1089 outstring_log(""); 1090 outstring_log("TSCR: Loaded %u Script Texts", count); 1091 1092 }else outstring_log("TSCR WARNING >> Loaded 0 Script Texts. Database table `script_texts` is empty."); 1093 1094 //Free database thread and resources 1095 TScriptDB.HaltDelayThread(); 1096 1097 //***End DB queries*** 1152 } 1153 1154 //Add to list 1155 EventAI_Event_List.push_back(temp); 1156 ++Count; 1157 } while (result->NextRow()); 1158 1159 delete result; 1160 1161 outstring_log(""); 1162 outstring_log(">> Loaded %u EventAI scripts", Count); 1163 }else 1164 { 1165 barGoLink bar(1); 1166 bar.step(); 1167 outstring_log(""); 1168 outstring_log(">> Loaded 0 EventAI scripts. DB table `eventai_scripts` is empty."); 1098 1169 } 1170 1171 //Free database thread and resources 1172 TScriptDB.HaltDelayThread(); 1173 1099 1174 } 1100 1175 1101 1176 struct TSpellSummary { 1102 uint8 Targets; // set of enum SelectTarget1103 uint8 Effects; // set of enum SelectEffect1177 uint8 Targets; // set of enum SelectTarget 1178 uint8 Effects; // set of enum SelectEffect 1104 1179 }extern *SpellSummary; 1105 1180 … … 1120 1195 void ScriptsInit() 1121 1196 { 1197 bool CanLoadDB = true; 1198 1122 1199 //Trinity Script startup 1123 1200 outstring_log(" _____ _ _ _ ____ _ _"); … … 1132 1209 //Get configuration file 1133 1210 if (!TScriptConfig.SetSource(_TRINITY_SCRIPT_CONFIG)) 1134 error_log("TSCR: Unable to open configuration file, Database will be unaccessible"); 1135 else outstring_log("TSCR: Using configuration file %s", _TRINITY_SCRIPT_CONFIG); 1136 1211 { 1212 CanLoadDB = false; 1213 error_log("TSCR: Unable to open configuration file. Database will be unaccessible. Configuration values will use default."); 1214 } 1215 else outstring_log("TSCR: Using configuration file %s",_TRINITY_SCRIPT_CONFIG); 1137 1216 1138 1217 //Check config file version … … 1150 1229 1151 1230 outstring_log("TSCR: Using locale %u", Locale); 1231 1232 EAI_ErrorLevel = TScriptConfig.GetIntDefault("EAIErrorLevel", 1); 1233 1234 switch (EAI_ErrorLevel) 1235 { 1236 case 0: 1237 outstring_log("TSCR: EventAI Error Reporting level set to 0 (Startup Errors only)"); 1238 break; 1239 case 1: 1240 outstring_log("TSCR: EventAI Error Reporting level set to 1 (Startup errors and Runtime event errors)"); 1241 break; 1242 case 2: 1243 outstring_log("TSCR: EventAI Error Reporting level set to 2 (Startup errors, Runtime event errors, and Creation errors)"); 1244 break; 1245 default: 1246 outstring_log("TSCR: Unknown EventAI Error Reporting level. Defaulting to 1 (Startup errors and Runtime event errors)"); 1247 EAI_ErrorLevel = 1; 1248 break; 1249 } 1250 1152 1251 outstring_log(""); 1153 1252 1154 EAI_ErrorLevel = TScriptConfig.GetIntDefault("EAIErrorLevel", 1); 1155 1156 switch (EAI_ErrorLevel) 1157 { 1158 case 0: 1159 outstring_log("TSCR: EventAI Error Reporting level set to 0 (Startup Errors only)"); 1160 break; 1161 1162 case 1: 1163 outstring_log("TSCR: EventAI Error Reporting level set to 1 (Startup errors and Runtime event errors)"); 1164 break; 1165 1166 case 2: 1167 outstring_log("TSCR: EventAI Error Reporting level set to 2 (Startup errors, Runtime event errors, and Creation errors)"); 1168 break; 1169 1170 default: 1171 outstring_log("TSCR: Unknown EventAI Error Reporting level. Defaulting to 1 (Startup errors and Runtime event errors)"); 1172 EAI_ErrorLevel = 1; 1173 break; 1174 } 1253 //Load database (must be called after TScriptConfig.SetSource). In case it failed, no need to even try load. 1254 if (CanLoadDB) 1255 LoadDatabase(); 1256 1257 outstring_log("TSCR: Loading C++ scripts"); 1258 barGoLink bar(1); 1259 bar.step(); 1175 1260 outstring_log(""); 1176 1177 //Load database (must be called after TScriptConfig.SetSource)1178 LoadDatabase();1179 1261 1180 1262 nrscripts = 0; … … 1756 1838 } 1757 1839 1758 const char* GetScriptLocalizedText(uint32 entry)1759 {1760 const char* temp = NULL;1761 1762 HM_NAMESPACE::hash_map<uint32, Localized_Text>::iterator i = Script_LocalizedTextMap.find(entry);1763 1764 if (i == Script_LocalizedTextMap.end())1765 {1766 error_log("TSCR: Script Localized Text %u not found", entry);1767 return DEFAULT_TEXT;1768 }1769 1770 switch (Locale)1771 {1772 case 1:1773 temp = (*i).second.locale_1.c_str();1774 break;1775 1776 case 2:1777 temp = (*i).second.locale_2.c_str();1778 break;1779 1780 case 3:1781 temp = (*i).second.locale_3.c_str();1782 break;1783 1784 case 4:1785 temp = (*i).second.locale_4.c_str();1786 break;1787 1788 case 5:1789 temp = (*i).second.locale_5.c_str();1790 break;1791 1792 case 6:1793 temp = (*i).second.locale_6.c_str();1794 break;1795 1796 case 7:1797 temp = (*i).second.locale_7.c_str();1798 break;1799 1800 case 8:1801 temp = (*i).second.locale_8.c_str();1802 break;1803 };1804 1805 if (strlen(temp))1806 return temp;1807 1808 return DEFAULT_TEXT;1809 }1810 1811 1840 const char* GetEventAIText(uint32 entry) 1812 1841 { … … 1834 1863 } 1835 1864 1836 void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target)1865 void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target) 1837 1866 { 1838 1867 if (!pSource) 1839 1868 { 1840 error_log("TSCR: ProcessScriptText invalid Source pointer.");1869 error_log("TSCR: DoScriptText entry %i, invalid Source pointer.",textEntry); 1841 1870 return; 1842 1871 } 1843 1872 1844 HM_NAMESPACE::hash_map<uint32, ScriptText>::iterator i = Script_TextMap.find(id); 1845 1846 if (i == Script_TextMap.end()) 1847 { 1848 error_log("TSCR: ProcessScriptText could not find id %u.",id); 1873 if (textEntry >= 0) 1874 { 1875 error_log("TSCR: DoScriptText attempts to process entry %i, but entry must be negative.",textEntry); 1849 1876 return; 1850 1877 } 1851 1878 1879 HM_NAMESPACE::hash_map<int32, StringTextData>::iterator i = TextMap.find(textEntry); 1880 1881 if (i == TextMap.end()) 1882 { 1883 error_log("TSCR: DoScriptText could not find text entry %i.",textEntry); 1884 return; 1885 } 1886 1852 1887 if((*i).second.SoundId) 1853 1888 { 1854 if( GetSoundEntriesStore()->LookupEntry((*i).second.SoundId))1889 if( GetSoundEntriesStore()->LookupEntry((*i).second.SoundId) ) 1855 1890 { 1856 1891 pSource->SendPlaySound((*i).second.SoundId, false); 1857 1892 } 1858 1893 else 1859 error_log("TSCR: ProcessScriptText id %u tried to process invalid soundid %u.",id,(*i).second.SoundId);1894 error_log("TSCR: DoScriptText entry %i tried to process invalid sound id %u.",textEntry,(*i).second.SoundId); 1860 1895 } 1861 1896 … … 1863 1898 { 1864 1899 case CHAT_TYPE_SAY: 1865 pSource->MonsterSay( (*i).second.Text.c_str(), (*i).second.Language, target ? target->GetGUID() : 0);1900 pSource->MonsterSay(textEntry, (*i).second.Language, target ? target->GetGUID() : 0); 1866 1901 break; 1867 1868 1902 case CHAT_TYPE_YELL: 1869 pSource->MonsterYell( (*i).second.Text.c_str(), (*i).second.Language, target ? target->GetGUID() : 0);1903 pSource->MonsterYell(textEntry, (*i).second.Language, target ? target->GetGUID() : 0); 1870 1904 break; 1871 1872 1905 case CHAT_TYPE_TEXT_EMOTE: 1873 pSource->MonsterTextEmote( (*i).second.Text.c_str(), target ? target->GetGUID() : 0);1906 pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0); 1874 1907 break; 1875 1876 1908 case CHAT_TYPE_BOSS_EMOTE: 1877 pSource->MonsterTextEmote( (*i).second.Text.c_str(), target ? target->GetGUID() : 0, true);1909 pSource->MonsterTextEmote(textEntry, target ? target->GetGUID() : 0, true); 1878 1910 break; 1879 1880 1911 case CHAT_TYPE_WHISPER: 1881 1912 { 1882 1913 if (target && target->GetTypeId() == TYPEID_PLAYER) 1883 pSource->MonsterWhisper( (*i).second.Text.c_str(), target->GetGUID());1884 else error_log("TSCR: ProcessScriptText id %u cannot whisper without target unit (TYPEID_PLAYER).", id);1914 pSource->MonsterWhisper(textEntry, target->GetGUID()); 1915 else error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry); 1885 1916 }break; 1886 1887 1917 case CHAT_TYPE_BOSS_WHISPER: 1888 1918 { 1889 1919 if (target && target->GetTypeId() == TYPEID_PLAYER) 1890 pSource->MonsterWhisper( (*i).second.Text.c_str(), target->GetGUID(), true);1891 else error_log("TSCR: ProcessScriptText id %u cannot whisper without target unit (TYPEID_PLAYER).", id);1920 pSource->MonsterWhisper(textEntry, target->GetGUID(), true); 1921 else error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", textEntry); 1892 1922 }break; 1893 1923 } -
trunk/src/bindings/scripts/ScriptMgr.h
r5 r28 1 1 /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> 2 * This program is free software licensed under GPL version 23 * Please see the included DOCS/LICENSE.TXT for more information */2 * This program is free software licensed under GPL version 2 3 * Please see the included DOCS/LICENSE.TXT for more information */ 4 4 5 5 #ifndef SCRIPTMGR_H … … 22 22 class WorldObject; 23 23 24 #define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb) 24 #define MAX_SCRIPTS 1000 //72 bytes each (approx 71kb) 25 #define VISIBLE_RANGE (166.0f) //MAX visible range (size of grid) 26 #define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>" 25 27 26 //MAX visible range (size of grid)27 #define VISIBLE_RANGE (166.0f)28 29 #define DEFAULT_TEXT "<Trinity Script Text Entry Missing!>"30 31 //32 28 struct Script 33 29 { … … 41 37 std::string Name; 42 38 43 // -- Quest/gossip Methods to be scripted --39 // Quest/gossip Methods to be scripted 44 40 bool (*pGossipHello )(Player*, Creature*); 45 41 bool (*pQuestAccept )(Player*, Creature*, Quest const* ); … … 62 58 CreatureAI* (*GetAI)(Creature*); 63 59 InstanceData* (*GetInstanceData)(Map*); 64 // -----------------------------------------65 60 }; 66 61 … … 70 65 // Localized Text function 71 66 const char* GetEventAILocalizedText(uint32 entry); 72 const char* GetScriptLocalizedText(uint32 entry);73 67 74 68 //EventAI text function 75 const char* GetEventAIText(uint32 entry); // TODO: Locales69 const char* GetEventAIText(uint32 entry); // TODO: Locales 76 70 77 // Script Text function78 void ProcessScriptText(uint32 id, WorldObject* pSource, Unit* target = NULL); // TODO: Locales71 //Generic scripting text function 72 void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target = NULL); 79 73 80 74 #if COMPILER == COMPILER_GNU -
trunk/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp
r18 r28 400 400 }else EnfeebleResetTimer -= diff; 401 401 402 if(m_creature->hasUnitState(UNIT_STAT_STUN DED)) //While shifting to phase 2 malchezaar stuns himself402 if(m_creature->hasUnitState(UNIT_STAT_STUNNED)) //While shifting to phase 2 malchezaar stuns himself 403 403 return; 404 404 -
trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_priestess_delrissa.cpp
r6 r28 1003 1003 }else Freezing_Trap_Timer -= diff; 1004 1004 1005 if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUN DED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED))1005 if(!m_creature->getVictim()->hasUnitState(UNIT_STAT_STUNNED | UNIT_STAT_ROOT | UNIT_STAT_CONFUSED | UNIT_STAT_DISTRACTED)) 1006 1006 DoMeleeAttackIfReady(); 1007 1007 }else -
trunk/src/bindings/scripts/scripts/zone/magisters_terrace/boss_selin_fireheart.cpp
r6 r28 17 17 /* ScriptData 18 18 SDName: Boss_Selin_Fireheart 19 SD%Complete: 9 919 SD%Complete: 90 20 20 SDComment: Heroic and Normal Support. Needs further testing. 21 21 SDCategory: Magister's Terrace … … 74 74 { 75 75 uint64 guid = pInstance->GetData64(DATA_FEL_CRYSTAL); 76 outstring_log("Selin: Adding Fel Crystal %u to list", guid);76 debug_log("SD2: Selin: Adding Fel Crystal %u to list", guid); 77 77 Crystals.push_back(guid); 78 78 } … … 117 117 118 118 GameObject* Door = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR)); 119 if( Door)120 Door->SetGoState(0); // Close the door. Open it only in JustDied.121 119 if( Door ) 120 Door->SetGoState(0); // Open the big encounter door. Close it in Aggro and open it only in JustDied(and here) 121 // Small door opened after event are expected to be closed by default 122 122 // Set Inst data for encounter 123 123 pInstance->SetData(DATA_SELIN_EVENT, NOT_STARTED); … … 161 161 } 162 162 } 163 if( CrystalChosen)163 if( CrystalChosen ) 164 164 { 165 165 DoYell(SAY_ENERGY, LANG_UNIVERSAL, NULL); 166 166 DoPlaySoundToSet(m_creature, SOUND_ENERGY); 167 167 168 CrystalChosen->CastSpell(CrystalChosen, SPELL_FEL_CRYSTAL_COSMETIC, true); 168 169 … … 186 187 //Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, FelCrystals[i])); 187 188 Creature* pCrystal = ((Creature*)Unit::GetUnit(*m_creature, *itr)); 188 if( pCrystal && pCrystal->isAlive())189 if( pCrystal && pCrystal->isAlive()) 189 190 pCrystal->DealDamage(pCrystal, pCrystal->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 190 191 } … … 195 196 DoYell(SAY_AGGRO, LANG_UNIVERSAL, NULL); 196 197 DoPlaySoundToSet(m_creature, SOUND_AGGRO); 198 199 if( pInstance ) 200 { 201 GameObject* EncounterDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR)); 202 if( EncounterDoor ) 203 EncounterDoor->SetGoState(1); //Close the encounter door, open it in JustDied/Reset 204 } 197 205 } 198 206 … … 246 254 247 255 pInstance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete! 256 248 257 GameObject* EncounterDoor = GameObject::GetGameObject((*m_creature), pInstance->GetData64(DATA_SELIN_ENCOUNTER_DOOR)); 249 if(EncounterDoor) 250 EncounterDoor->SetGoState(1); // Open the door 258 if( EncounterDoor ) 259 EncounterDoor->SetGoState(0); // Open the encounter door 260 261 GameObject* ContinueDoor = GameObject::GetGameObject(*m_creature, pInstance->GetData64(DATA_SELIN_DOOR)); 262 if( ContinueDoor ) 263 ContinueDoor->SetGoState(0); // Open the door leading further in 251 264 252 265 ShatterRemainingCrystals(); … … 303 316 }else 304 317 { 305 if(IsDraining) 306 if(EmpowerTimer < diff) 307 { 308 IsDraining = false; 309 DrainingCrystal = false; 310 DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL); 311 DoPlaySoundToSet(m_creature, SOUND_EMPOWERED); 312 Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID); 313 if(CrystalChosen && CrystalChosen->isAlive()) 314 // Use Deal Damage to kill it, not setDeathState. 315 CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 316 317 CrystalGUID = 0; 318 319 m_creature->GetMotionMaster()->Clear(); 320 m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 321 }else EmpowerTimer -= diff; 318 if( IsDraining ) 319 { 320 if( EmpowerTimer < diff ) 321 { 322 IsDraining = false; 323 DrainingCrystal = false; 324 325 DoYell(SAY_EMPOWERED, LANG_UNIVERSAL, NULL); 326 DoPlaySoundToSet(m_creature, SOUND_EMPOWERED); 327 328 Unit* CrystalChosen = Unit::GetUnit(*m_creature, CrystalGUID); 329 if( CrystalChosen && CrystalChosen->isAlive() ) 330 // Use Deal Damage to kill it, not setDeathState. 331 CrystalChosen->DealDamage(CrystalChosen, CrystalChosen->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); 332 333 CrystalGUID = 0; 334 335 m_creature->GetMotionMaster()->Clear(); 336 m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim()); 337 }else EmpowerTimer -= diff; 338 } 322 339 } 323 340 -
trunk/src/bindings/scripts/scripts/zone/magisters_terrace/instance_magisters_terrace.cpp
r6 r28 17 17 /* ScriptData 18 18 SDName: Instance_Magisters_Terrace 19 SD%Complete: 10019 SD%Complete: 60 20 20 SDComment: Designed only for Selin Fireheart 21 21 SDCategory: Magister's Terrace … … 119 119 switch(entry) 120 120 { 121 case 24723: 122 SelinGUID = creature->GetGUID(); 123 break; 124 case 24560: 125 DelrissaGUID = creature->GetGUID(); 126 break; 127 case 24722: 128 FelCrystals.push_back(creature->GetGUID()); 129 break; 121 case 24723: SelinGUID = creature->GetGUID(); break; 122 case 24560: DelrissaGUID = creature->GetGUID(); break; 123 case 24722: FelCrystals.push_back(creature->GetGUID()); break; 124 } 125 } 126 127 void OnObjectCreate(GameObject* go) 128 { 129 switch(go->GetEntry()) 130 { 131 case 187896: VexallusDoorGUID = go->GetGUID(); break; 132 //SunwellRaid Gate 02 133 case 187979: SelinDoorGUID = go->GetGUID(); break; 134 //Assembly Chamber Door 135 case 188065: SelinEncounterDoorGUID = go->GetGUID(); break; 136 case 187770: DelrissaDoorGUID = go->GetGUID(); break; 137 case 188165: KaelStatue[0] = go->GetGUID(); break; 138 case 188166: KaelStatue[1] = go->GetGUID(); break; 130 139 } 131 140 } … … 165 174 return 0; 166 175 } 167 168 void OnObjectCreate(GameObject* go)169 {170 switch(go->GetEntry())171 {172 case 187896: VexallusDoorGUID = go->GetGUID(); break;173 case 187979: SelinDoorGUID = go->GetGUID(); break;174 case 188118: SelinEncounterDoorGUID = go->GetGUID(); break;175 case 187770: DelrissaDoorGUID = go->GetGUID(); break;176 case 188165: KaelStatue[0] = go->GetGUID(); break;177 case 188166: KaelStatue[1] = go->GetGUID(); break;178 }179 }180 176 }; 181 177 -
trunk/src/bindings/scripts/scripts/zone/temple_of_ahnqiraj/boss_twinemperors.cpp
r18 r28 88 88 Abuse_Bug_Timer = 10000 + rand()%7000; 89 89 BugsTimer = 2000; 90 m_creature->clearUnitState(UNIT_STAT_STUN DED);90 m_creature->clearUnitState(UNIT_STAT_STUNNED); 91 91 DontYellWhenDead = false; 92 92 EnrageTimer = 15*60000; … … 291 291 DoResetThreat(); 292 292 DoCast(m_creature, SPELL_TWIN_TELEPORT_VISUAL); 293 m_creature->addUnitState(UNIT_STAT_STUN DED);293 m_creature->addUnitState(UNIT_STAT_STUNNED); 294 294 AfterTeleport = true; 295 295 AfterTeleportTimer = 2000; … … 303 303 if (!tspellcasted) 304 304 { 305 m_creature->clearUnitState(UNIT_STAT_STUN DED);305 m_creature->clearUnitState(UNIT_STAT_STUNNED); 306 306 DoCast(m_creature, SPELL_TWIN_TELEPORT); 307 m_creature->addUnitState(UNIT_STAT_STUN DED);307 m_creature->addUnitState(UNIT_STAT_STUNNED); 308 308 } 309 309 … … 313 313 { 314 314 AfterTeleport = false; 315 m_creature->clearUnitState(UNIT_STAT_STUN DED);315 m_creature->clearUnitState(UNIT_STAT_STUNNED); 316 316 Unit *nearu = PickNearestPlayer(); 317 317 //DoYell(nearu->GetName(), LANG_UNIVERSAL, 0); -
trunk/src/bindings/scripts/sql/scriptdev2_structure.sql
r5 r28 74 74 DROP TABLE IF EXISTS `script_texts`; 75 75 CREATE TABLE `script_texts` ( 76 `id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier', 77 `sound` int(11) unsigned NOT NULL default '0', 78 `type` int(11) unsigned NOT NULL default '0', 79 `language` int(11) unsigned NOT NULL default '0', 80 `text` varchar(255) NOT NULL default '', 81 `comment` varchar(255) NOT NULL default '', 82 PRIMARY KEY (`id`) 76 `entry` mediumint(8) NOT NULL, 77 `content_default` text NOT NULL, 78 `content_loc1` text, 79 `content_loc2` text, 80 `content_loc3` text, 81 `content_loc4` text, 82 `content_loc5` text, 83 `content_loc6` text, 84 `content_loc7` text, 85 `content_loc8` text, 86 `sound` mediumint(8) unsigned NOT NULL default '0', 87 `type` tinyint unsigned NOT NULL default '0', 88 `language` tinyint unsigned NOT NULL default '0', 89 `comment` text, 90 PRIMARY KEY (`entry`) 83 91 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Script Texts'; 84 92 85 86 DROP TABLE IF EXISTS `script_localized_texts`; 87 CREATE TABLE `script_localized_texts` ( 88 `id` int(11) unsigned NOT NULL auto_increment COMMENT 'Identifier', 89 `locale_1` varchar(255) NOT NULL default '', 90 `locale_2` varchar(255) NOT NULL default '', 91 `locale_3` varchar(255) NOT NULL default '', 92 `locale_4` varchar(255) NOT NULL default '', 93 `locale_5` varchar(255) NOT NULL default '', 94 `locale_6` varchar(255) NOT NULL default '', 95 `locale_7` varchar(255) NOT NULL default '', 96 `locale_8` varchar(255) NOT NULL default '', 97 `comment` varchar(255) NOT NULL default '' COMMENT 'Text Comment', 98 PRIMARY KEY (`id`) 99 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Localized Script Text'; 100 93 DROP TABLE IF EXISTS `custom_texts`; 94 CREATE TABLE `custom_texts` ( 95 `entry` mediumint(8) NOT NULL, 96 `content_default` text NOT NULL, 97 `content_loc1` text, 98 `content_loc2` text, 99 `content_loc3` text, 100 `content_loc4` text, 101 `content_loc5` text, 102 `content_loc6` text, 103 `content_loc7` text, 104 `content_loc8` text, 105 `sound` mediumint(8) unsigned NOT NULL default '0', 106 `type` tinyint unsigned NOT NULL default '0', 107 `language` tinyint unsigned NOT NULL default '0', 108 `comment` text, 109 PRIMARY KEY (`entry`) 110 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Custom Texts'; 101 111 102 112 DROP TABLE IF EXISTS `script_db_version`;