diff --git a/VC100/100ScriptDev2.vcxproj b/VC100/100ScriptDev2.vcxproj index cf314563c..cebfb83d5 100644 --- a/VC100/100ScriptDev2.vcxproj +++ b/VC100/100ScriptDev2.vcxproj @@ -276,6 +276,7 @@ + @@ -545,6 +546,9 @@ + + + @@ -749,6 +753,7 @@ + diff --git a/VC100/100ScriptDev2.vcxproj.filters b/VC100/100ScriptDev2.vcxproj.filters index 400b891aa..41f594c92 100644 --- a/VC100/100ScriptDev2.vcxproj.filters +++ b/VC100/100ScriptDev2.vcxproj.filters @@ -1227,6 +1227,15 @@ scripts\northrend\nexus\nexus + + scripts\northrend\nexus\oculus + + + scripts\northrend\nexus\oculus + + + scripts\northrend\nexus\oculus + scripts\northrend\obsidian_sanctum @@ -1890,6 +1899,9 @@ scripts\northrend\nexus\nexus + + scripts\northrend\nexus\oculus + scripts\northrend\obsidian_sanctum diff --git a/VC80/80ScriptDev2.vcproj b/VC80/80ScriptDev2.vcproj index 63ee6ed44..e0ace264c 100644 --- a/VC80/80ScriptDev2.vcproj +++ b/VC80/80ScriptDev2.vcproj @@ -679,6 +679,10 @@ + + @@ -2122,6 +2126,22 @@ + + + + + + + + + + @@ -1977,6 +1981,22 @@ + + + + + + + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +== ICC Learning Project == + +This project has as goals: +* Learning how to use Git to work in a distibuted workflow +* Learning the base system of ScriptedAI (Base-class for SD2 Creature scripts) +* Learning the base system of how SD2 handles instance scripts +* Learning how to structure research about bosses, to get solid scripts for them +* Learning how to interact with the MaNGOS project and database projects to do things _right_ diff --git a/icc_project/documentation/day-1.txt b/icc_project/documentation/day-1.txt new file mode 100644 index 000000000..8d5ffa1b0 --- /dev/null +++ b/icc_project/documentation/day-1.txt @@ -0,0 +1,147 @@ +== First Part + +This part should introduce you to adding a new branch with Git, switching between the branches, and how to do the most basic work with Git. + +The changes for the ICC learning project are currently located at SD2 repository, within the branch "icc_project" + +This part assumes: + +* You have already cloned SD2, if not look into http://www.scriptdev2.com/showthread.php?t=4 +* You are on a clean branch, and have not yet used the name "icc_project" for a branch on your system. + See the next section how to check, and restore a clean environment + +I will always use the Git bash to work with Git. +Hence I strongly suggest for you to use it as well. +But nearly all stuff must work with GUI tools somehow +(Note for *nix User: "Open 'Git bash here'" can be translated to open a bash in the directory) + +So, to do anything with Git, we will open a Git bash in the ScriptDev2 directory in your MaNGOS source folder - in src\bindings\. + +To do so, open your explorer, right click the "ScriptDev2" directory and select "Git bash here" from the context menu. + +This will open a nice black and white window, where you can type commands in a very old fashioned way :) + +=== Checking your status + +The first and most important command is +-------------------------------- +git status +-------------------------------- +This will show the current state of your work tree related to the index. + +What does this mean: +When you look at your ScriptDev2 directory, there are two things you must keep in mind: + +* The directory contains files - these files are referred to as the work tree, and are just normal files. +* Git has an internal representation of the history related to your project, this history is stored in the index. + +So +git status+ now shows you in which state every file in your work tree is in relation to what state the file should be compared to your current history index + +The default output should be: +-------------------------------- +# On branch master +nothing to commit (working directory clean) +-------------------------------- + +This shows you that you are on your "master" branch (this is default), and that you have no change related to your history (working directory clean) + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Check the status +================================================================== +Add or change a file, and compare the output of +git status+ +================================================================== + +If you have a not clean working tree, you must clean it. + +=== Resetting your working tree to the index +[WARNING] +================================================================== +This will delete all changes! +-------------------------------- +git reset --hard +-------------------------------- +================================================================== + +Note: This will only affect files which are known to the index, so a new created file won't get deleted. + +Remark: This will only give you what I expect, if you didn't too many experiments yourself. + +=== Updating your remote information for the SD2 repo. + +The SD2 repo (assuming it was cloned from initially) should be named "origin" +If you have done nothing special, it will be and you don't have to worry. + +To update the information for the remote origin repository, simply do: +-------------------------------- +git fetch +-------------------------------- + +=== Cloning the remote branch containing the icc learning project. + +Git is really great when it comes to branching. +This means, it is easy to have different branches of history-indexes and to switch the working-tree files between them. + +The reason why branches are so cool is, that one branch does not change the history of another branch. +So it is very easy to have different things to work on. + +The process to switch the working tree from one history branch to another is called "checkout", and hence the command that is to be used is +-------------------------------- +git checkout +-------------------------------- +where is the name of the branch to which you will switch your working tree + +However, before you are able to checkout to a branch, you must create it. + +To make this easier, there is the "-b" option for the checkout command: + +All in all you should type: +-------------------------------- +git checkout -b icc_project -t remotes/origin/icc_project +-------------------------------- + +This will do the following: +[horizontal] +*-b*:: create a new branch named "icc_project" +*-t*:: use the point from which you branch as "tracking" branch +*remotes/origin/icc_project*:: is the branch icc_project in the repository origin which is a remote repository + +=== Switching between branches: + +As already mentioned, you can easily switch between branches with +-------------------------------- +git checkout +-------------------------------- + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Test switching +================================================================== +Observe changes of files in the directory (especially the sub directory icc_project) while switching with +-------------------------------- +git checkout master +git checkout icc_project +-------------------------------- +================================================================== + +== End of First Part + +=== What this part was about: + +* Checking the status of working tree, command > git status +* Checking out a remote branch into a local branch +* Switching branches, command > git checkout + +=== Most important concepts: + +* index and working tree (What were they?) +* branches in Git (What are they used for?) + +=== Additional resources: + +TIP: http://www.youtube.com/watch?v=4XpnKHJAok8[Tech talk about what Git is not] This is a nice vid, it should clarify why we use git, and explain some more concepts of Git :) + +=== What comes next: + +* How to do local commits +* How to read history diff --git a/icc_project/documentation/day-2.txt b/icc_project/documentation/day-2.txt new file mode 100644 index 000000000..775a32c87 --- /dev/null +++ b/icc_project/documentation/day-2.txt @@ -0,0 +1,378 @@ + +From Day 1 you should have learnt these things: + +* Meaning of working tree and index: The working tree are the actual files on your file system, the index is the history information +* The concept of branches: A branch is a branch of the history index + +Also you should be able to switch between branches with +git checkout+ and to check the state of your working tree related to the index with +git status+ + +== First Part: + +This part now should introduce you to know how to actual see the history. + +=== Excursion: The pager 'less' + +This is especially important for Windows user! + +When using Git via Git bash, the default tool set is the archaic tool set every *nix fan will have learnt by heart, but they can be extremely weird from Windows view. + +In old times, when there was nothing except console and there were no possibilities to scroll in the text, console environments had the so called pager programs, which were used to be able to scroll in output. + +Assume you would have an enormous amount of text, so if you would push it directly onto the console, you would not be able to read anything, because it would be way too fast. + +So, the idea is to give the output to a program -- the pager -- which allows you to scroll up and down in the output. + +Default pager on *nix is 'less' - which Git bash uses by default to show the history (or many other things). +You can scroll in there with the arrow keys or a whole page by the space bar. +And most important: You quit less by pressing "q" + +[TIP] +================================================================== +http://unixhelp.ed.ac.uk/CGI/man-cgi?less[The man page for less can be found here] + +(Disclaimer: I don't take responsibility for brain damage caused by any provided link here!) + +Anyhow: A better "guide" for less to link would be appreciated, but trying to search for "how to less" kind of doesn't work. +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Try to find a better less how-to and take a look +==================================================================================================================================== +Hint: add "unix" to your search attempt :) +==================================================================================================================================== + +=== Viewing the history of a branch in Git + +OK, now we can look into the history of the current branch, this is done simply by +-------------------------------- +git log +-------------------------------- +Just do so now :) + +Remember: To close the output, type "q" + +The most recent commits (see 3) might look like this: +-------------------------------- +commit 1cebd00445e7bd92927f305e40225de1049d450c <1> +Author: Schmoozerd <2> +Date: Tue Oct 4 02:02:44 2011 +0200 <3> + + Add some files and documentation for the first part <4> + +commit e0601735424f712d685330b421898db16a366b17 <1> +Author: Schmoozerd <2> +Date: Tue Oct 4 01:14:46 2011 +0200 <3> + + Initial Commit for the ICC Learning project <4> +-------------------------------- + +*What does this show:* + +<1> This is the hash of the commit, which should globally uniquely identify any commit. + Usually it is enough to only take the first ~6 digits. + This is more or less the "name" of the commit +<2> Yes you guessed rightly, this is the author of the commit +<3> When the commit was authored +<4> This is the message the author thought might be helpful to describe the commit + +*So - what is git log useful for?* + +With git log you are able to see the history, who did which changes, and in which order. +Also git log has a big amount of options, which help you to actually search for a specific commit (ie by author) + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Search the history by author +================================================================== +If you have already submitted a patch to SD2, that got accepted it is likely that you are "author" of a commit. Check with +-------------------------------- +git log --author="yourNickName" +-------------------------------- +If you are not, pick anyone whom you think has contributed and look what +git log --author+ tells you ;) +================================================================== + +=== The structure of objects in the git history index + +When you do a change, and make this change known to the history, then you have a "commit" + +Any commit has: + +* An author +* A commit hash (the strange numbers already seen in git log) +* The set of changes it describes (if you didn't change anything, there is no commit!) + +* One previous commit on which the commit is done. + +As of the last statement, you have a chain of commits. And this is your history! + + +=== View a commit + +You can view a commit with +-------------------------------- +git show +-------------------------------- + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 3* - View a commit by hash +================================================================== +-------------------------------- +git show 111cea5073191b +-------------------------------- +What commit does this refer to: What is the commit message? Who is the author? When was it committed? +================================================================== + +=== How to access commits + +Things are only useful if you can work with them, and to do so you need powerful ways to access them. +Git provides reasonable ways to "get to" a specific commit. + +You have already seen the commit hash, this identifies a commit and hence is a great accessor (except that no one can remember endless amounts of hash-ids) + +When you are on a local branch, "HEAD" always points to the top-most commit of your local branch. + +A branchname always points to the HEAD commit of the branch with the branchname + +"~N" refers to "N commits before the commit + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 4* - Look into a few commits +================================================================== +Try these examples, maybe a few more. +-------------------------------- +git show HEAD~1 +git show master +git show master~304 +-------------------------------- +Remember: To close the pager, type "q" +================================================================== + +=== Advanced looking into the history: + +Now that you know how commits are accessed, you are able to invoke more features from git log. + +TIP: http://book.git-scm.com/3_reviewing_history_-_git_log.html[For interested Readers - this goes quite ahead for now] + +== End of First Part + +=== What this part was about: + +* Knowing what a 'commit' means. +* Showing a commit ( +git show+ ) +* Knowing how to access various commits + +== Second Part + +From the first part of today you should know what commits are, and how to find them. +Also you should feel safe about concepts as branches, working tree and index + +Now it is time to start doing some own commits! + +=== Why commit? + +* When you commit, you get the full power of Git to track your history. +* Also commits are easier to merge and handle than changes that are just there. +* Also with committing, you are able to provide extra information in the commit message to tell "what you have done why". + +So, the golden rule of thumb is: + +[IMPORTANT] +================================================================== +*Commit often, commit early!* + +And of course: Publish your commits! (More about this likely tomorrow) +================================================================== + +=== How to commit: + +The base command to commit changes is +-------------------------------- +git commit +-------------------------------- +however this command alone won't make you very happy. + +You must tell Git which changes you want to commit. +A very reasonable way is often, to commit all changes, like with +-------------------------------- +git commit -a -m"My first commit" +-------------------------------- +Where +[horizontal] +*-a*:: commit _all_ changes in all tracked files +*-m *:: take as commit message, note that I used ".." to mark the whole text as message + +*Example:* This commit was added with +-------------------------------- +> git commit -a -m"Day 2, Part 2 Howto git commit" +-------------------------------- + +==== Track new files + +As this would only commit changes in already tracked files, you might wonder how to commit (changes to) new files. + +You can add a new file with +-------------------------------- +git add path/to/fileName +-------------------------------- +Then the file named fileName located in path/to/ will be committed with your next +git commit -a+ command + +Remark for later: If you plan a couple of commits, it might be a good idea to fork a new branch and commit them there + +==== Workflow in Git + +By using these commands, the usual work flow in Git represents itself like this: + +You edit a few files +-------------------------------- +git commit -a -m "Some cool edits" +-------------------------------- +You edit more +-------------------------------- +git commit -a -m"More cool edits" +-------------------------------- +You edit even more +-------------------------------- +git commit -a -m"The coolest edits ever" +-------------------------------- +Then you check your work with +-------------------------------- +git log +-------------------------------- + +The topmost three commits should then be + +. The coolest edits ever +. More cool edits +. Some cool edits + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 5* - Do some test commits +==================================================================================================================================== +Suggested files to change might be found in icc_project\research +==================================================================================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 6* +================================================================== +Look at your work with +git log+ +================================================================== + +WARNING: Special Exercises are not important to do right now, but if you feel confident or want to test some things feel free to explore a bit + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 7* - Commit changes with a new file +================================================================== +Add a new file to git and commit it (lookup +git add+) +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 8* - Commit in a branch +================================================================== +To start invoke +git checkout -b testing+ +Remember: the -b will create a new branch, and git checkout switches to a branch +================================================================== + +==== Possible additional sources related to this topic: + +TIP: http://book.git-scm.com/3_normal_workflow.html (unfortunately it seems the flash vids showing this are gone) + +TIP: http://www.youtube.com/watch?v=8dhZ9BXQgc4[Tech Talk of what Git is about] I think I don't like the style of the speaker too much - but maybe you do :) + +=== Undo Changes + +This section will show up every now and then, because there are different ways to undo things, depending on what and how you want to undo. + +It is not necessary, but I suggest to remove the testing changes from Ex. 5-7 from your icc_project branch. + +Do so by switching into this branch with + +-------------------------------- +git checkout icc_project +-------------------------------- + +and reset to origin state with + +-------------------------------- +git reset --hard origin/icc_project +-------------------------------- + +=== Excursion: The editor 'vi' + +You remember that Git uses by default the archaic pager 'less' in some cases? + +They are even more hostile, because in some cases by default (when there is need to edit something) Git will start the well loved 'vi' editor. + +==== Change default editor in Git, aka 'The good news' + +You can change the default editor to some editor that at least is usable for people who didn't suffer years of brain damage caused by vi and think this is a good editor :) + +To change the default editor, look at this line carefully: +-------------------------------- +git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin" +-------------------------------- +This is however only an example how it worked on my system. + +==== Reasons why 'vi' is still worth knowing about: + +* Every *nix system has vi, and it works nicely over ssh -- so it might be required some day to know at least the very basics +* Actually vi performs quite nicely related to big files +* Well, vi is very powerful + +Besides I like it, refer to brain damage to understand why ;) + +As vi originates in the golden ages when mice where only found under the desk of full-time hackers, +and not on the desk related to GUI editors, there was the very pressing question how to know if you want to invoke a command (ie "save" ) or when to write a word (ie "save" ). +Many editors solved this by using CTRL and similar for command mode, and normal typing else wise. + +However vi went another way (because of more powerful features and because ctrl and similar caused trouble on telnet sessions). + +==== How 'vi' works +vi has a few different modes, which can be switched and entered with a few buttons: + +* The INSERT mode: When this mode is active, there is a "-- INSERT --" marked on the bottom of your console, and in this mode vi behaves like normal editors. +If you type things, they will show on the screen - so you will do what you expect from an editor: you will edit a file + +* The command mode: In this mode, pressing keys are considered as commands, and do confusing things! + +===== How to switch between the modes: +When you start vi you are in the command mode. Press "i" to start the insert mode. +When you are in the INSERT mode, press "Esc" to leave the INSERT mode and return to command mode. + +===== Closing 'vi' + +Actually most people green to vi wonder about one thing most: + +*How to close the damn program?* + +The answer is relatively easy: + +You must be in the command mode, and then press ":". This will activate a special mode (for interested: ex-mode) in which you can type in commands. +the most useful commands are: (you don't need to press the ":" again) + +[horizontal] ++:wq+:: Write and Quit, which it does, and you will have manged to quit vi ;) ++:q+:: Only quit, to do so there must be no change ++:q!+:: Quit and discard changes you made + +TIP: There are tons of docs for vi out there, maybe http://www.gentoo.org/doc/en/vi-guide.xml is a good one. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 9* +================================================================== +Do a few changes and use > git commit -a and experiment :) +================================================================== + +== End of Second Part + +=== What this part was about: + +* Doing own commits with git commit +* Really encouraging to do own simple tests now! diff --git a/icc_project/documentation/day-3.txt b/icc_project/documentation/day-3.txt new file mode 100644 index 000000000..33ee726f7 --- /dev/null +++ b/icc_project/documentation/day-3.txt @@ -0,0 +1,170 @@ +In Day 2 we showed what commits are, how to navigate in them, and how to create them. + +This part is now about the content of a commit. +Remember the (meta) structure of a commit: + +* Commit hash +* Commit date +* Author information +* Commit message +* Content changes + +Today we will talk about the Content changes in each commit. + +== First Part: + +=== The diff format + +One of the natural ways in programming to display changes between two files (or two states), is a so called "diff". + +Usually this might look like this: (pointless example to emphasise how to read it) +-------------------------------- +diff --git a/README b/README <1> +index bba7c29..79dc7e6 100644 +--- a/README ++++ b/README +@@ -22,7 +23,7 @@ that comes with MaNGOS ( http://www.getmangos.com ), written in C++ and is <2> + compatible with Windows and Linux. SQL needed for database support both <3> + MySQL and PostgreSQL. <3> + +-This script library provides unique scripts for NPCs, gameobjects, events <4> ++This script library provides unique and great scripts for NPCs, gameobjects, events <5> + and other that need unique implementation. <3> + + Once ScriptDev2 is compiled it is automatically run by MaNGOS on server <3> + +-------------------------------- + +*You can read such a (unified) patch format like this:* + +<1> diff --git a/path/to/file b/path/to/file + This line tells you that you have a diff created with git, and it has the changes in path/to/file (two versions, a and b) +<2> @@ -A,B +C,D + This line tells you where the hunk you have changes with is located, and how big it is. + - A is the line where the content did begin in the first version + - B is the length of the hunk before the change in the first version + - C is the line where the content begins in the second version + - D is the length of the hunk in the second version +<3> A content (unchanged) line always starts with a blanc +<4> A line starting with a minus sign indicates that this line is removed +<5> A line starting with a plus sign indicates that this line is added + +*So, now to our example diff:* + +the first line tells us, that we look at a change for the file README (located in main ScriptDev2 directory) + +Open it and look into line 22 (A). + +line 22 currently is +compatible with Windows and Linux. SQL needed for database support both+ + +so we know that we are in the right place to apply our changes. + +A few lines later, we see the line +This script library provides unique scripts for NPCs, gameobjects, events+ +which out diff replaces with the line +This script library provides unique and great scripts for NPCs, gameobjects, events+. + +(Clearly: if you delete a line, and insert at the same place another line, you actually do replace this line) + +Note that a diff can consist of changes for multiple files, and each file changes can consist of multiple hunks + +TIP: http://en.wikipedia.org/wiki/Diff[Further documentation] including various similar diff formats are also mentioned there, perhaps just look into it when reading the second time + +=== Creating a diff with Git + +-------------------------------- +git diff +-------------------------------- + +This is one of the most important commands in Git. + +With git diff you see the change set as unified diff between the current working tree and the HEAD + +For memory: HEAD is the topmost commit in the current branch + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Use git diff +================================================================== +Edit a few files and see what happens with +git diff+ +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Compare to diff above +================================================================== +Edit the README in a way to get the same unified diff I posted above - did I cheat? +================================================================== + +TIP: http://book.git-scm.com/3_comparing_commits_-_git_diff.html[Further documentation] his will show additional more advanced uses of git diff, but you should be able to understand them! + +=== Other important commands to see diffs + +You already should know +git show+ - this commands also shows the changes of the specified commit as unified diff (after some meta information of the commit) + +However with this command, you can only see the changes of a commit, not between current working tree and index + +Another tool I like very very much to see diffs of multiple commits is +-------------------------------- +git format-patch +-------------------------------- + +* However this tool creates by default a bunch of diff-files, to prevent this you can use the +--stdout+ option. +* Also you should specify from which point on you want to see the commits. +* Also you can specify to which point you want to see the commits. + +I usually use it this way: +-------------------------------- +> git format-patch [..] --stdout +-------------------------------- +With the meaning: + +[horizontal] +:: Commit, from which the changes will be shown (see day2 how a commit can be referenced) + ..:: Optional commit, to which the changes will be shown ++--stdout+:: print the output to the console instead of creating files for each commit + + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 3* - Basic example for git format-patch +================================================================== +Use format-patch to see the changes between master and icc_project, try +-------------------------------- +git format-patch master --stdout +-------------------------------- +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 4* - git format-patch for different branches +================================================================== +Do Day 2 - Special Exercise 8 if you have not already done, and look at the format-patch output between the created testing branch and the icc_project branch +================================================================== + +=== Cleanup what happened today + +Assuming you are on the icc_project branch, and you have no "valuable" custom changes on there, use +-------------------------------- +git reset --hard origin/icc_project +-------------------------------- +to reset all changes of tracked files from your index and working tree. + +Check if everything is nice with +git status+ ;) + +== End of First Part + +This Part should have shown how to use the commands +-------------------------------- +git diff +git show +git format-patch +-------------------------------- +to look into changes of commits, or between commits and the working-tree + +*Basic concepts:* + +* You should have a rough feeling of how to "read" unified patches. + +*What comes next:* + +* A small Excursion into Bash redirection and pipes, look into http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html if curious +* How to apply unified patches with git apply and git am diff --git a/icc_project/documentation/day-4.txt b/icc_project/documentation/day-4.txt new file mode 100644 index 000000000..507183b9d --- /dev/null +++ b/icc_project/documentation/day-4.txt @@ -0,0 +1,246 @@ + +From Day 3 you should have learnt these things: + +* How to read unified diffs +* How to use +git diff+, +git show+ and +git format-patch+ to create diff between different commits or the working tree + +Today now is about how to + +* Create patch files, that is files which contain the output from the above commands +* How to apply them + +== First Part: + +A very neat way to create the patch files within a bash (ie Git bash) is to use the output redirection + +=== Excursion: Some notes about working with a console + +*Reasons to still use a console environment for some things* + +* You definitively will feel like a geek! ++ +(Do we actually need more reasons?) + +* Using a console is for some things very fast (and very slow for others) +* Reasonable to learn, as *nix systems won't proper work without (Windows systems won't work proper without using +cmd+ now and then, only that the cmd sucks) + +*Most useful commands in a bash console* + +OK, to clarify: When you type commands into a console, there is actually a program that interprets these commands. + +Some examples are the cmd (from (win)do(w)s), or bash which got popular on Linux + +[horizontal] +*ls*:: List the content of the current directory (on Windows this was called +dir+) +*cd*:: Change your directory. If you invoke +cd ..+ then you will change into the parent directory +*cat*:: Can be used to get text from a file onto the console +*cp* A B:: Copy a file from A to B +*mv* A B:: Move a file from A to B (if A and B are in the same directory, than this renames) +*rm* A:: Remove (this means delete) file A +*mkdir*:: Create a directory +*rmdir*:: Remove a directory + +*Very useful things:* + +Auto completion (Bash can do this):: +If you want to type something, and press the +tab+ key, the bash will try to auto complete a word for you. ++ +Example: Type (in the ScriptDev2-directory) into the bash: +ls to+ and then press the +tab+ key. + +Copy and Paste in the bash (For Windows users):: +If you click on the top-left corner of your console window, you can select "Edit" and there "Mark" and "Paste". Also you can use the INSERT key to paste the content of your clipboard ++ +(Marking is finished with +enter+, the marked text will then be in your clipboard) + +Using previously typed commands:: +With the arrow keys (up, down) you can reuse previous commands easily. + +=== Excursion: Bash output/ input redirection + +For most console based systems it is possible to use these types of output redirection + +[horizontal] +*>*:: Forward the output into a file, the file will be created if it does not exist, and truncated before refilled if it exists +*>>*:: Forward the output into a file, but append if the file already exists +*|*:: (Called pipe) Forward the output from the program as input to the next program +:: A few more exists which I won't cover! + +Remember the nice tools like +git diff+ or +git format-patch --stdout+ from Day 3? + +They were working nice, but only displayed their stuff in the console. + +The trick to get their output into files is to use output redirection. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Use output redirection to create patch files +================================================================== +* Do Exercise 1 from Day3, but redirect the output of +git diff+ with +git diff > temp_diff.patch+ +* Do Exercise 3 from Day3, but redirect the output of +git diff+ with +git diff > temp_format.patch+ + +And look at these created files with a patch tool (if you have one installed), an editor and +cat+. +(To use cat do: +cat temp_diff.patch+ and +cat temp_format.patch+) + +Congratulation, you have created your first patch files! +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Use output redirection to create patch files +================================================================== +Do some more edits and test bash auto completion with +git diff > te+ +d+ +================================================================== + +Sometimes you might not want to get all changes directly into a file, but would like to view the output of ie +git format-patch --stdout+ slowly. + +Remember the pager 'less' from Day 2? + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 3* - Fais la pipe (My French is bad, maybe it was Utilize) +================================================================== +Use +git format-patch master --stdout | less+ +================================================================== + +== End of First Part + +[TIP] +================================================================== +If you still cannot get enough about using bash, look http://linux.org.mt/article/terminal[here] + +For more bash programming purposes look http://tldp.org/LDP/Bash-Beginners-Guide/html/[here] + +If anybody finds a neat beginners guide suitable for this topic, please inform! +================================================================== + +== Second Part: + +Now we want to apply a few patch files. + +You will need the patch files you created in Part 1 - Exercise 1! + +Also you should copy the content of https://github.com/scriptdev2/scriptdev2/commit/9438d49b62f81d543489b87e8c8e60d94afb1fcd.patch[SD2-Commit 2302] +into a file in your ScriptDev2 directory, expected name +sd2_2302.patch+ + +=== Applying patches with git apply and git am + +Both commands apply a patch from a filename with appropriate format if possible. + +git am:: +Git am applies a patch created with +format-patch+ to the 'index' ++ +As a formatted patch contains some meta information of the commit(s) from which it was created, it will directly commit the change sets from the commits, and thereby using the provided meta information in the patch file. ++ +Hence a patch file for git am must contain this information in a defined way. + +git apply:: +Git apply applies a patch created with git show or git diff to the 'working tree' ++ +These patches contain no additional meta information, and hence won't be committed automatically. + +To apply the following examples, be sure to be on clear icc_project, to do so use +-------------------------------- +git reset --hard origin/icc_project +-------------------------------- + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 4* - Apply a patch with git apply +================================================================== +Apply the patch created in Exercise 1 from file +temp_diff.patch+ +-------------------------------- +git apply temp_diff.patch +-------------------------------- +Check what this did! Use git status, git diff and git log to see what this did! + +Reset your changes with +git reset --hard+ +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 5* - Apply a patch with git am +================================================================== +Apply the patch from file +sd2_2302.patch+ +-------------------------------- +git am sd2_2302.patch +-------------------------------- +Check what this did! + +Reset your changes with +git reset --hard origin/icc_project+ +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 6* - Why why why? +================================================================== +Why did I suggest to use different ways to git reset --hard in exercises 4 and 5? +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 7* - Some first conflicts +================================================================== +Try to apply the changes in +temp_format.patch+ with +git am+ + +This gives errors - Why? + +To abort the attempt to apply this with git am, use +-------------------------------- +git am --abort +-------------------------------- +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 8* - Apply to a conflict free point +================================================================== +Find a point in the history where the changes from +temp_format.patch+ could be applied! + +Checkout to this point, and apply there +-------------------------------- +git checkout -b apply-safe +git am temp_format.patch +-------------------------------- +Now you have applied the patch file. Check what happened with the usual suspects :) +================================================================== + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Special Exercise 9* - Merging conflicts +================================================================== +Checkout to your icc_project branch + +Try to merge the apply-safe branch into your current branch, try +git merge apply-safe+ + +This will give the same conflicts as you had in Exercise 7, but now you have the possibility to use the powerful tools of git to merge. Actually for me merge went without problems! + +However if you still get conflicts, abort the merge with git reset --hard +================================================================== + +Now, there might have been many changes, and it is time to cleanup: + +-------------------------------- +git checkout icc_project +git reset --hard origin/icc_project <1> +git branch -D apply-safe <2> +rm sd2_2302.patch <3> +rm temp_format.patch +rm temp_diff.patch +-------------------------------- + +<1> Do you already know why this time the reset --hard version with origin/icc_project was used? +<2> git branch -D will delete a branch +<3> Remove a few untracked files - check for more with +git status+ + +== End of Second Part + +Today we have seen + +* how to use a console environment +* how to use dark console powers to create patch files +* how to apply patch files +* how using Git the right way conflict solving can become very easy! (Special exercises) + +So, now we have the tools in place to actually start working on ICC code. + +Expect the first steps toward a C++ script in the next days! diff --git a/icc_project/documentation/day-7.txt b/icc_project/documentation/day-7.txt new file mode 100644 index 000000000..360f525f2 --- /dev/null +++ b/icc_project/documentation/day-7.txt @@ -0,0 +1,299 @@ +From the first week you should have learnt how to use Git to manage your source code + +In this week we will start to look at the basic parts of actual boss scripting. + +Today now is about how to + +* What the first script looks like +* A few elemental things about object oriented programming (OOP) + +== First Part: + +=== The very first script + +In commit 55481e02, see https://github.com/scriptdev2/scriptdev2/commit/55481e026600049a66277ee4e71110b1ba797418[Commit on Github] I added the following patch to the icc_branch: + +-------------------------------- +From 55481e026600049a66277ee4e71110b1ba797418 Mon Sep 17 00:00:00 2001 +From: Schmoozerd +Date: Tue, 11 Oct 2011 18:51:53 +0200 +Subject: [PATCH] ICC, Festergut - Implement first script + +--- + .../icecrown_citadel/boss_festergut.cpp | 23 ++++++++++++++++++++ + sql/mangos_scriptname_full.sql | 3 ++ + sql/updates/r8800_mangos.sql | 1 + + 3 files changed, 27 insertions(+), 0 deletions(-) + create mode 100644 sql/updates/r8800_mangos.sql + +diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +index d0ce130..acd358d 100644 +--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp ++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +@@ -38,6 +38,29 @@ enum + SAY_FESTERGUT_DEATH = -1631091, + }; + ++struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI <1> ++{ ++ boss_festergutAI(Creature* pCreature) : ScriptedAI(pCreature) ++ { ++ Reset(); ++ } ++ ++ void Reset() <2> ++ { ++ } ++}; ++ ++CreatureAI* GetAI_boss_festergut(Creature* pCreature) <3> ++{ ++ return new boss_festergutAI(pCreature); ++} ++ + void AddSC_boss_festergut() + { ++ Script* pNewScript; <4> ++ ++ pNewScript = new Script; ++ pNewScript->Name = "boss_festergut"; ++ pNewScript->GetAI = &GetAI_boss_festergut; ++ pNewScript->RegisterSelf(); + } +diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql +index 8d95c69..de37e42 100644 +--- a/sql/mangos_scriptname_full.sql ++++ b/sql/mangos_scriptname_full.sql +@@ -707,6 +707,9 @@ UPDATE creature_template SET ScriptName='npc_silvermoon_harry' WHERE entry=24539 + /* ICECROWN CITADEL */ + /* */ + <5> ++/* ICECROWN CITADEL */ ++UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626; ++ + /* FORGE OF SOULS */ + UPDATE creature_template SET ScriptName='boss_bronjahm' WHERE entry=36497; + UPDATE creature_template SET ScriptName='npc_corrupted_soul_fragment' WHERE entry=36535; +diff --git a/sql/updates/r8800_mangos.sql b/sql/updates/r8800_mangos.sql +new file mode 100644 +index 0000000..262da6d +--- /dev/null ++++ b/sql/updates/r8800_mangos.sql +@@ -0,0 +1 @@ <6> ++UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626; +-- +1.7.6.msysgit.0 + +-------------------------------- + +==== How this commit and patch here were created: + +-------------------------------- + +git add sql/updates/r8800_mangos.sql ## To track this new file +git commit -a -m "ICC, Festergut - Implement first script" ## Commit all changes and name commit msg +git log ## To get the hash-id +git format-patch HEAD^..HEAD --stdout > temp.patch ## Get the patch (and pasted here) +-------------------------------- + +==== What can be seen here + +Actually there are 6 main steps that I did - Don't worry, they should be clear by the end of the day: + +<1> The actual class for the bossAI (AI = Artificial Intelligence) to be scripted +<2> Any SD2 Boss script must implement the Reset function +<3> The wrapper to actually create an instance of the implemented class +<4> Some internal magic to help registering a script to SD2 side such that it can be used after assigned to the database. ++ +Remark especially that the to be used ScriptName is assigned here, too + +<5> The required SQL-changes for +mangos_scriptname_full.sql+ +<6> The required SQL-changes for the sql update file + +=== Object oriented programming + +This is now about the most fundamental aspect -- *objects* and *classes* + +==== What is a class? What is an object? + +A class is the 'shape' or an 'idea' of *things* that we have in our mind. + +I will stay with the name 'idea' for now, because I think to distinct between classes and objects, it is (for now) easier to use the words "thing" and "idea". + +When you go outside, then you might see an actual tree that grows high up into the air. This tree is an actual 'thing', that you can see, feel, smell and so on, it is part of the reality. +Nearby, there might be another tree, which would be another 'thing', but also an tree. +As a matter of fact, to read this sentence you must have an 'idea' of trees in your mind (connected to the word tree), which helps you to recognise a tree when you see one. + +So, in your mind there lives the 'idea' of tree, and in reality you can see 'things' that fit into the category tree - which is the 'idea' tree you have. + +If you want to know if a 'thing' is a tree, you might compare the properties of the thing you see to the 'idea' of tree you have in your mind. In your example (tree) reasonable properties would be: +A tree has roots, a stem, branches, and in summer the branches have leaves or needles. Also you might expect that the stem is quite tall, the roots are mostly in the earth, and so on.. + +Important of the concept of ideas is that you can differ: +No real 'thing' is exactly like the 'idea' of it, and no 'idea' is exactly like any real thing. They both live in different planes. + +About functionality: +* An idea can have attributes, expected behaviour (drop leaves in winter), and ways to modify it (nick an apple) +* The things realises - which means fill the values and behaviour - of these functionalities + +In OOP (Object Oriented Programming) this concept is used in this way: +* An 'idea' is represented by a *class*, +* A 'thing' is represented by an *object* (or often called *instance* (of the class) ) + +Note: I feel this is not well written, any improvements are very welcome + +==== A class hierarchy + +As noted above the concepts of classes and objects is very natural to the way we think, and there is one other big part that is important: *Inheritance* +Classes can be subclasses of other classes, or parent classes of other classes. + +This means, a class "A" which is a subclass of class "B" inherits all stuff from class B, but might overwrite a few things, or extend functionality. + +If you now have many classes, which have sub and super classes, you have a hierarchy. + +As this is also a very fundamental concept, I will give a very simple example: + +*Possible class hierarchy of two dimensional elemental geometric shapes* + +image:images/geo_shapes.png[Image: Class hierarchy for geometric shapes] + +See also http://666kb.com/i/bxpk46qvs7hzcu7am.gif[In case the image does not directly work] + +There you can see (in some UML notation) the setup: + +* A super class which is rather abstract, named GeometricalShape ++ +This class has the attribute of the +LeftBottomCorner+ (of type Point ), a +Color+ attribute and a function to get the area +GetArea+ + +* A "Circle" is a geometric shape, hence it is realised as a subclass. ++ +Note that the attributes Color and LeftBottomCorner are inherited from GeometricShape. ++ +The function +GetArea+ needs to be overwritten to reproduce the expected result + +* A "Rectangular" is also a geometric shape, however there we need an additional point (Could have also used height and width). +* A "Square" is a specialisation of a rectangular, hence realised as subclass + +NOTE: These are only classes, no objects yet! + +===== C++ implementation of this hierarchy + +This is a sketch of normal C++ implementation + +-------------------------------- +class GeometricShape <1> +{ + GeometricShape(Point leftBottomCorner, int color) <2> + { + m_pLeftBottomCorner.x = leftBottomCorner.x; <3> + m_pLeftBottomCorner.y = leftBottomCorner.y; + m_iColor = color; + } + + virtual float GetArea() { return 0.0f; } <4> + + Point m_pLeftBottomCorner; <5> + int m_iColor; +}; + +class Circle : public GeometricShape <6> +{ + Circle(Point leftBottomCorner, int color, float radius) : GeometricShape(leftBottomCorner, color) <7> + { + m_fRadius = radius; + } + + float GetArea() <8> + { + return radius*radius*(float)PI; + } + + float m_fRadius; <9> +}; +... +-------------------------------- + +What do the different lines mean: + +<1> This tells C++ that a new class starts which is named +GeometricShape+ +<2> This is the constructor of the class (when an object of a class is instantiated, the constructor is the first thing that is called) ++ +Here we tell the constructor to require two parameters, one of type Point, and one of type int + +<3> Here we set the internal values of the class to the parameters given in the constructor +<4> This is the default function to return the area of the geometric shape ++ +The virtual keyword is there, to mark this function to be overwritten by subclasses + +<5> These are two member variables for the class. ++ +This is in Hungarian Notation which we use in ScriptDev2. For more information see http://www.scriptdev2.com/showthread.php?t=4098[SD2 Coding Standards] + +<6> This defines Circle as subclass of GeometricShape (by the :) +<7> Constructor for Circle, we call the constructor of GeometricShape, and also set the new member variable +<8> Overwrite the GetArea function to return the expected value for a circle. +<9> A member variable of Circle + +[TIP] +================================================================== +Some overview for OOP: http://en.wikipedia.org/wiki/Object-oriented_programming[wikipedia OOP overview] - This covers mostly concepts + +A fair warning about the example I chosed here: http://en.wikipedia.org/wiki/Circle-ellipse_problem[Why it works in this simple way, but may fail in other cases] + +Some C++ specific tutorial, which goes far further than such a small guide like this would ever do: http://www.desy.de/gna/html/cc/Tutorial/tutorial.html +================================================================== + +== Back to the class hierarchy for boss scripts in ScriptDev2 + +-------------------------------- +struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI <1> +{ + boss_festergutAI(Creature* pCreature) : ScriptedAI(pCreature) <2> + { + Reset(); + } + + void Reset() <3> + { + } +}; + +CreatureAI* GetAI_boss_festergut(Creature* pCreature) <4> +{ + return new boss_festergutAI(pCreature); <5> +} +-------------------------------- + +<1> In this line we define the class +boss_festergutAI+ as a subclass of +ScriptedAI+ ++ +* struct and class mean for us for now the same +* the +MANGOS_DLL_DECL+ can be considered as magic, that is required because we implement a class for a DLL to be used by another project + +<2> The constructor for our class: We inherit stuff from ScriptedAI, and call its constructor first, then we do some own code +<3> Reset is a so called "pure virtual function" which means a subclass must implement it, else wise it won't compile +<4> This is now something new. If you have read the stuff above carefully you would have noted that we have yet only implemented classes, but never objects. ++ +But of course we want to handle objects, each boss should have a specific object/ instance of the AI loaded. This is done with the +new+ keyword. + +<5> This line creates a new object of the class +boss_festergutAI+ and handles this newly created class back to some other places (actually to mangos) where it is assigned to the real boss. + +== End of first part + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Test the first script! +================================================================== +Compile SD2 with these changes, and then test the script on boss festergut. + +As the script does not do very much, use the +.npc aiinfo+ command, to see if it is actually loaded +================================================================== + +What you should have seen today: + +* Basic things of OOP: Classes and Objects +* Inheritance as fundamental concept to make the programmers' life easier + +What comes next: + +* A few notes to class hierarchy used in ScriptDev2 (CreatureAI <- ScriptedAI <- boss_*AI) +* How to bring life to the first script. diff --git a/icc_project/documentation/day-8.txt b/icc_project/documentation/day-8.txt new file mode 100644 index 000000000..6a054efde --- /dev/null +++ b/icc_project/documentation/day-8.txt @@ -0,0 +1,232 @@ +In Day 7 you should have seen: + +* A few basic ideas of OOP +* What a minimal ScriptDev2 script looks like, and how it is added to the system + +This day is now about + +* A description about the main classes used for boss scripts in ScriptDev2 +* A few things you can do with the provided powers + +== First Part + +Interaction between MaNGOS and ScriptDev2 for Creature AIs + +=== The CreatureAI class + +The class 'CreatureAI' defined in MaNGOS, especially in +src/game/CreatureAI.h+ is the topmost class for any AI a creature uses. +Any npc in the world has one AI, and this AI is a subclass of CreatureAI. + +The AI of any Creature can be accessed by the member function of the Creature class named +AI()+. + +TIP: https://github.com/mangos/mangos/blob/master/src/game/CreatureAI.h[The MaNGOS CreatureAI header] + +TIP: TODO Link here to auto-generated documentation + +When you look into the source, you will notice that nearly all of the functions are marked 'virtual' +This means, that when anywhere in the core one of these functions is called the implementation of this function in the actual class realising the AI will be called. + +This is the way how the script is "informed" about events that it might want to react to. + +When the core will call these functions is documented there. + +=== The ScriptedAI class + +The class 'ScriptedAI' is the base class in ScriptDev2 to be used to implement scripts. +It implements a few of the functions of CreatureAI with default behaviour you might expect from a creature. + +What are the actual default implementations of ScriptedAI can be seen in +include/sc_creature.cpp+: + +TIP: https://github.com/scriptdev2/scriptdev2/blob/master/include/sc_creature.cpp[Basic ScriptDev2 class for creature scripts] + +When we implement a boss script, we usally overwrite a few functions of ScriptedAI (and hence overwrite the functions of CreatureAI). + +=== Our example class 'boss_festergutAI' + +As you should remember from Day 7 that 'boss_festergutAI' is a subclass of 'ScriptedAI', which is a subclass of 'CreatureAI'. + +Currently, this class does not do very much, and hence also the instances of the class assigned to a spawned creature is also rather boring. + +== End of first part + +This already brings us to the end of the small introduction of the CreatureAI functions. +This got way shorter than intended, and must be improved. + +The main problem here is how to bring a relatively big class with a fair amount of documentation into a usable format for this guide. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Do my job :) +================================================================== +Do look into the CreatureAI class, and think if there might be ways to present it in a guide environment! +================================================================== + +== Second Part: + +As just noted, the script we added to boss Festergut with the class 'boss_festergutAI' is really really boring, so now we start to change it! + +In this part we will cover a few of the virtual functions we have available through 'CreatureAI' to do some text output. + +=== Text Output in ScriptDev2 + +Luckily most of the texts in ICC are already prepared for ScriptDev2, so we can use them very easy. +They might not be all correct, and it will become required to change some of them to make them better. +Currently they are taken from http://www.wowwiki.com[wowwiki], which is a good source but not always perfect. + + +==== The signature of a function + +Any function defined in C++ has a so called signature. +This is the combination of: + +return-type:: The type of the values returned by the function +function-name:: The name of the function (in case of C++ case sensetive) +paramter-list:: The parameter types the function takes + +=== DoScriptText + +Our main method to output text is +DoScriptText+ which is defined in +ScriptMgr.cpp+, its signature looks like this: + +-------------------------------- +void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget /*=NULL*/) +-------------------------------- + +Where the parameters have this meaning: + +*iTextEntry*(an int32 number):: Entry of the text, stored in SD2-database +*pSource*(a WorldObject, often a Creature):: Who displays the text +*pTarget*(a Unit, that is player or creature):: To whom the text will be directed, 'not' required + +TIP: A detailed description of how SD2 stores the texts in the database can be found in http://www.scriptdev2.com/showthread.php?t=5536[Guide for SD2-SQL] + +=== Doing Text on Aggro + +Most bosses have a text when they start attacking, this we call 'Aggro' for which a function in ScriptedAI is defined, with the signature + +-------------------------------- +void Aggro(Unit* pWho) +-------------------------------- +pWho:: is the Unit (Player or Creature) whom we aggro. + +This we will now overwrite, to display the text "Fun time!" by Festergut when Festergut aggroes. + +This text is already in the SD2 database, and the number is assigned the constant +SAY_AGGRO+. + +The required change looks like this: + +-------------------------------- +From f5f3a22fec940bdf0b4a20fc6f8c09859af97609 Mon Sep 17 00:00:00 2001 +From: Schmoozerd +Date: Sat, 15 Oct 2011 01:31:06 +0200 +Subject: [PATCH] ICC, Festergut - Add Aggro text + +--- + .../icecrown_citadel/boss_festergut.cpp | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +index acd358d..940b7f7 100644 +--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp ++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +@@ -48,6 +48,11 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI + void Reset() + { + } ++ ++ void Aggro(Unit* pWho) <1> ++ { ++ DoScriptText(SAY_AGGRO, m_creature); ++ } + }; + + CreatureAI* GetAI_boss_festergut(Creature* pCreature) +-- +1.7.6.msysgit.0 +-------------------------------- +Where + +<1> The actual changes to the code + +Remark that the variable +m_creature+ links to Festergut. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Where is it from +================================================================== +Where is the variable m_creature defined? +================================================================== + +=== Doing Text when killing a player + +This is very important text, because a both where this doesn't happen should not be called boss :) +Only killed players are good players! + +Looking again into CreatureAI you can find: + +-------------------------------- + /** + * Called when the creature kills a unit + * @param pVictim Victim that got killed + */ + virtual void KilledUnit(Unit* pVictim) {} +-------------------------------- + +As Player is a subclass of Unit, a player is also a unit, so this function can be expected to be called when the creature kills a player. +This is infact true, so we will use this function to display the text we want to display when killing enemies. + +From http://www.wowwiki.com/Festergut[wowwiki] we take the texts "Daddy, I did it!" and "Dead, dead, dead!" which should be displayed when killing. +There are already two constants assinged: +SAY_SLAY_1+ and +SAY_SLAY_2+. + +The required code to overwrite the function "void KilledUnit(Unit* pVictim)" is: + +-------------------------------- + void KilledUnit(Unit* pVictim) + { + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + } +-------------------------------- + +The full changeset can be seen on https://github.com/scriptdev2/scriptdev2/commit/7a35df04b072ebbeb038235e0b6d6b68a91ab81b[Github] or on https://github.com/scriptdev2/scriptdev2/commit/7a35df04b072ebbeb038235e0b6d6b68a91ab81b.patch[Github as format-patch] + +In case you have never seen this construction before: + +With +expression ? A : B+ you tell the code to set at this place IF expression is true THEN A ELSE B, which is handy to write compact code. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 3* - More texts +================================================================== +Find a function that could be used when a creature just died, and use it to display the text of constant +SAY_DEATH+ +================================================================== + +== End of second part + +What you should have seen today: + +* Where the functions you can use in ScriptDev2 boss scripts come from +* How to use them to display some texts + +What comes next: + +* The UpdateAI function, and timers +* Some more constructs to make a boss deadly + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 4* - Prepare yourself +================================================================== +Figure out how UpdateAI is called, and think about how this could be used. +================================================================== + +NOTE: This is no special exercise, because I really want to encourage you guys to take matters into your own hand, and do some own stuff! + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 5* - Do some own stuff +================================================================== +* Pick another boss, create a basic script (look into Day 7) +* Let this other boss display some basic texts like done today +* Share the code you did with us all! ++ +Best use format-patch styled output on http://paste2.org/new-paste and post your scripts in the forum. Take a look into the first week if you feel unsecure with creating patches and commits! +================================================================== diff --git a/icc_project/documentation/day-9.txt b/icc_project/documentation/day-9.txt new file mode 100644 index 000000000..abde4fce1 --- /dev/null +++ b/icc_project/documentation/day-9.txt @@ -0,0 +1,332 @@ +In Day 8 you should have seen: + +* Which classes you need to specialise in order to create boss scripts +* A bunch of functions that are useful for this + +This day is now about + +* Some thoughts about spells (as this is the thing most bosses do: Cast spells) +* Implementing casting spells + +== First Part + +For a clean scripting attempt it is expected to handle nearly everything with spells. So this part is now about the spell system. + +Any spell is cast by some caster onto some victim. And a spell will hit some targets. + +For some direct spells like ie Fireball the target will be the victim, but ie for AoE spells like ArcaneExplosion the victim will be the caster (self-cast spell), and the targets will be enemies around. + +=== The spell system + +Spells are provided in dbc form which can be extracted from the wow-client. Actually if you installed a local test server already, you will have extracted these dbc files. + +The structure (as far as known) for the spell.dbc can be seen in MaNGOS::DBCStructure.h - +struct SpellEntry+. However this is rather unpleasant to read and hence I 'strongly' suggest to use a tool to help understanding these entries. + +TIP: https://github.com/LordJZ/spellwork_cs[SpellWork] This is a nice tool to view the spell dbc, binary files can be downloaded from the SpellWork/bin/Release directory over github + +Basic structure of a spell: + +* Id and name - this identifies a spell +* Some internal information +* Spell Range +* Difficulty information (if exists) - If a spell has difficulty information, you only need to cast the base spell, the proper one for current difficulty will be selected by MaNGOS +* Information about Cast-Time, Duration of auras and similar + +* Information what the spell actually does: ++ +A spell has up to three effects (like summon or dealing damage). ++ +Each effect consists of: ++ + - The effect type (what the effect will do) + - The target types (how the targeting of the spell will work - AoE, Self, enemy) + - Some additional information about this effect (like how many damage, what npc will be summoned and so on) + +=== The spell system in MaNGOS + +Some parts of how spells should be handled are unknown, which means we can only interpret the values from spell.dbc by what should happen (and this usually is how the handling is implemented within MaNGOS) + +It is not in the scope of this guide to give some detailed explanation of everything about how spells are handled. For this you must seriously study the MaNGOS code. + +TIP: TODO Link here to the wiki page that should exist about mangos spell system. + +Effects and their implementation can be seen in MaNGOS:SpellEffects.cpp. Often the name of the effect gives some good clue what they will do + +Targeting can be seen in MaNGOS::Spell.cpp. Most important targets are: + +* TARGET_SELF - the effect will target the caster +* TARGET_*AREA* - the effect will work as AoE spell, in case of SpellRange == 0, the spell must be self cast +* TARGET_CHAIN_DAMAGE - the effect will target the victim +* TARGET_SCRIPT* - the target is fixed by the table `spell_script_target` + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 1* - Check a few spells +==================================================================================================================================== +Download SpellWork and check a few spells: Maybe IDs 9488 or 59245. +==================================================================================================================================== + +=== Which spells should a boss cast? + +Well, by now you should have seen a few spells and be able to have a rough idea what they are doing. But of course the most important question still is: What spells should a boss use? (And when) + +To get information what spells a boss should use, you can check: + +* Database sites (like wowhead) - NPCs usually have there a list of abilities, however this can be incomplete or even wrong +* Transcriptor/ Combat logs (there are sites where such are available) +* The DBM Addon +* Watching videos +* Wowwiki and similar sites + +There are usually two answers of *when* a spell is cast: + +. On a timer: This means, some time after engaging combat, and then repeating after some time. +. On some event: Like 50% health, or when an add dies + +To figure this you must use resources like videos, experience or a bunch of logs (and of course good guessing also helps) + +== End of first part + +In this part you should have seen how a spell looks like, and how to obtain information about its use. + +== Second Part: + +This part now will look about how spell casting is to be implemented in MaNGOS. + +The main function that will be used for spell casting is: +-------------------------------- +DoCastSpellIfCan(Unit* pVictim, uint32 uiSpellId); which returns a value of type CastResult +-------------------------------- + +=== The virtual function UpdateAI(const uint32 uiDiff) + +MaNGOS calls for every AI the function +UpdateAI(const uint32 uiDiff)+ about every 100ms. The actual time since last call is stored in uiDiff. + +This gives two possibilites: + +* Handle things that should be handled always +* Countdown a timer + +==== How does a timer work, if we know the time-diff since we last called a function? + +A timer is a variable of type uin32 (unsingned integer), which stores the time until the timer should expire next (in millieseconds) + +So, a minimal timer script would look like: +-------------------------------- +struct MANGOS_DLL_DECL boss_dummyAI : public ScriptedAI +{ + boss_dummyAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiTimer; <1> + + void Reset() <2> + { + m_uiTimer = 17000; <3> + } + + void UpdateAI(const uint32 uiDiff) <4> + { + if (m_uiTimer < uiDiff) <6> + { + DoScriptText(-1000001, m_creature); <7> + m_uiTimer = 30000; <8> + } + else + m_uiTimer -= uiDiff; <5> + } +}; +-------------------------------- + +Note that this misses all stuff like registering the script, but you should be able to test it, if you move the content to some other empty script (maybe festergut) + +The meaning of the new lines: + +<1> In this line the member variable +m_uiTimer+ of the struct boss_dummyAI is defined. +<2> This is the virtual Reset function that every script implements. +<3> And we reset here the timer to the initially value. +<4> Here we overwrite the UpdateAI function, that will be called every +uiDiff+ millieseconds. +<5> If the timer is not expired ("else") we decrement it. +<6> We check if the timer is expired (which means it is time to do something for which we need the timer) +<7> Some Text will be displayed +<8> The timer will be set to a new value + +Currently this function only contains the timer handling. + +===== How exactly does a timer work + +It is probably a good idea to clarify this with pen and paper: Think what will happen in the code (assume the UpdateAI is called every 100ms) + +When the script is initialized the timer will be 17000. On first 'tick' of UpdateAI evaluating the code looks like: +---------------------------------------------------------------- + void UpdateAI(const uint32 uiDiff==100) + { + if (m_uiTimer==17000 < 100) // evaluates to false + { + DoScriptText(-1000001, m_creature); + m_uiTimer = 30000; + } + else + m_uiTimer==17000 -= 100; + } +---------------------------------------------------------------- +When this code is finished, m_uiTimer will be decremented by 100, and has then the value of 16900. + +The next tick would look like: +---------------------------------------------------------------- + void UpdateAI(const uint32 uiDiff==100) + { + if (m_uiTimer==16900 < 100) // evaluates to false + { + DoScriptText(-1000001, m_creature); + m_uiTimer = 30000; + } + else + m_uiTimer==16900 -= 100; + } +---------------------------------------------------------------- +When this code is finished, m_uiTimer will be decremented by 100, and has then the value of 16800. + +After a bunch of more 'ticks' the code will evaluate to (Exercise: How many ticks? - How long does it take?) +---------------------------------------------------------------- + void UpdateAI(const uint32 uiDiff==100) + { + if (m_uiTimer==0 < 100) // evaluates to true + { + DoScriptText(-1000001, m_creature); + m_uiTimer = 30000; + } + else + m_uiTimer==0 -= 100; + } +---------------------------------------------------------------- +And the timer will be expired, and the actions that should happen when the timer is expired will be triggered. + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 2* - Understand the timer +================================================================== +When will the timer first expire? + +When will the timer the second time expire? +================================================================== +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 3* - Understand the timer(2) +================================================================== +Change the code so that the timer will initially expire after 10seconds, and from then expire every 30-40 seconds. (Hint: +urand(A, B)+ gives a random number between A and B) +================================================================== + +==== What other stuff fits well into the UpdateAI function? + +In normal cases we want to script combat behaviour. And most important for combating is of course threat management (whom the boss should attack). + +This is handled by MaNGOS with the function +SelectHostileTarget+. + +Also we normally want a boss to do melee attack. + +This is handled by MaNGOS with the function +DoMeleeAttackIfReady+. + +So the structure for a normal +UpdateAI+ should look like this (changes might be reasonable, but only very rarely) +---------------------------------------------------------------- + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; <1> + + // Some combat Timers + + DoMeleeAttackIfReady(); + } +---------------------------------------------------------------- +<1> As of this return anything after will only be executed when we are in proper combat. + +=== Real example: Let Festergut cast something + +On http://old.wowhead.com/npc=36626#abilities[wowhead-Festergut] I found a spell ID for the Berserk spell as well as the information that the berserk should happen after 5 minutes (initially) + +---------------------------------------------------------------- +diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +index b059c1f..30ec25e 100644 +--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp ++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +@@ -36,6 +36,8 @@ enum + SAY_BERSERK = -1631089, + SAY_DEATH = -1631090, + SAY_FESTERGUT_DEATH = -1631091, ++ ++ SPELL_BERSERK = 47008, <1> + }; + + struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI +@@ -45,8 +47,11 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI + Reset(); + } + ++ uint32 m_uiBerserkTimer; <2> ++ + void Reset() + { ++ m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS; + } + + void Aggro(Unit* pWho) +@@ -58,6 +63,21 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI + { + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + } ++ ++ void UpdateAI(const uint32 uiDiff) ++ { ++ if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) ++ return; ++ ++ if (m_uiBerserkTimer < uiDiff) <3> ++ { ++ DoCastSpellIfCan(m_creature, SPELL_BERSERK); ++ DoScriptText(SAY_BERSERK, m_creature); ++ m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS; ++ } ++ else ++ m_uiBerserkTimer -= uiDiff; ++ } + }; + + CreatureAI* GetAI_boss_festergut(Creature* pCreature) +---------------------------------------------------------------- + +What is done here: + +<1> The Berserk spell ID is assigned to an enum (to prevent so called magic numbers) +<2> As we can expect that there will be additional timers for this boss, we must find unique names for every timer, usually this works well with the spellname. ++ +Also note the http://www.scriptdev2.com/showthread.php?t=4098[ScriptDev2 Coding Standards] + +<3> The actual implementation of the timer. From the infos there should be besides the casting of the berserk spell also a text displayed that Festergut enrages. + +This patch was commited with bd821056ec9f + +[NOTE] +[icon="./images/icons/example.png", caption="Exercise"] +.*Exercise 4* - Add some abilities to your own script +================================================================== +Write a script for an own boss and add some abilites, or add some abilites to Festergut here. + +Provide patches to the forum thread! + +Also note from which sources you got which info - good place for this would be the commit message +================================================================== + +== End of second part + +What you should have seen today: + +* How spells work +* How to cast spells on a timer + +What comes next: + +* Using events to trigger some stuff +* Using phases diff --git a/icc_project/documentation/html/day-1.html b/icc_project/documentation/html/day-1.html new file mode 100644 index 000000000..95b9ac3b8 --- /dev/null +++ b/icc_project/documentation/html/day-1.html @@ -0,0 +1,994 @@ + + + + + + + + + + + +
+
+

1. First Part

+
+

This part should introduce you to adding a new branch with Git, switching between the branches, and how to do the most basic work with Git.

+

The changes for the ICC learning project are currently located at SD2 repository, within the branch "icc_project"

+

This part assumes:

+
    +
  • +

    +You have already cloned SD2, if not look into http://www.scriptdev2.com/showthread.php?t=4 +

    +
  • +
  • +

    +You are on a clean branch, and have not yet used the name "icc_project" for a branch on your system. + See the next section how to check, and restore a clean environment +

    +
  • +
+

I will always use the Git bash to work with Git. +Hence I strongly suggest for you to use it as well. +But nearly all stuff must work with GUI tools somehow +(Note for *nix User: "Open Git bash here" can be translated to open a bash in the directory)

+

So, to do anything with Git, we will open a Git bash in the ScriptDev2 directory in your MaNGOS source folder - in src\bindings\.

+

To do so, open your explorer, right click the "ScriptDev2" directory and select "Git bash here" from the context menu.

+

This will open a nice black and white window, where you can type commands in a very old fashioned way :)

+
+

1.1. Checking your status

+

The first and most important command is

+
+
+
git status
+
+

This will show the current state of your work tree related to the index.

+

What does this mean: +When you look at your ScriptDev2 directory, there are two things you must keep in mind:

+
    +
  • +

    +The directory contains files - these files are referred to as the work tree, and are just normal files. +

    +
  • +
  • +

    +Git has an internal representation of the history related to your project, this history is stored in the index. +

    +
  • +
+

So git status now shows you in which state every file in your work tree is in relation to what state the file should be compared to your current history index

+

The default output should be:

+
+
+
# On branch master
+nothing to commit (working directory clean)
+
+

This shows you that you are on your "master" branch (this is default), and that you have no change related to your history (working directory clean)

+
+ + + +
+Exercise + +
Exercise 1 - Check the status
+

Add or change a file, and compare the output of git status

+
+
+

If you have a not clean working tree, you must clean it.

+
+
+

1.2. Resetting your working tree to the index

+
+ + + +
+Warning + +

This will delete all changes!

+
+
+
git reset --hard
+
+
+
+

Note: This will only affect files which are known to the index, so a new created file won’t get deleted.

+

Remark: This will only give you what I expect, if you didn’t too many experiments yourself.

+
+
+

1.3. Updating your remote information for the SD2 repo.

+

The SD2 repo (assuming it was cloned from initially) should be named "origin" +If you have done nothing special, it will be and you don’t have to worry.

+

To update the information for the remote origin repository, simply do:

+
+
+
git fetch
+
+
+
+

1.4. Cloning the remote branch containing the icc learning project.

+

Git is really great when it comes to branching. +This means, it is easy to have different branches of history-indexes and to switch the working-tree files between them.

+

The reason why branches are so cool is, that one branch does not change the history of another branch. +So it is very easy to have different things to work on.

+

The process to switch the working tree from one history branch to another is called "checkout", and hence the command that is to be used is

+
+
+
git checkout <newBranch>
+
+

where <newBranch> is the name of the branch to which you will switch your working tree

+

However, before you are able to checkout to a branch, you must create it.

+

To make this easier, there is the "-b" option for the checkout command:

+

All in all you should type:

+
+
+
git checkout -b icc_project -t remotes/origin/icc_project
+
+

This will do the following:

+
+ + + + + + + + + + + + +
+-b +
+
+

+create a new branch named "icc_project" +

+
+-t +
+
+

+use the point from which you branch as "tracking" branch +

+
+remotes/origin/icc_project +
+
+

+is the branch icc_project in the repository origin which is a remote repository +

+
+
+
+

1.5. Switching between branches:

+

As already mentioned, you can easily switch between branches with

+
+
+
git checkout <branchName>
+
+
+ + + +
+Exercise + +
Exercise 2 - Test switching
+

Observe changes of files in the directory (especially the sub directory icc_project) while switching with

+
+
+
git checkout master
+git checkout icc_project
+
+
+
+
+
+
+
+

2. End of First Part

+
+
+

2.1. What this part was about:

+
    +
  • +

    +Checking the status of working tree, command > git status +

    +
  • +
  • +

    +Checking out a remote branch into a local branch +

    +
  • +
  • +

    +Switching branches, command > git checkout +

    +
  • +
+
+
+

2.2. Most important concepts:

+
    +
  • +

    +index and working tree (What were they?) +

    +
  • +
  • +

    +branches in Git (What are they used for?) +

    +
  • +
+
+
+

2.3. Additional resources:

+
+ + + +
+Tip +Tech talk about what Git is not This is a nice vid, it should clarify why we use git, and explain some more concepts of Git :)
+
+
+
+

2.4. What comes next:

+
    +
  • +

    +How to do local commits +

    +
  • +
  • +

    +How to read history +

    +
  • +
+
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-2.html b/icc_project/documentation/html/day-2.html new file mode 100644 index 000000000..5d59fad6c --- /dev/null +++ b/icc_project/documentation/html/day-2.html @@ -0,0 +1,1347 @@ + + + + + + + + + + + +
+

From Day 1 you should have learnt these things:

+
    +
  • +

    +Meaning of working tree and index: The working tree are the actual files on your file system, the index is the history information +

    +
  • +
  • +

    +The concept of branches: A branch is a branch of the history index +

    +
  • +
+

Also you should be able to switch between branches with git checkout and to check the state of your working tree related to the index with git status

+
+

1. First Part:

+
+

This part now should introduce you to know how to actual see the history.

+
+

1.1. Excursion: The pager less

+

This is especially important for Windows user!

+

When using Git via Git bash, the default tool set is the archaic tool set every *nix fan will have learnt by heart, but they can be extremely weird from Windows view.

+

In old times, when there was nothing except console and there were no possibilities to scroll in the text, console environments had the so called pager programs, which were used to be able to scroll in output.

+

Assume you would have an enormous amount of text, so if you would push it directly onto the console, you would not be able to read anything, because it would be way too fast.

+

So, the idea is to give the output to a program — the pager — which allows you to scroll up and down in the output.

+

Default pager on *nix is less - which Git bash uses by default to show the history (or many other things). +You can scroll in there with the arrow keys or a whole page by the space bar. +And most important: You quit less by pressing "q"

+
+ + + +
+Tip + + +

(Disclaimer: I don’t take responsibility for brain damage caused by any provided link here!)

+

Anyhow: A better "guide" for less to link would be appreciated, but trying to search for "how to less" kind of doesn’t work.

+
+
+
+ + + +
+Exercise + +
Exercise 1 - Try to find a better less how-to and take a look
+

Hint: add "unix" to your search attempt :)

+
+
+
+
+

1.2. Viewing the history of a branch in Git

+

OK, now we can look into the history of the current branch, this is done simply by

+
+
+
git log
+
+

Just do so now :)

+

Remember: To close the output, type "q"

+

The most recent commits (see 3) might look like this:

+
+
+
commit 1cebd00445e7bd92927f305e40225de1049d450c          1
+Author: Schmoozerd <schmoozerd@scriptdev2.com>           2
+Date:   Tue Oct 4 02:02:44 2011 +0200                    3
+
+    Add some files and documentation for the first part  4
+
+commit e0601735424f712d685330b421898db16a366b17          1
+Author: Schmoozerd <schmoozerd@scriptdev2.com>           2
+Date:   Tue Oct 4 01:14:46 2011 +0200                    3
+
+    Initial Commit for the ICC Learning project          4
+
+

What does this show:

+
+ + + + +
1 +This is the hash of the commit, which should globally uniquely identify any commit. + Usually it is enough to only take the first ~6 digits. + This is more or less the "name" of the commit +
2 +Yes you guessed rightly, this is the author of the commit +
3 +When the commit was authored +
4 +This is the message the author thought might be helpful to describe the commit +
+

So - what is git log useful for?

+

With git log you are able to see the history, who did which changes, and in which order. +Also git log has a big amount of options, which help you to actually search for a specific commit (ie by author)

+
+ + + +
+Exercise + +
Exercise 2 - Search the history by author
+

If you have already submitted a patch to SD2, that got accepted it is likely that you are "author" of a commit. Check with

+
+
+
git log --author="yourNickName"
+
+

If you are not, pick anyone whom you think has contributed and look what git log --author tells you ;)

+
+
+
+
+

1.3. The structure of objects in the git history index

+

When you do a change, and make this change known to the history, then you have a "commit"

+

Any commit has:

+
    +
  • +

    +An author +

    +
  • +
  • +

    +A commit hash (the strange numbers already seen in git log) +

    +
  • +
  • +

    +The set of changes it describes (if you didn’t change anything, there is no commit!) +

    +
  • +
  • +

    +One previous commit on which the commit is done. +

    +
  • +
+

As of the last statement, you have a chain of commits. And this is your history!

+
+
+

1.4. View a commit

+

You can view a commit with

+
+
+
git show <someIdentifier>
+
+
+ + + +
+Exercise + +
Exercise 3 - View a commit by hash
+
+
+
git show 111cea5073191b
+
+

What commit does this refer to: What is the commit message? Who is the author? When was it committed?

+
+
+
+
+

1.5. How to access commits

+

Things are only useful if you can work with them, and to do so you need powerful ways to access them. +Git provides reasonable ways to "get to" a specific commit.

+

You have already seen the commit hash, this identifies a commit and hence is a great accessor (except that no one can remember endless amounts of hash-ids)

+

When you are on a local branch, "HEAD" always points to the top-most commit of your local branch.

+

A branchname always points to the HEAD commit of the branch with the branchname

+

"<Commit>~N" refers to "N commits before the commit <Commit>

+
+ + + +
+Exercise + +
Exercise 4 - Look into a few commits
+

Try these examples, maybe a few more.

+
+
+
git show HEAD~1
+git show master
+git show master~304
+
+

Remember: To close the pager, type "q"

+
+
+
+
+

1.6. Advanced looking into the history:

+

Now that you know how commits are accessed, you are able to invoke more features from git log.

+ +
+
+
+
+

2. End of First Part

+
+
+

2.1. What this part was about:

+
    +
  • +

    +Knowing what a commit means. +

    +
  • +
  • +

    +Showing a commit ( git show ) +

    +
  • +
  • +

    +Knowing how to access various commits +

    +
  • +
+
+
+
+
+

3. Second Part

+
+

From the first part of today you should know what commits are, and how to find them. +Also you should feel safe about concepts as branches, working tree and index

+

Now it is time to start doing some own commits!

+
+

3.1. Why commit?

+
    +
  • +

    +When you commit, you get the full power of Git to track your history. +

    +
  • +
  • +

    +Also commits are easier to merge and handle than changes that are just there. +

    +
  • +
  • +

    +Also with committing, you are able to provide extra information in the commit message to tell "what you have done why". +

    +
  • +
+

So, the golden rule of thumb is:

+
+ + + +
+Important + +

Commit often, commit early!

+

And of course: Publish your commits! (More about this likely tomorrow)

+
+
+
+
+

3.2. How to commit:

+

The base command to commit changes is

+
+
+
git commit
+
+

however this command alone won’t make you very happy.

+

You must tell Git which changes you want to commit. +A very reasonable way is often, to commit all changes, like with

+
+
+
git commit -a -m"My first commit"
+
+

Where

+
+ + + + + + + + +
+-a +
+
+

+commit all changes in all tracked files +

+
+-m <String> +
+
+

+take <String> as commit message, note that I used ".." to mark the whole text as message +

+
+

Example: This commit was added with

+
+
+
> git commit -a -m"Day 2, Part 2 Howto git commit"
+
+
+

3.2.1. Track new files

+

As this would only commit changes in already tracked files, you might wonder how to commit (changes to) new files.

+

You can add a new file with

+
+
+
git add path/to/fileName
+
+

Then the file named fileName located in path/to/ will be committed with your next git commit -a command

+

Remark for later: If you plan a couple of commits, it might be a good idea to fork a new branch and commit them there

+
+
+

3.2.2. Workflow in Git

+

By using these commands, the usual work flow in Git represents itself like this:

+

You edit a few files

+
+
+
git commit -a -m "Some cool edits"
+
+

You edit more

+
+
+
git commit -a -m"More cool edits"
+
+

You edit even more

+
+
+
git commit -a -m"The coolest edits ever"
+
+

Then you check your work with

+
+
+
git log
+
+

The topmost three commits should then be

+
    +
  1. +

    +The coolest edits ever +

    +
  2. +
  3. +

    +More cool edits +

    +
  4. +
  5. +

    +Some cool edits +

    +
  6. +
+
+ + + +
+Exercise + +
Exercise 5 - Do some test commits
+

Suggested files to change might be found in icc_project\research

+
+
+
+ + + +
+Exercise + +
Exercise 6
+

Look at your work with git log

+
+
+
+ + + +
+Warning +Special Exercises are not important to do right now, but if you feel confident or want to test some things feel free to explore a bit
+
+
+ + + +
+Exercise + +
Special Exercise 7 - Commit changes with a new file
+

Add a new file to git and commit it (lookup git add)

+
+
+
+ + + +
+Exercise + +
Special Exercise 8 - Commit in a branch
+

To start invoke git checkout -b testing +Remember: the -b will create a new branch, and git checkout switches to a branch

+
+
+
+
+ +
+ + + +
+Tip +http://book.git-scm.com/3_normal_workflow.html (unfortunately it seems the flash vids showing this are gone)
+
+
+ + + +
+Tip +Tech Talk of what Git is about I think I don’t like the style of the speaker too much - but maybe you do :)
+
+
+
+
+

3.3. Undo Changes

+

This section will show up every now and then, because there are different ways to undo things, depending on what and how you want to undo.

+

It is not necessary, but I suggest to remove the testing changes from Ex. 5-7 from your icc_project branch.

+

Do so by switching into this branch with

+
+
+
git checkout icc_project
+
+

and reset to origin state with

+
+
+
git reset --hard origin/icc_project
+
+
+
+

3.4. Excursion: The editor vi

+

You remember that Git uses by default the archaic pager less in some cases?

+

They are even more hostile, because in some cases by default (when there is need to edit something) Git will start the well loved vi editor.

+
+

3.4.1. Change default editor in Git, aka The good news

+

You can change the default editor to some editor that at least is usable for people who didn’t suffer years of brain damage caused by vi and think this is a good editor :)

+

To change the default editor, look at this line carefully:

+
+
+
git config --global core.editor "'C:/Program Files/Notepad++/notepad++.exe' -multiInst -notabbar -nosession -noPlugin"
+
+

This is however only an example how it worked on my system.

+
+
+

3.4.2. Reasons why vi is still worth knowing about:

+
    +
  • +

    +Every *nix system has vi, and it works nicely over ssh — so it might be required some day to know at least the very basics +

    +
  • +
  • +

    +Actually vi performs quite nicely related to big files +

    +
  • +
  • +

    +Well, vi is very powerful +

    +
  • +
+

Besides I like it, refer to brain damage to understand why ;)

+

As vi originates in the golden ages when mice where only found under the desk of full-time hackers, +and not on the desk related to GUI editors, there was the very pressing question how to know if you want to invoke a command (ie "save" ) or when to write a word (ie "save" ). +Many editors solved this by using CTRL and similar for command mode, and normal typing else wise.

+

However vi went another way (because of more powerful features and because ctrl and similar caused trouble on telnet sessions).

+
+
+

3.4.3. How vi works

+

vi has a few different modes, which can be switched and entered with a few buttons:

+
    +
  • +

    +The INSERT mode: When this mode is active, there is a "-- INSERT --" marked on the bottom of your console, and in this mode vi behaves like normal editors. +If you type things, they will show on the screen - so you will do what you expect from an editor: you will edit a file +

    +
  • +
  • +

    +The command mode: In this mode, pressing keys are considered as commands, and do confusing things! +

    +
  • +
+
+
How to switch between the modes:
+

When you start vi you are in the command mode. Press "i" to start the insert mode. +When you are in the INSERT mode, press "Esc" to leave the INSERT mode and return to command mode.

+
+
+
Closing vi
+

Actually most people green to vi wonder about one thing most:

+

How to close the damn program?

+

The answer is relatively easy:

+

You must be in the command mode, and then press ":". This will activate a special mode (for interested: ex-mode) in which you can type in commands. +the most useful commands are: (you don’t need to press the ":" again)

+
+ + + + + + + + + + + + +
+:wq +
+
+

+Write and Quit, which it does, and you will have manged to quit vi ;) +

+
+:q +
+
+

+Only quit, to do so there must be no change +

+
+:q! +
+
+

+Quit and discard changes you made +

+
+
+ + + +
+Tip +There are tons of docs for vi out there, maybe http://www.gentoo.org/doc/en/vi-guide.xml is a good one.
+
+
+ + + +
+Exercise + +
Special Exercise 9
+

Do a few changes and use > git commit -a and experiment :)

+
+
+
+
+
+
+
+
+

4. End of Second Part

+
+
+

4.1. What this part was about:

+
    +
  • +

    +Doing own commits with git commit +

    +
  • +
  • +

    +Really encouraging to do own simple tests now! +

    +
  • +
+
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-3.html b/icc_project/documentation/html/day-3.html new file mode 100644 index 000000000..b4f2b3b3b --- /dev/null +++ b/icc_project/documentation/html/day-3.html @@ -0,0 +1,1042 @@ + + + + + + + + + + + +
+

In Day 2 we showed what commits are, how to navigate in them, and how to create them.

+

This part is now about the content of a commit. +Remember the (meta) structure of a commit:

+
    +
  • +

    +Commit hash +

    +
  • +
  • +

    +Commit date +

    +
  • +
  • +

    +Author information +

    +
  • +
  • +

    +Commit message +

    +
  • +
  • +

    +Content changes +

    +
  • +
+

Today we will talk about the Content changes in each commit.

+
+

1. First Part:

+
+
+

1.1. The diff format

+

One of the natural ways in programming to display changes between two files (or two states), is a so called "diff".

+

Usually this might look like this: (pointless example to emphasise how to read it)

+
+
+
diff --git a/README b/README        1
+index bba7c29..79dc7e6 100644
+--- a/README
++++ b/README
+@@ -22,7 +23,7 @@ that comes with MaNGOS ( http://www.getmangos.com ), written in C++ and is        2
+ compatible with Windows and Linux. SQL needed for database support both                            3
+ MySQL and PostgreSQL.                                                                              3
+
+-This script library provides unique scripts for NPCs, gameobjects, events              4
++This script library provides unique and great scripts for NPCs, gameobjects, events    5
+ and other that need unique implementation.                                                         3
+
+ Once ScriptDev2 is compiled it is automatically run by MaNGOS on server                            3
+
+

You can read such a (unified) patch format like this:

+
+ + + + + +
1 +diff --git a/path/to/file b/path/to/file + This line tells you that you have a diff created with git, and it has the changes in path/to/file (two versions, a and b) +
2 +@@ -A,B +C,D <someString> + This line tells you where the hunk you have changes with is located, and how big it is. +
    +
  • +

    +A is the line where the content did begin in the first version +

    +
  • +
  • +

    +B is the length of the hunk before the change in the first version +

    +
  • +
  • +

    +C is the line where the content begins in the second version +

    +
  • +
  • +

    +D is the length of the hunk in the second version +

    +
  • +
+
3 +A content (unchanged) line always starts with a blanc +
4 +A line starting with a minus sign indicates that this line is removed +
5 +A line starting with a plus sign indicates that this line is added +
+

So, now to our example diff:

+

the first line tells us, that we look at a change for the file README (located in main ScriptDev2 directory)

+

Open it and look into line 22 (A).

+

line 22 currently is compatible with Windows and Linux. SQL needed for database support both

+

so we know that we are in the right place to apply our changes.

+

A few lines later, we see the line This script library provides unique scripts for NPCs, gameobjects, events +which out diff replaces with the line This script library provides unique and great scripts for NPCs, gameobjects, events.

+

(Clearly: if you delete a line, and insert at the same place another line, you actually do replace this line)

+

Note that a diff can consist of changes for multiple files, and each file changes can consist of multiple hunks

+
+ + + +
+Tip +Further documentation including various similar diff formats are also mentioned there, perhaps just look into it when reading the second time
+
+
+
+

1.2. Creating a diff with Git

+
+
+
git diff
+
+

This is one of the most important commands in Git.

+

With git diff you see the change set as unified diff between the current working tree and the HEAD

+

For memory: HEAD is the topmost commit in the current branch

+
+ + + +
+Exercise + +
Exercise 1 - Use git diff
+

Edit a few files and see what happens with git diff

+
+
+
+ + + +
+Exercise + +
Exercise 2 - Compare to diff above
+

Edit the README in a way to get the same unified diff I posted above - did I cheat?

+
+
+
+ + + +
+Tip +Further documentation his will show additional more advanced uses of git diff, but you should be able to understand them!
+
+
+
+

1.3. Other important commands to see diffs

+

You already should know git show - this commands also shows the changes of the specified commit as unified diff (after some meta information of the commit)

+

However with this command, you can only see the changes of a commit, not between current working tree and index

+

Another tool I like very very much to see diffs of multiple commits is

+
+
+
git format-patch
+
+
    +
  • +

    +However this tool creates by default a bunch of diff-files, to prevent this you can use the --stdout option. +

    +
  • +
  • +

    +Also you should specify from which point on you want to see the commits. +

    +
  • +
  • +

    +Also you can specify to which point you want to see the commits. +

    +
  • +
+

I usually use it this way:

+
+
+
> git format-patch <startCommit>[..<endCommit>] --stdout
+
+

With the meaning:

+
+ + + + + + + + + + + + +
+<startCommit> +
+
+

+Commit, from which the changes will be shown (see day2 how a commit can be referenced) +

+
+..<endCommit> +
+
+

+Optional commit, to which the changes will be shown +

+
+--stdout +
+
+

+print the output to the console instead of creating files for each commit +

+
+
+ + + +
+Exercise + +
Exercise 3 - Basic example for git format-patch
+

Use format-patch to see the changes between master and icc_project, try

+
+
+
git format-patch master --stdout
+
+
+
+
+ + + +
+Exercise + +
Exercise 4 - git format-patch for different branches
+

Do Day 2 - Special Exercise 8 if you have not already done, and look at the format-patch output between the created testing branch and the icc_project branch

+
+
+
+
+

1.4. Cleanup what happened today

+

Assuming you are on the icc_project branch, and you have no "valuable" custom changes on there, use

+
+
+
git reset --hard origin/icc_project
+
+

to reset all changes of tracked files from your index and working tree.

+

Check if everything is nice with git status ;)

+
+
+
+
+

2. End of First Part

+
+

This Part should have shown how to use the commands

+
+
+
git diff
+git show
+git format-patch
+
+

to look into changes of commits, or between commits and the working-tree

+

Basic concepts:

+
    +
  • +

    +You should have a rough feeling of how to "read" unified patches. +

    +
  • +
+

What comes next:

+
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-4.html b/icc_project/documentation/html/day-4.html new file mode 100644 index 000000000..2000e674f --- /dev/null +++ b/icc_project/documentation/html/day-4.html @@ -0,0 +1,1217 @@ + + + + + + + + + + + +
+

From Day 3 you should have learnt these things:

+
    +
  • +

    +How to read unified diffs +

    +
  • +
  • +

    +How to use git diff, git show and git format-patch to create diff between different commits or the working tree +

    +
  • +
+

Today now is about how to

+
    +
  • +

    +Create patch files, that is files which contain the output from the above commands +

    +
  • +
  • +

    +How to apply them +

    +
  • +
+
+

1. First Part:

+
+

A very neat way to create the patch files within a bash (ie Git bash) is to use the output redirection

+
+

1.1. Excursion: Some notes about working with a console

+

Reasons to still use a console environment for some things

+
    +
  • +

    +You definitively will feel like a geek! +

    +

    (Do we actually need more reasons?)

    +
  • +
  • +

    +Using a console is for some things very fast (and very slow for others) +

    +
  • +
  • +

    +Reasonable to learn, as *nix systems won’t proper work without (Windows systems won’t work proper without using cmd now and then, only that the cmd sucks) +

    +
  • +
+

Most useful commands in a bash console

+

OK, to clarify: When you type commands into a console, there is actually a program that interprets these commands.

+

Some examples are the cmd (from (win)do(w)s), or bash which got popular on Linux

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ls +
+
+

+List the content of the current directory (on Windows this was called dir) +

+
+cd +
+
+

+Change your directory. If you invoke cd .. then you will change into the parent directory +

+
+cat +
+
+

+Can be used to get text from a file onto the console +

+
+cp A B +
+
+

+Copy a file from A to B +

+
+mv A B +
+
+

+Move a file from A to B (if A and B are in the same directory, than this renames) +

+
+rm A +
+
+

+Remove (this means delete) file A +

+
+mkdir +
+
+

+Create a directory +

+
+rmdir +
+
+

+Remove a directory +

+
+

Very useful things:

+
+
+Auto completion (Bash can do this) +
+
+

+If you want to type something, and press the tab key, the bash will try to auto complete a word for you. +

+

Example: Type (in the ScriptDev2-directory) into the bash: ls to and then press the tab key.

+
+
+Copy and Paste in the bash (For Windows users) +
+
+

+If you click on the top-left corner of your console window, you can select "Edit" and there "Mark" and "Paste". Also you can use the INSERT key to paste the content of your clipboard +

+

(Marking is finished with enter, the marked text will then be in your clipboard)

+
+
+Using previously typed commands +
+
+

+With the arrow keys (up, down) you can reuse previous commands easily. +

+
+
+
+
+

1.2. Excursion: Bash output/ input redirection

+

For most console based systems it is possible to use these types of output redirection

+
+ + + + + + + + + + + + +
+> +
+
+

+Forward the output into a file, the file will be created if it does not exist, and truncated before refilled if it exists +

+
+>> +
+
+

+Forward the output into a file, but append if the file already exists +

+
+| +
+
+

+(Called pipe) Forward the output from the program as input to the next program +:: A few more exists which I won’t cover! +

+
+

Remember the nice tools like git diff or git format-patch --stdout from Day 3?

+

They were working nice, but only displayed their stuff in the console.

+

The trick to get their output into files is to use output redirection.

+
+ + + +
+Exercise + +
Exercise 1 - Use output redirection to create patch files
+
    +
  • +

    +Do Exercise 1 from Day3, but redirect the output of git diff with git diff > temp_diff.patch +

    +
  • +
  • +

    +Do Exercise 3 from Day3, but redirect the output of git diff with git diff > temp_format.patch +

    +
  • +
+

And look at these created files with a patch tool (if you have one installed), an editor and cat. +(To use cat do: cat temp_diff.patch and cat temp_format.patch)

+

Congratulation, you have created your first patch files!

+
+
+
+ + + +
+Exercise + +
Exercise 2 - Use output redirection to create patch files
+

Do some more edits and test bash auto completion with git diff > te <press tab key> d <press tab key>

+
+
+

Sometimes you might not want to get all changes directly into a file, but would like to view the output of ie git format-patch --stdout slowly.

+

Remember the pager less from Day 2?

+
+ + + +
+Exercise + +
Exercise 3 - Fais la pipe (My French is bad, maybe it was Utilize)
+

Use git format-patch master --stdout | less

+
+
+
+
+
+
+

2. End of First Part

+
+
+ + + +
+Tip + +

If you still cannot get enough about using bash, look here

+

For more bash programming purposes look here

+

If anybody finds a neat beginners guide suitable for this topic, please inform!

+
+
+
+
+
+

3. Second Part:

+
+

Now we want to apply a few patch files.

+

You will need the patch files you created in Part 1 - Exercise 1!

+

Also you should copy the content of SD2-Commit 2302 +into a file in your ScriptDev2 directory, expected name sd2_2302.patch

+
+

3.1. Applying patches with git apply and git am

+

Both commands apply a patch from a filename with appropriate format if possible.

+
+
+git am +
+
+

+Git am applies a patch created with format-patch to the index +

+

As a formatted patch contains some meta information of the commit(s) from which it was created, it will directly commit the change sets from the commits, and thereby using the provided meta information in the patch file.

+

Hence a patch file for git am must contain this information in a defined way.

+
+
+git apply +
+
+

+Git apply applies a patch created with git show or git diff to the working tree +

+

These patches contain no additional meta information, and hence won’t be committed automatically.

+
+
+

To apply the following examples, be sure to be on clear icc_project, to do so use

+
+
+
git reset --hard origin/icc_project
+
+
+ + + +
+Exercise + +
Exercise 4 - Apply a patch with git apply
+

Apply the patch created in Exercise 1 from file temp_diff.patch

+
+
+
git apply temp_diff.patch
+
+

Check what this did! Use git status, git diff and git log to see what this did!

+

Reset your changes with git reset --hard

+
+
+
+ + + +
+Exercise + +
Exercise 5 - Apply a patch with git am
+

Apply the patch from file sd2_2302.patch

+
+
+
git am sd2_2302.patch
+
+

Check what this did!

+

Reset your changes with git reset --hard origin/icc_project

+
+
+
+ + + +
+Exercise + +
Exercise 6 - Why why why?
+

Why did I suggest to use different ways to git reset --hard in exercises 4 and 5?

+
+
+
+ + + +
+Exercise + +
Special Exercise 7 - Some first conflicts
+

Try to apply the changes in temp_format.patch with git am

+

This gives errors - Why?

+

To abort the attempt to apply this with git am, use

+
+
+
git am --abort
+
+
+
+
+ + + +
+Exercise + +
Special Exercise 8 - Apply to a conflict free point
+

Find a point in the history where the changes from temp_format.patch could be applied!

+

Checkout to this point, and apply there

+
+
+
git checkout -b apply-safe <ThisPoint>
+git am temp_format.patch
+
+

Now you have applied the patch file. Check what happened with the usual suspects :)

+
+
+
+ + + +
+Exercise + +
Special Exercise 9 - Merging conflicts
+

Checkout to your icc_project branch

+

Try to merge the apply-safe branch into your current branch, try git merge apply-safe

+

This will give the same conflicts as you had in Exercise 7, but now you have the possibility to use the powerful tools of git to merge. Actually for me merge went without problems!

+

However if you still get conflicts, abort the merge with git reset --hard

+
+
+

Now, there might have been many changes, and it is time to cleanup:

+
+
+
git checkout icc_project
+git reset --hard origin/icc_project 1
+git branch -D apply-safe    2
+rm sd2_2302.patch    3
+rm temp_format.patch
+rm temp_diff.patch
+
+
+ + + +
1 +Do you already know why this time the reset --hard version with origin/icc_project was used? +
2 +git branch -D will delete a branch +
3 +Remove a few untracked files - check for more with git status +
+
+
+
+
+

4. End of Second Part

+
+

Today we have seen

+
    +
  • +

    +how to use a console environment +

    +
  • +
  • +

    +how to use dark console powers to create patch files +

    +
  • +
  • +

    +how to apply patch files +

    +
  • +
  • +

    +how using Git the right way conflict solving can become very easy! (Special exercises) +

    +
  • +
+

So, now we have the tools in place to actually start working on ICC code.

+

Expect the first steps toward a C++ script in the next days!

+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-7.html b/icc_project/documentation/html/day-7.html new file mode 100644 index 000000000..121a6e5d0 --- /dev/null +++ b/icc_project/documentation/html/day-7.html @@ -0,0 +1,1130 @@ + + + + + + + + + + + +
+

From the first week you should have learnt how to use Git to manage your source code

+

In this week we will start to look at the basic parts of actual boss scripting.

+

Today now is about how to

+
    +
  • +

    +What the first script looks like +

    +
  • +
  • +

    +A few elemental things about object oriented programming (OOP) +

    +
  • +
+
+

1. First Part:

+
+
+

1.1. The very first script

+

In commit 55481e02, see Commit on Github I added the following patch to the icc_branch:

+
+
+
From 55481e026600049a66277ee4e71110b1ba797418 Mon Sep 17 00:00:00 2001
+From: Schmoozerd <schmoozerd@scriptdev2.com>
+Date: Tue, 11 Oct 2011 18:51:53 +0200
+Subject: [PATCH] ICC, Festergut - Implement first script
+
+---
+ .../icecrown_citadel/boss_festergut.cpp            |   23 ++++++++++++++++++++
+ sql/mangos_scriptname_full.sql                     |    3 ++
+ sql/updates/r8800_mangos.sql                       |    1 +
+ 3 files changed, 27 insertions(+), 0 deletions(-)
+ create mode 100644 sql/updates/r8800_mangos.sql
+
+diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+index d0ce130..acd358d 100644
+--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+@@ -38,6 +38,29 @@ enum
+     SAY_FESTERGUT_DEATH         = -1631091,
+ };
+
++struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI        1
++{
++    boss_festergutAI(Creature* pCreature) : ScriptedAI(pCreature)
++    {
++        Reset();
++    }
++
++    void Reset()                                                   2
++    {
++    }
++};
++
++CreatureAI* GetAI_boss_festergut(Creature* pCreature)              3
++{
++    return new boss_festergutAI(pCreature);
++}
++
+ void AddSC_boss_festergut()
+ {
++    Script* pNewScript;                                            4
++
++    pNewScript = new Script;
++    pNewScript->Name = "boss_festergut";
++    pNewScript->GetAI = &GetAI_boss_festergut;
++    pNewScript->RegisterSelf();
+ }
+diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql
+index 8d95c69..de37e42 100644
+--- a/sql/mangos_scriptname_full.sql
++++ b/sql/mangos_scriptname_full.sql
+@@ -707,6 +707,9 @@ UPDATE creature_template SET ScriptName='npc_silvermoon_harry' WHERE entry=24539
+ /* ICECROWN CITADEL */
+ /*  */
+                                                                    5
++/* ICECROWN CITADEL */
++UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626;
++
+ /* FORGE OF SOULS */
+ UPDATE creature_template SET ScriptName='boss_bronjahm' WHERE entry=36497;
+ UPDATE creature_template SET ScriptName='npc_corrupted_soul_fragment' WHERE entry=36535;
+diff --git a/sql/updates/r8800_mangos.sql b/sql/updates/r8800_mangos.sql
+new file mode 100644
+index 0000000..262da6d
+--- /dev/null
++++ b/sql/updates/r8800_mangos.sql
+@@ -0,0 +1 @@                                                       6
++UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626;
+--
+1.7.6.msysgit.0
+
+
+

1.1.1. How this commit and patch here were created:

+
+
+
<Edit the required stuff>
+git add sql/updates/r8800_mangos.sql                                    ## To track this new file
+git commit -a -m "ICC, Festergut - Implement first script"              ## Commit all changes and name commit msg
+git log                                                                 ## To get the hash-id
+git format-patch HEAD^..HEAD --stdout > temp.patch                      ## Get the patch (and pasted here)
+
+
+
+

1.1.2. What can be seen here

+

Actually there are 6 main steps that I did - Don’t worry, they should be clear by the end of the day:

+
+ + + + + + +
1 +The actual class for the bossAI (AI = Artificial Intelligence) to be scripted +
2 +Any SD2 Boss script must implement the Reset function +
3 +The wrapper to actually create an instance of the implemented class +
4 +Some internal magic to help registering a script to SD2 side such that it can be used after assigned to the database. +

Remark especially that the to be used ScriptName is assigned here, too

+
5 +The required SQL-changes for mangos_scriptname_full.sql +
6 +The required SQL-changes for the sql update file +
+
+
+
+

1.2. Object oriented programming

+

This is now about the most fundamental aspect — objects and classes

+
+

1.2.1. What is a class? What is an object?

+

A class is the shape or an idea of things that we have in our mind.

+

I will stay with the name idea for now, because I think to distinct between classes and objects, it is (for now) easier to use the words "thing" and "idea".

+

When you go outside, then you might see an actual tree that grows high up into the air. This tree is an actual thing, that you can see, feel, smell and so on, it is part of the reality. +Nearby, there might be another tree, which would be another thing, but also an tree. +As a matter of fact, to read this sentence you must have an idea of trees in your mind (connected to the word tree), which helps you to recognise a tree when you see one.

+

So, in your mind there lives the idea of tree, and in reality you can see things that fit into the category tree - which is the idea tree you have.

+

If you want to know if a thing is a tree, you might compare the properties of the thing you see to the idea of tree you have in your mind. In your example (tree) reasonable properties would be: +A tree has roots, a stem, branches, and in summer the branches have leaves or needles. Also you might expect that the stem is quite tall, the roots are mostly in the earth, and so on..

+

Important of the concept of ideas is that you can differ: +No real thing is exactly like the idea of it, and no idea is exactly like any real thing. They both live in different planes.

+

About functionality: +* An idea can have attributes, expected behaviour (drop leaves in winter), and ways to modify it (nick an apple) +* The things realises - which means fill the values and behaviour - of these functionalities

+

In OOP (Object Oriented Programming) this concept is used in this way: +* An idea is represented by a class, +* A thing is represented by an object (or often called instance (of the class) )

+

Note: I feel this is not well written, any improvements are very welcome

+
+
+

1.2.2. A class hierarchy

+

As noted above the concepts of classes and objects is very natural to the way we think, and there is one other big part that is important: Inheritance +Classes can be subclasses of other classes, or parent classes of other classes.

+

This means, a class "A" which is a subclass of class "B" inherits all stuff from class B, but might overwrite a few things, or extend functionality.

+

If you now have many classes, which have sub and super classes, you have a hierarchy.

+

As this is also a very fundamental concept, I will give a very simple example:

+

Possible class hierarchy of two dimensional elemental geometric shapes

+

+Image: Class hierarchy for geometric shapes +

+ +

There you can see (in some UML notation) the setup:

+
    +
  • +

    +A super class which is rather abstract, named GeometricalShape +

    +

    This class has the attribute of the LeftBottomCorner (of type Point ), a Color attribute and a function to get the area GetArea

    +
  • +
  • +

    +A "Circle" is a geometric shape, hence it is realised as a subclass. +

    +

    Note that the attributes Color and LeftBottomCorner are inherited from GeometricShape.

    +

    The function GetArea needs to be overwritten to reproduce the expected result

    +
  • +
  • +

    +A "Rectangular" is also a geometric shape, however there we need an additional point (Could have also used height and width). +

    +
  • +
  • +

    +A "Square" is a specialisation of a rectangular, hence realised as subclass +

    +
  • +
+
+ + + +
+Note +These are only classes, no objects yet!
+
+
+
C++ implementation of this hierarchy
+

This is a sketch of normal C++ implementation

+
+
+
class GeometricShape                                    1
+{
+    GeometricShape(Point leftBottomCorner, int color)   2
+    {
+        m_pLeftBottomCorner.x = leftBottomCorner.x;     3
+        m_pLeftBottomCorner.y = leftBottomCorner.y;
+        m_iColor = color;
+    }
+
+    virtual float GetArea() { return 0.0f; }            4
+
+    Point m_pLeftBottomCorner;                          5
+    int m_iColor;
+};
+
+class Circle : public GeometricShape                    6
+{
+    Circle(Point leftBottomCorner, int color, float radius) : GeometricShape(leftBottomCorner, color)   7
+    {
+        m_fRadius = radius;
+    }
+
+    float GetArea()                                     8
+    {
+        return radius*radius*(float)PI;
+    }
+
+    float m_fRadius;                                    9
+};
+...
+
+

What do the different lines mean:

+
+ + + + + + + + + +
1 +This tells C++ that a new class starts which is named GeometricShape +
2 +This is the constructor of the class (when an object of a class is instantiated, the constructor is the first thing that is called) +

Here we tell the constructor to require two parameters, one of type Point, and one of type int

+
3 +Here we set the internal values of the class to the parameters given in the constructor +
4 +This is the default function to return the area of the geometric shape +

The virtual keyword is there, to mark this function to be overwritten by subclasses

+
5 +These are two member variables for the class. +

This is in Hungarian Notation which we use in ScriptDev2. For more information see SD2 Coding Standards

+
6 +This defines Circle as subclass of GeometricShape (by the :) +
7 +Constructor for Circle, we call the constructor of GeometricShape, and also set the new member variable +
8 +Overwrite the GetArea function to return the expected value for a circle. +
9 +A member variable of Circle +
+
+ + + +
+Tip + +

Some overview for OOP: wikipedia OOP overview - This covers mostly concepts

+

A fair warning about the example I chosed here: Why it works in this simple way, but may fail in other cases

+

Some C++ specific tutorial, which goes far further than such a small guide like this would ever do: http://www.desy.de/gna/html/cc/Tutorial/tutorial.html

+
+
+
+
+
+
+
+
+

2. Back to the class hierarchy for boss scripts in ScriptDev2

+
+
+
+
struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI        1
+{
+    boss_festergutAI(Creature* pCreature) : ScriptedAI(pCreature)  2
+    {
+        Reset();
+    }
+
+    void Reset()                                                   3
+    {
+    }
+};
+
+CreatureAI* GetAI_boss_festergut(Creature* pCreature)              4
+{
+    return new boss_festergutAI(pCreature);                        5
+}
+
+
+ + + + + +
1 +In this line we define the class boss_festergutAI as a subclass of ScriptedAI +
    +
  • +

    +struct and class mean for us for now the same +

    +
  • +
  • +

    +the MANGOS_DLL_DECL can be considered as magic, that is required because we implement a class for a DLL to be used by another project +

    +
  • +
+
2 +The constructor for our class: We inherit stuff from ScriptedAI, and call its constructor first, then we do some own code +
3 +Reset is a so called "pure virtual function" which means a subclass must implement it, else wise it won’t compile +
4 +This is now something new. If you have read the stuff above carefully you would have noted that we have yet only implemented classes, but never objects. +

But of course we want to handle objects, each boss should have a specific object/ instance of the AI loaded. This is done with the new keyword.

+
5 +This line creates a new object of the class boss_festergutAI and handles this newly created class back to some other places (actually to mangos) where it is assigned to the real boss. +
+
+
+
+

3. End of first part

+
+
+ + + +
+Exercise + +
Exercise 1 - Test the first script!
+

Compile SD2 with these changes, and then test the script on boss festergut.

+

As the script does not do very much, use the .npc aiinfo command, to see if it is actually loaded

+
+
+

What you should have seen today:

+
    +
  • +

    +Basic things of OOP: Classes and Objects +

    +
  • +
  • +

    +Inheritance as fundamental concept to make the programmers' life easier +

    +
  • +
+

What comes next:

+
    +
  • +

    +A few notes to class hierarchy used in ScriptDev2 (CreatureAI ← ScriptedAI ← boss_*AI) +

    +
  • +
  • +

    +How to bring life to the first script. +

    +
  • +
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-8.html b/icc_project/documentation/html/day-8.html new file mode 100644 index 000000000..2266e803d --- /dev/null +++ b/icc_project/documentation/html/day-8.html @@ -0,0 +1,1119 @@ + + + + + + + + + + + +
+

In Day 7 you should have seen:

+
    +
  • +

    +A few basic ideas of OOP +

    +
  • +
  • +

    +What a minimal ScriptDev2 script looks like, and how it is added to the system +

    +
  • +
+

This day is now about

+
    +
  • +

    +A description about the main classes used for boss scripts in ScriptDev2 +

    +
  • +
  • +

    +A few things you can do with the provided powers +

    +
  • +
+
+

1. First Part

+
+

Interaction between MaNGOS and ScriptDev2 for Creature AIs

+
+

1.1. The CreatureAI class

+

The class CreatureAI defined in MaNGOS, especially in src/game/CreatureAI.h is the topmost class for any AI a creature uses. +Any npc in the world has one AI, and this AI is a subclass of CreatureAI.

+

The AI of any Creature can be accessed by the member function of the Creature class named AI().

+ +
+ + + +
+Tip +TODO Link here to auto-generated documentation
+
+

When you look into the source, you will notice that nearly all of the functions are marked virtual +This means, that when anywhere in the core one of these functions is called the implementation of this function in the actual class realising the AI will be called.

+

This is the way how the script is "informed" about events that it might want to react to.

+

When the core will call these functions is documented there.

+
+
+

1.2. The ScriptedAI class

+

The class ScriptedAI is the base class in ScriptDev2 to be used to implement scripts. +It implements a few of the functions of CreatureAI with default behaviour you might expect from a creature.

+

What are the actual default implementations of ScriptedAI can be seen in include/sc_creature.cpp:

+ +

When we implement a boss script, we usally overwrite a few functions of ScriptedAI (and hence overwrite the functions of CreatureAI).

+
+
+

1.3. Our example class boss_festergutAI

+

As you should remember from Day 7 that boss_festergutAI is a subclass of ScriptedAI, which is a subclass of CreatureAI.

+

Currently, this class does not do very much, and hence also the instances of the class assigned to a spawned creature is also rather boring.

+
+
+
+
+

2. End of first part

+
+

This already brings us to the end of the small introduction of the CreatureAI functions. +This got way shorter than intended, and must be improved.

+

The main problem here is how to bring a relatively big class with a fair amount of documentation into a usable format for this guide.

+
+ + + +
+Exercise + +
Exercise 1 - Do my job :)
+

Do look into the CreatureAI class, and think if there might be ways to present it in a guide environment!

+
+
+
+
+
+

3. Second Part:

+
+

As just noted, the script we added to boss Festergut with the class boss_festergutAI is really really boring, so now we start to change it!

+

In this part we will cover a few of the virtual functions we have available through CreatureAI to do some text output.

+
+

3.1. Text Output in ScriptDev2

+

Luckily most of the texts in ICC are already prepared for ScriptDev2, so we can use them very easy. +They might not be all correct, and it will become required to change some of them to make them better. +Currently they are taken from wowwiki, which is a good source but not always perfect.

+
+

3.1.1. The signature of a function

+

Any function defined in C++ has a so called signature. +This is the combination of:

+
+
+return-type +
+
+

+The type of the values returned by the function +

+
+
+function-name +
+
+

+The name of the function (in case of C++ case sensetive) +

+
+
+paramter-list +
+
+

+The parameter types the function takes +

+
+
+
+
+
+

3.2. DoScriptText

+

Our main method to output text is DoScriptText which is defined in ScriptMgr.cpp, its signature looks like this:

+
+
+
void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget /*=NULL*/)
+
+

Where the parameters have this meaning:

+
+
+iTextEntry(an int32 number) +
+
+

+Entry of the text, stored in SD2-database +

+
+
+pSource(a WorldObject, often a Creature) +
+
+

+Who displays the text +

+
+
+pTarget(a Unit, that is player or creature) +
+
+

+To whom the text will be directed, not required +

+
+
+
+ + + +
+Tip +A detailed description of how SD2 stores the texts in the database can be found in Guide for SD2-SQL
+
+
+
+

3.3. Doing Text on Aggro

+

Most bosses have a text when they start attacking, this we call Aggro for which a function in ScriptedAI is defined, with the signature

+
+
+
void Aggro(Unit* pWho)
+
+
+
+pWho +
+
+

+is the Unit (Player or Creature) whom we aggro. +

+
+
+

This we will now overwrite, to display the text "Fun time!" by Festergut when Festergut aggroes.

+

This text is already in the SD2 database, and the number is assigned the constant SAY_AGGRO.

+

The required change looks like this:

+
+
+
From f5f3a22fec940bdf0b4a20fc6f8c09859af97609 Mon Sep 17 00:00:00 2001
+From: Schmoozerd <schmoozerd@scriptdev2.com>
+Date: Sat, 15 Oct 2011 01:31:06 +0200
+Subject: [PATCH] ICC, Festergut - Add Aggro text
+
+---
+ .../icecrown_citadel/boss_festergut.cpp            |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+index acd358d..940b7f7 100644
+--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+@@ -48,6 +48,11 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI
+     void Reset()
+     {
+     }
++
++    void Aggro(Unit* pWho)                         1
++    {
++        DoScriptText(SAY_AGGRO, m_creature);
++    }
+ };
+
+ CreatureAI* GetAI_boss_festergut(Creature* pCreature)
+--
+1.7.6.msysgit.0
+
+

Where

+
+ +
1 +The actual changes to the code +
+

Remark that the variable m_creature links to Festergut.

+
+ + + +
+Exercise + +
Exercise 2 - Where is it from
+

Where is the variable m_creature defined?

+
+
+
+
+

3.4. Doing Text when killing a player

+

This is very important text, because a both where this doesn’t happen should not be called boss :) +Only killed players are good players!

+

Looking again into CreatureAI you can find:

+
+
+
        /**
+         * Called when the creature kills a unit
+         * @param pVictim Victim that got killed
+         */
+        virtual void KilledUnit(Unit* pVictim) {}
+
+

As Player is a subclass of Unit, a player is also a unit, so this function can be expected to be called when the creature kills a player. +This is infact true, so we will use this function to display the text we want to display when killing enemies.

+

From wowwiki we take the texts "Daddy, I did it!" and "Dead, dead, dead!" which should be displayed when killing. +There are already two constants assinged: SAY_SLAY_1 and SAY_SLAY_2.

+

The required code to overwrite the function "void KilledUnit(Unit* pVictim)" is:

+
+
+
    void KilledUnit(Unit* pVictim)
+    {
+        DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature);
+    }
+
+

The full changeset can be seen on Github or on Github as format-patch

+

In case you have never seen this construction before:

+

With expression ? A : B you tell the code to set at this place IF expression is true THEN A ELSE B, which is handy to write compact code.

+
+ + + +
+Exercise + +
Exercise 3 - More texts
+

Find a function that could be used when a creature just died, and use it to display the text of constant SAY_DEATH

+
+
+
+
+
+
+

4. End of second part

+
+

What you should have seen today:

+
    +
  • +

    +Where the functions you can use in ScriptDev2 boss scripts come from +

    +
  • +
  • +

    +How to use them to display some texts +

    +
  • +
+

What comes next:

+
    +
  • +

    +The UpdateAI function, and timers +

    +
  • +
  • +

    +Some more constructs to make a boss deadly +

    +
  • +
+
+ + + +
+Exercise + +
Exercise 4 - Prepare yourself
+

Figure out how UpdateAI is called, and think about how this could be used.

+
+
+
+ + + +
+Note +This is no special exercise, because I really want to encourage you guys to take matters into your own hand, and do some own stuff!
+
+
+ + + +
+Exercise + +
Exercise 5 - Do some own stuff
+
    +
  • +

    +Pick another boss, create a basic script (look into Day 7) +

    +
  • +
  • +

    +Let this other boss display some basic texts like done today +

    +
  • +
  • +

    +Share the code you did with us all! +

    +

    Best use format-patch styled output on http://paste2.org/new-paste and post your scripts in the forum. Take a look into the first week if you feel unsecure with creating patches and commits!

    +
  • +
+
+
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/day-9.html b/icc_project/documentation/html/day-9.html new file mode 100644 index 000000000..18fa77549 --- /dev/null +++ b/icc_project/documentation/html/day-9.html @@ -0,0 +1,1246 @@ + + + + + + + + + + + +
+

In Day 8 you should have seen:

+
    +
  • +

    +Which classes you need to specialise in order to create boss scripts +

    +
  • +
  • +

    +A bunch of functions that are useful for this +

    +
  • +
+

This day is now about

+
    +
  • +

    +Some thoughts about spells (as this is the thing most bosses do: Cast spells) +

    +
  • +
  • +

    +Implementing casting spells +

    +
  • +
+
+

1. First Part

+
+

For a clean scripting attempt it is expected to handle nearly everything with spells. So this part is now about the spell system.

+

Any spell is cast by some caster onto some victim. And a spell will hit some targets.

+

For some direct spells like ie Fireball the target will be the victim, but ie for AoE spells like ArcaneExplosion the victim will be the caster (self-cast spell), and the targets will be enemies around.

+
+

1.1. The spell system

+

Spells are provided in dbc form which can be extracted from the wow-client. Actually if you installed a local test server already, you will have extracted these dbc files.

+

The structure (as far as known) for the spell.dbc can be seen in MaNGOS::DBCStructure.h - struct SpellEntry. However this is rather unpleasant to read and hence I strongly suggest to use a tool to help understanding these entries.

+
+ + + +
+Tip +SpellWork This is a nice tool to view the spell dbc, binary files can be downloaded from the SpellWork/bin/Release directory over github
+
+

Basic structure of a spell:

+
    +
  • +

    +Id and name - this identifies a spell +

    +
  • +
  • +

    +Some internal information +

    +
  • +
  • +

    +Spell Range +

    +
  • +
  • +

    +Difficulty information (if exists) - If a spell has difficulty information, you only need to cast the base spell, the proper one for current difficulty will be selected by MaNGOS +

    +
  • +
  • +

    +Information about Cast-Time, Duration of auras and similar +

    +
  • +
  • +

    +Information what the spell actually does: +

    +

    A spell has up to three effects (like summon or dealing damage).

    +

    Each effect consists of:

    +
      +
    • +

      +The effect type (what the effect will do) +

      +
    • +
    • +

      +The target types (how the targeting of the spell will work - AoE, Self, enemy) +

      +
    • +
    • +

      +Some additional information about this effect (like how many damage, what npc will be summoned and so on) +

      +
    • +
    +
  • +
+
+
+

1.2. The spell system in MaNGOS

+

Some parts of how spells should be handled are unknown, which means we can only interpret the values from spell.dbc by what should happen (and this usually is how the handling is implemented within MaNGOS)

+

It is not in the scope of this guide to give some detailed explanation of everything about how spells are handled. For this you must seriously study the MaNGOS code.

+
+ + + +
+Tip +TODO Link here to the wiki page that should exist about mangos spell system.
+
+

Effects and their implementation can be seen in MaNGOS:SpellEffects.cpp. Often the name of the effect gives some good clue what they will do

+

Targeting can be seen in MaNGOS::Spell.cpp. Most important targets are:

+
    +
  • +

    +TARGET_SELF - the effect will target the caster +

    +
  • +
  • +

    +TARGET_*AREA* - the effect will work as AoE spell, in case of SpellRange == 0, the spell must be self cast +

    +
  • +
  • +

    +TARGET_CHAIN_DAMAGE - the effect will target the victim +

    +
  • +
  • +

    +TARGET_SCRIPT* - the target is fixed by the table spell_script_target +

    +
  • +
+
+ + + +
+Exercise + +
Exercise 1 - Check a few spells
+

Download SpellWork and check a few spells: Maybe IDs 9488 or 59245.

+
+
+
+
+

1.3. Which spells should a boss cast?

+

Well, by now you should have seen a few spells and be able to have a rough idea what they are doing. But of course the most important question still is: What spells should a boss use? (And when)

+

To get information what spells a boss should use, you can check:

+
    +
  • +

    +Database sites (like wowhead) - NPCs usually have there a list of abilities, however this can be incomplete or even wrong +

    +
  • +
  • +

    +Transcriptor/ Combat logs (there are sites where such are available) +

    +
  • +
  • +

    +The DBM Addon +

    +
  • +
  • +

    +Watching videos +

    +
  • +
  • +

    +Wowwiki and similar sites +

    +
  • +
+

There are usually two answers of when a spell is cast:

+
    +
  1. +

    +On a timer: This means, some time after engaging combat, and then repeating after some time. +

    +
  2. +
  3. +

    +On some event: Like 50% health, or when an add dies +

    +
  4. +
+

To figure this you must use resources like videos, experience or a bunch of logs (and of course good guessing also helps)

+
+
+
+
+

2. End of first part

+
+

In this part you should have seen how a spell looks like, and how to obtain information about its use.

+
+
+
+

3. Second Part:

+
+

This part now will look about how spell casting is to be implemented in MaNGOS.

+

The main function that will be used for spell casting is:

+
+
+
DoCastSpellIfCan(Unit* pVictim, uint32 uiSpellId); which returns a value of type CastResult
+
+
+

3.1. The virtual function UpdateAI(const uint32 uiDiff)

+

MaNGOS calls for every AI the function UpdateAI(const uint32 uiDiff) about every 100ms. The actual time since last call is stored in uiDiff.

+

This gives two possibilites:

+
    +
  • +

    +Handle things that should be handled always +

    +
  • +
  • +

    +Countdown a timer +

    +
  • +
+
+

3.1.1. How does a timer work, if we know the time-diff since we last called a function?

+

A timer is a variable of type uin32 (unsingned integer), which stores the time until the timer should expire next (in millieseconds)

+

So, a minimal timer script would look like:

+
+
+
struct MANGOS_DLL_DECL boss_dummyAI : public ScriptedAI
+{
+    boss_dummyAI(Creature* pCreature) : ScriptedAI(pCreature)
+    {
+        Reset();
+    }
+
+    uint32 m_uiTimer;                                              1
+
+    void Reset()                                                   2
+    {
+        m_uiTimer = 17000;                                         3
+    }
+
+    void UpdateAI(const uint32 uiDiff)                             4
+    {
+        if (m_uiTimer < uiDiff)                                    6
+        {
+            DoScriptText(-1000001, m_creature);                    7
+            m_uiTimer = 30000;                                     8
+        }
+        else
+            m_uiTimer -= uiDiff;                                   5
+    }
+};
+
+

Note that this misses all stuff like registering the script, but you should be able to test it, if you move the content to some other empty script (maybe festergut)

+

The meaning of the new lines:

+
+ + + + + + + + +
1 +In this line the member variable m_uiTimer of the struct boss_dummyAI is defined. +
2 +This is the virtual Reset function that every script implements. +
3 +And we reset here the timer to the initially value. +
4 +Here we overwrite the UpdateAI function, that will be called every uiDiff millieseconds. +
5 +If the timer is not expired ("else") we decrement it. +
6 +We check if the timer is expired (which means it is time to do something for which we need the timer) +
7 +Some Text will be displayed +
8 +The timer will be set to a new value +
+

Currently this function only contains the timer handling.

+
+
How exactly does a timer work
+

It is probably a good idea to clarify this with pen and paper: Think what will happen in the code (assume the UpdateAI is called every 100ms)

+

When the script is initialized the timer will be 17000. On first tick of UpdateAI evaluating the code looks like:

+
+
+
    void UpdateAI(const uint32 uiDiff==100)
+    {
+        if (m_uiTimer==17000 < 100)    // evaluates to false
+        {
+            DoScriptText(-1000001, m_creature);
+            m_uiTimer = 30000;
+        }
+        else
+            m_uiTimer==17000 -= 100;
+    }
+
+

When this code is finished, m_uiTimer will be decremented by 100, and has then the value of 16900.

+

The next tick would look like:

+
+
+
    void UpdateAI(const uint32 uiDiff==100)
+    {
+        if (m_uiTimer==16900 < 100)    // evaluates to false
+        {
+            DoScriptText(-1000001, m_creature);
+            m_uiTimer = 30000;
+        }
+        else
+            m_uiTimer==16900 -= 100;
+    }
+
+

When this code is finished, m_uiTimer will be decremented by 100, and has then the value of 16800.

+

After a bunch of more ticks the code will evaluate to (Exercise: How many ticks? - How long does it take?)

+
+
+
    void UpdateAI(const uint32 uiDiff==100)
+    {
+        if (m_uiTimer==0 < 100)    // evaluates to true
+        {
+            DoScriptText(-1000001, m_creature);
+            m_uiTimer = 30000;
+        }
+        else
+            m_uiTimer==0 -= 100;
+    }
+
+

And the timer will be expired, and the actions that should happen when the timer is expired will be triggered.

+
+ + + +
+Exercise + +
Exercise 2 - Understand the timer
+

When will the timer first expire?

+

When will the timer the second time expire?

+
+
+
+ + + +
+Exercise + +
Exercise 3 - Understand the timer(2)
+

Change the code so that the timer will initially expire after 10seconds, and from then expire every 30-40 seconds. (Hint: urand(A, B) gives a random number between A and B)

+
+
+
+
+
+

3.1.2. What other stuff fits well into the UpdateAI function?

+

In normal cases we want to script combat behaviour. And most important for combating is of course threat management (whom the boss should attack).

+

This is handled by MaNGOS with the function SelectHostileTarget.

+

Also we normally want a boss to do melee attack.

+

This is handled by MaNGOS with the function DoMeleeAttackIfReady.

+

So the structure for a normal UpdateAI should look like this (changes might be reasonable, but only very rarely)

+
+
+
    void UpdateAI(const uint32 uiDiff)
+    {
+        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
+           return;              1
+
+        // Some combat Timers
+
+        DoMeleeAttackIfReady();
+    }
+
+
+ +
1 +As of this return anything after will only be executed when we are in proper combat. +
+
+
+
+

3.2. Real example: Let Festergut cast something

+

On wowhead-Festergut I found a spell ID for the Berserk spell as well as the information that the berserk should happen after 5 minutes (initially)

+
+
+
diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+index b059c1f..30ec25e 100644
+--- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
++++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp
+@@ -36,6 +36,8 @@ enum
+     SAY_BERSERK                 = -1631089,
+     SAY_DEATH                   = -1631090,
+     SAY_FESTERGUT_DEATH         = -1631091,
++
++    SPELL_BERSERK               = 47008,                          1
+ };
+
+ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI
+@@ -45,8 +47,11 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI
+         Reset();
+     }
+
++    uint32 m_uiBerserkTimer;                                      2
++
+     void Reset()
+     {
++        m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS;
+     }
+
+     void Aggro(Unit* pWho)
+@@ -58,6 +63,21 @@ struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI
+     {
+         DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature);
+     }
++
++    void UpdateAI(const uint32 uiDiff)
++    {
++        if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
++            return;
++
++        if (m_uiBerserkTimer < uiDiff)                            3
++        {
++            DoCastSpellIfCan(m_creature, SPELL_BERSERK);
++            DoScriptText(SAY_BERSERK, m_creature);
++            m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS;
++        }
++        else
++            m_uiBerserkTimer -= uiDiff;
++    }
+ };
+
+ CreatureAI* GetAI_boss_festergut(Creature* pCreature)
+
+

What is done here:

+
+ + + +
1 +The Berserk spell ID is assigned to an enum (to prevent so called magic numbers) +
2 +As we can expect that there will be additional timers for this boss, we must find unique names for every timer, usually this works well with the spellname. + +
3 +The actual implementation of the timer. From the infos there should be besides the casting of the berserk spell also a text displayed that Festergut enrages. +
+

This patch was commited with bd821056ec9f

+
+ + + +
+Exercise + +
Exercise 4 - Add some abilities to your own script
+

Write a script for an own boss and add some abilites, or add some abilites to Festergut here.

+

Provide patches to the forum thread!

+

Also note from which sources you got which info - good place for this would be the commit message

+
+
+
+
+
+
+

4. End of second part

+
+

What you should have seen today:

+
    +
  • +

    +How spells work +

    +
  • +
  • +

    +How to cast spells on a timer +

    +
  • +
+

What comes next:

+
    +
  • +

    +Using events to trigger some stuff +

    +
  • +
  • +

    +Using phases +

    +
  • +
+
+
+
+

+ + + diff --git a/icc_project/documentation/html/images/geo_shapes.png b/icc_project/documentation/html/images/geo_shapes.png new file mode 100644 index 000000000..f024c4a77 Binary files /dev/null and b/icc_project/documentation/html/images/geo_shapes.png differ diff --git a/icc_project/documentation/html/images/icons/README b/icc_project/documentation/html/images/icons/README new file mode 100644 index 000000000..f12b2a730 --- /dev/null +++ b/icc_project/documentation/html/images/icons/README @@ -0,0 +1,5 @@ +Replaced the plain DocBook XSL admonition icons with Jimmac's DocBook +icons (http://jimmac.musichall.cz/ikony.php3). I dropped transparency +from the Jimmac icons to get round MS IE and FOP PNG incompatibilies. + +Stuart Rackham diff --git a/icc_project/documentation/html/images/icons/callouts/1.png b/icc_project/documentation/html/images/icons/callouts/1.png new file mode 100644 index 000000000..7d473430b Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/1.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/10.png b/icc_project/documentation/html/images/icons/callouts/10.png new file mode 100644 index 000000000..997bbc824 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/10.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/11.png b/icc_project/documentation/html/images/icons/callouts/11.png new file mode 100644 index 000000000..ce47dac3f Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/11.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/12.png b/icc_project/documentation/html/images/icons/callouts/12.png new file mode 100644 index 000000000..31daf4e2f Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/12.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/13.png b/icc_project/documentation/html/images/icons/callouts/13.png new file mode 100644 index 000000000..14021a89c Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/13.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/14.png b/icc_project/documentation/html/images/icons/callouts/14.png new file mode 100644 index 000000000..64014b75f Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/14.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/15.png b/icc_project/documentation/html/images/icons/callouts/15.png new file mode 100644 index 000000000..0d65765fc Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/15.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/2.png b/icc_project/documentation/html/images/icons/callouts/2.png new file mode 100644 index 000000000..5d09341b2 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/2.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/3.png b/icc_project/documentation/html/images/icons/callouts/3.png new file mode 100644 index 000000000..ef7b70047 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/3.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/4.png b/icc_project/documentation/html/images/icons/callouts/4.png new file mode 100644 index 000000000..adb8364eb Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/4.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/5.png b/icc_project/documentation/html/images/icons/callouts/5.png new file mode 100644 index 000000000..4d7eb4600 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/5.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/6.png b/icc_project/documentation/html/images/icons/callouts/6.png new file mode 100644 index 000000000..0ba694af6 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/6.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/7.png b/icc_project/documentation/html/images/icons/callouts/7.png new file mode 100644 index 000000000..472e96f8a Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/7.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/8.png b/icc_project/documentation/html/images/icons/callouts/8.png new file mode 100644 index 000000000..5e60973c2 Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/8.png differ diff --git a/icc_project/documentation/html/images/icons/callouts/9.png b/icc_project/documentation/html/images/icons/callouts/9.png new file mode 100644 index 000000000..a0676d26c Binary files /dev/null and b/icc_project/documentation/html/images/icons/callouts/9.png differ diff --git a/icc_project/documentation/html/images/icons/caution.png b/icc_project/documentation/html/images/icons/caution.png new file mode 100644 index 000000000..9a8c515a1 Binary files /dev/null and b/icc_project/documentation/html/images/icons/caution.png differ diff --git a/icc_project/documentation/html/images/icons/example.png b/icc_project/documentation/html/images/icons/example.png new file mode 100644 index 000000000..1199e864f Binary files /dev/null and b/icc_project/documentation/html/images/icons/example.png differ diff --git a/icc_project/documentation/html/images/icons/home.png b/icc_project/documentation/html/images/icons/home.png new file mode 100644 index 000000000..37a5231ba Binary files /dev/null and b/icc_project/documentation/html/images/icons/home.png differ diff --git a/icc_project/documentation/html/images/icons/important.png b/icc_project/documentation/html/images/icons/important.png new file mode 100644 index 000000000..be685cc4e Binary files /dev/null and b/icc_project/documentation/html/images/icons/important.png differ diff --git a/icc_project/documentation/html/images/icons/next.png b/icc_project/documentation/html/images/icons/next.png new file mode 100644 index 000000000..64e126bdd Binary files /dev/null and b/icc_project/documentation/html/images/icons/next.png differ diff --git a/icc_project/documentation/html/images/icons/note.png b/icc_project/documentation/html/images/icons/note.png new file mode 100644 index 000000000..7c1f3e2fa Binary files /dev/null and b/icc_project/documentation/html/images/icons/note.png differ diff --git a/icc_project/documentation/html/images/icons/prev.png b/icc_project/documentation/html/images/icons/prev.png new file mode 100644 index 000000000..3e8f12fe2 Binary files /dev/null and b/icc_project/documentation/html/images/icons/prev.png differ diff --git a/icc_project/documentation/html/images/icons/tip.png b/icc_project/documentation/html/images/icons/tip.png new file mode 100644 index 000000000..f087c73b7 Binary files /dev/null and b/icc_project/documentation/html/images/icons/tip.png differ diff --git a/icc_project/documentation/html/images/icons/up.png b/icc_project/documentation/html/images/icons/up.png new file mode 100644 index 000000000..2db1ce62f Binary files /dev/null and b/icc_project/documentation/html/images/icons/up.png differ diff --git a/icc_project/documentation/html/images/icons/warning.png b/icc_project/documentation/html/images/icons/warning.png new file mode 100644 index 000000000..d41edb9ad Binary files /dev/null and b/icc_project/documentation/html/images/icons/warning.png differ diff --git a/icc_project/research/research_blood_prince_council.txt b/icc_project/research/research_blood_prince_council.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_blood_queen_lanathel.txt b/icc_project/research/research_boss_blood_queen_lanathel.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_deathbringer_saurfang.txt b/icc_project/research/research_boss_deathbringer_saurfang.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_festergut.txt b/icc_project/research/research_boss_festergut.txt new file mode 100644 index 000000000..f139357a0 --- /dev/null +++ b/icc_project/research/research_boss_festergut.txt @@ -0,0 +1,23 @@ +Hi, + +I made 2 structograms about the UpdateAI of the boss festergut. +I hope it will give you on a simple way a overview about what the boss do. + +### UpdateAI + +Basic structogram about the UpdateAI from festergut: +http://filebeam.com/989245ce17458b524896e4baf40f2a29.jpg) + +After you see this, you may want to see more detail. +To satisfy this, you can look at the second structogram: + +More detailed structogram about the UpdateAI of Festergut: +http://filebeam.com/148c8edc1dd7da75c5287128ae19b57d.jpg + + +### ScriptedAI + +After you know how the UpdateAI should look, you have to integrate it in the ScriptedAI. + +The structure of the ScriptedAI is shown in the following structogram: +http://filebeam.com/d249e442935fb2c53a5e0c624af4eb92.jpg diff --git a/icc_project/research/research_boss_lady_deathwhisper.txt b/icc_project/research/research_boss_lady_deathwhisper.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_lord_marrowgar.txt b/icc_project/research/research_boss_lord_marrowgar.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_professor_putricide.txt b/icc_project/research/research_boss_professor_putricide.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_rotface.txt b/icc_project/research/research_boss_rotface.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_sindragosa.txt b/icc_project/research/research_boss_sindragosa.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_the_lich_king.txt b/icc_project/research/research_boss_the_lich_king.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_boss_valithria_dreamwalker.txt b/icc_project/research/research_boss_valithria_dreamwalker.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_gunship_battle.txt b/icc_project/research/research_gunship_battle.txt new file mode 100644 index 000000000..e69de29bb diff --git a/icc_project/research/research_instance_icecrown_citadel.txt b/icc_project/research/research_instance_icecrown_citadel.txt new file mode 100644 index 000000000..e69de29bb diff --git a/include/sc_creature.cpp b/include/sc_creature.cpp index c625da773..cecf63f41 100644 --- a/include/sc_creature.cpp +++ b/include/sc_creature.cpp @@ -124,7 +124,6 @@ void ScriptedAI::EnterEvadeMode() m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); if (m_creature->isAlive()) m_creature->GetMotionMaster()->MoveTargetedHome(); diff --git a/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp b/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp new file mode 100644 index 000000000..2b1aa23d9 --- /dev/null +++ b/scripts/eastern_kingdoms/deadmines/boss_mr_smite.cpp @@ -0,0 +1,278 @@ +/* Copyright (C) 2006 - 2011 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: Boss_Mr_Smite +SD%Complete: 100 +SDComment: +SDCategory: Deadmines +EndScriptData */ + +#include "precompiled.h" +#include "deadmines.h" + +enum +{ + SAY_PHASE_2 = -1036002, + SAY_PHASE_3 = -1036003, + + // EQUIP_ID_SWORD = 2179, // default equipment, not used in code + EQUIP_ID_AXE = 2183, + EQUIP_ID_HAMMER = 10756, + + SPELL_NIBLE_REFLEXES = 6433, // removed after phase 1 + SPELL_SMITE_SLAM = 6435, + SPELL_SMITE_STOMP = 6432, + SPELL_SMITE_HAMMER = 6436, + SPELL_THRASH = 12787, // unclear, possible 3417 (only 10% proc chance) + + PHASE_1 = 1, + PHASE_2 = 2, + PHASE_3 = 3, + PHASE_EQUIP_NULL = 4, + PHASE_EQUIP_START = 5, + PHASE_EQUIP_PROCESS = 6, + PHASE_EQUIP_END = 7, +}; + +struct MANGOS_DLL_DECL boss_mr_smiteAI : public ScriptedAI +{ + boss_mr_smiteAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } + + uint32 m_uiPhase; + uint32 m_uiEquipTimer; + uint32 m_uiSlamTimer; + + void Reset() + { + m_uiPhase = PHASE_1; + m_uiEquipTimer = 0; + m_uiSlamTimer = 9000; + + DoCastSpellIfCan(m_creature, SPELL_NIBLE_REFLEXES, CAST_TRIGGERED); + + // must assume database has the default equipment set + SetEquipmentSlots(true); + } + + void AttackedBy(Unit* pAttacker) + { + if (m_creature->getVictim()) + return; + + if (m_uiPhase > PHASE_3) + return; + + AttackStart(pAttacker); + } + + void AttackStart(Unit* pWho) + { + if (m_uiPhase > PHASE_3) + return; + + if (m_creature->Attack(pWho, true)) + { + m_creature->AddThreat(pWho); + m_creature->SetInCombatWith(pWho); + pWho->SetInCombatWith(m_creature); + + m_creature->GetMotionMaster()->MoveChase(pWho); + } + } + + void MovementInform(uint32 uiMotionType, uint32 uiPointId) + { + if (uiMotionType != POINT_MOTION_TYPE) + return; + + m_creature->SetSheath(SHEATH_STATE_UNARMED); + m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); + + m_uiEquipTimer = 3000; + m_uiPhase = PHASE_EQUIP_PROCESS; + } + + void PhaseEquipStart() + { + ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); + + if (!pInstance) + return; + + GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); + + if (!pChest) + return; + + m_uiPhase = PHASE_EQUIP_NULL; + + float fX, fY, fZ; + pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); + + m_creature->GetMotionMaster()->Clear(); + m_creature->SetFacingToObject(pChest); + m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); + } + + void PhaseEquipProcess() + { + if (m_creature->GetHealthPercent() < 33.0f) + { + // It's Hammer, go Hammer! + SetEquipmentSlots(false, EQUIP_ID_HAMMER, EQUIP_UNEQUIP); + DoCastSpellIfCan(m_creature, SPELL_SMITE_HAMMER); + } + else + SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE); + + m_creature->SetStandState(UNIT_STAND_STATE_STAND); + m_uiPhase = PHASE_EQUIP_END; + m_uiEquipTimer = 1000; + + Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0); + + if (!pVictim) + { + EnterEvadeMode(); + return; + } + } + + void PhaseEquipEnd() + { + // We don't have getVictim, so select from threat list + Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0); + + if (!pVictim) + { + EnterEvadeMode(); + return; + } + + m_creature->SetSheath(SHEATH_STATE_MELEE); + + m_uiPhase = m_creature->GetHealthPercent() < 33.0f ? PHASE_3 : PHASE_2; + + if (m_uiPhase == PHASE_2) + DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED); + + AttackStart(pVictim); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + { + if (m_uiEquipTimer) + { + // decrease the cooldown in between equipment change phases + if (m_uiEquipTimer > uiDiff) + { + m_uiEquipTimer -= uiDiff; + return; + } + else + m_uiEquipTimer = 0; + } + + switch(m_uiPhase) + { + case PHASE_EQUIP_START: + PhaseEquipStart(); + break; + case PHASE_EQUIP_PROCESS: + PhaseEquipProcess(); + break; + case PHASE_EQUIP_END: + PhaseEquipEnd(); + break; + } + + return; + } + + // the normal combat phases + switch(m_uiPhase) + { + case PHASE_1: + { + if (m_creature->GetHealthPercent() < 66.0f) + { + if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK) + { + DoScriptText(SAY_PHASE_2, m_creature); + m_uiPhase = PHASE_EQUIP_START; + m_uiEquipTimer = 2500; + + // will clear getVictim (m_attacking) + m_creature->AttackStop(true); + m_creature->RemoveAurasDueToSpell(SPELL_NIBLE_REFLEXES); + } + return; + } + break; + } + case PHASE_2: + { + if (m_creature->GetHealthPercent() < 33.0f) + { + if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK) + { + DoScriptText(SAY_PHASE_3, m_creature); + m_uiPhase = PHASE_EQUIP_START; + m_uiEquipTimer = 2500; + + // will clear getVictim (m_attacking) + m_creature->AttackStop(true); + m_creature->RemoveAurasDueToSpell(SPELL_THRASH); + } + return; + } + break; + } + case PHASE_3: + { + if (m_uiSlamTimer < uiDiff) + { + if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SMITE_SLAM) == CAST_OK) + m_uiSlamTimer = 11000; + } + else + m_uiSlamTimer -= uiDiff; + + break; + } + } + + DoMeleeAttackIfReady(); + } +}; + +CreatureAI* GetAI_boss_mr_smite(Creature* pCreature) +{ + return new boss_mr_smiteAI(pCreature); +} + +void AddSC_boss_mr_smite() +{ + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_mr_smite"; + pNewScript->GetAI = &GetAI_boss_mr_smite; + pNewScript->RegisterSelf(); +} diff --git a/scripts/eastern_kingdoms/deadmines/deadmines.cpp b/scripts/eastern_kingdoms/deadmines/deadmines.cpp index f863d9936..4e6907a8a 100644 --- a/scripts/eastern_kingdoms/deadmines/deadmines.cpp +++ b/scripts/eastern_kingdoms/deadmines/deadmines.cpp @@ -16,261 +16,14 @@ /* ScriptData SDName: Deadmines -SD%Complete: 75 -SDComment: Contains boss_mr_smite and GO for event at end door +SD%Complete: 100 +SDComment: Contains GO for Iron Clad door event SDCategory: Deadmines EndScriptData */ #include "precompiled.h" #include "deadmines.h" -/*###### -## boss_mr_smite -######*/ - -enum -{ - SAY_PHASE_2 = -1036002, - SAY_PHASE_3 = -1036003, - - // EQUIP_ID_SWORD = 2179, // default equipment, not used in code - EQUIP_ID_AXE = 2183, - EQUIP_ID_HAMMER = 10756, - - SPELL_NIBLE_REFLEXES = 6433, // removed after phase 1 - SPELL_SMITE_SLAM = 6435, - SPELL_SMITE_STOMP = 6432, - SPELL_SMITE_HAMMER = 6436, - SPELL_THRASH = 12787, // unclear, possible 3417 (only 10% proc chance) - - PHASE_1 = 1, - PHASE_2 = 2, - PHASE_3 = 3, - PHASE_EQUIP_NULL = 4, - PHASE_EQUIP_START = 5, - PHASE_EQUIP_PROCESS = 6, - PHASE_EQUIP_END = 7, -}; - -struct MANGOS_DLL_DECL boss_mr_smiteAI : public ScriptedAI -{ - boss_mr_smiteAI(Creature* pCreature) : ScriptedAI(pCreature) { Reset(); } - - uint32 m_uiPhase; - uint32 m_uiEquipTimer; - uint32 m_uiSlamTimer; - - void Reset() - { - m_uiPhase = PHASE_1; - m_uiEquipTimer = 0; - m_uiSlamTimer = 9000; - - DoCastSpellIfCan(m_creature, SPELL_NIBLE_REFLEXES, CAST_TRIGGERED); - - // must assume database has the default equipment set - SetEquipmentSlots(true); - } - - void AttackedBy(Unit* pAttacker) - { - if (m_creature->getVictim()) - return; - - if (m_uiPhase > PHASE_3) - return; - - AttackStart(pAttacker); - } - - void AttackStart(Unit* pWho) - { - if (m_uiPhase > PHASE_3) - return; - - if (m_creature->Attack(pWho, true)) - { - m_creature->AddThreat(pWho); - m_creature->SetInCombatWith(pWho); - pWho->SetInCombatWith(m_creature); - - m_creature->GetMotionMaster()->MoveChase(pWho); - } - } - - void MovementInform(uint32 uiMotionType, uint32 uiPointId) - { - if (uiMotionType != POINT_MOTION_TYPE) - return; - - m_creature->SetSheath(SHEATH_STATE_UNARMED); - m_creature->SetStandState(UNIT_STAND_STATE_KNEEL); - - m_uiEquipTimer = 3000; - m_uiPhase = PHASE_EQUIP_PROCESS; - } - - void PhaseEquipStart() - { - ScriptedInstance* pInstance = (ScriptedInstance*)m_creature->GetInstanceData(); - - if (!pInstance) - return; - - GameObject* pChest = pInstance->GetSingleGameObjectFromStorage(GO_SMITE_CHEST); - - if (!pChest) - return; - - m_uiPhase = PHASE_EQUIP_NULL; - - float fX, fY, fZ; - pChest->GetContactPoint(m_creature, fX, fY, fZ, CONTACT_DISTANCE); - - m_creature->GetMotionMaster()->Clear(); - m_creature->SetFacingToObject(pChest); - m_creature->GetMotionMaster()->MovePoint(0, fX, fY, fZ); - } - - void PhaseEquipProcess() - { - if (m_creature->GetHealthPercent() < 33.0f) - { - // It's Hammer, go Hammer! - SetEquipmentSlots(false, EQUIP_ID_HAMMER, EQUIP_UNEQUIP); - DoCastSpellIfCan(m_creature, SPELL_SMITE_HAMMER); - } - else - SetEquipmentSlots(false, EQUIP_ID_AXE, EQUIP_ID_AXE); - - m_creature->SetStandState(UNIT_STAND_STATE_STAND); - m_uiPhase = PHASE_EQUIP_END; - m_uiEquipTimer = 1000; - - Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0); - - if (!pVictim) - { - EnterEvadeMode(); - return; - } - } - - void PhaseEquipEnd() - { - // We don't have getVictim, so select from threat list - Unit* pVictim = m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 0); - - if (!pVictim) - { - EnterEvadeMode(); - return; - } - - m_creature->SetSheath(SHEATH_STATE_MELEE); - - m_uiPhase = m_creature->GetHealthPercent() < 33.0f ? PHASE_3 : PHASE_2; - - if (m_uiPhase == PHASE_2) - DoCastSpellIfCan(m_creature, SPELL_THRASH, CAST_TRIGGERED); - - AttackStart(pVictim); - } - - void UpdateAI(const uint32 uiDiff) - { - if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) - { - if (m_uiEquipTimer) - { - // decrease the cooldown in between equipment change phases - if (m_uiEquipTimer > uiDiff) - { - m_uiEquipTimer -= uiDiff; - return; - } - else - m_uiEquipTimer = 0; - } - - switch(m_uiPhase) - { - case PHASE_EQUIP_START: - PhaseEquipStart(); - break; - case PHASE_EQUIP_PROCESS: - PhaseEquipProcess(); - break; - case PHASE_EQUIP_END: - PhaseEquipEnd(); - break; - } - - return; - } - - // the normal combat phases - switch(m_uiPhase) - { - case PHASE_1: - { - if (m_creature->GetHealthPercent() < 66.0f) - { - if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK) - { - DoScriptText(SAY_PHASE_2, m_creature); - m_uiPhase = PHASE_EQUIP_START; - m_uiEquipTimer = 2500; - - // will clear getVictim (m_attacking) - m_creature->AttackStop(true); - m_creature->RemoveAurasDueToSpell(SPELL_NIBLE_REFLEXES); - } - return; - } - break; - } - case PHASE_2: - { - if (m_creature->GetHealthPercent() < 33.0f) - { - if (DoCastSpellIfCan(m_creature, SPELL_SMITE_STOMP) == CAST_OK) - { - DoScriptText(SAY_PHASE_3, m_creature); - m_uiPhase = PHASE_EQUIP_START; - m_uiEquipTimer = 2500; - - // will clear getVictim (m_attacking) - m_creature->AttackStop(true); - m_creature->RemoveAurasDueToSpell(SPELL_THRASH); - } - return; - } - break; - } - case PHASE_3: - { - if (m_uiSlamTimer < uiDiff) - { - if (DoCastSpellIfCan(m_creature->getVictim(), SPELL_SMITE_SLAM) == CAST_OK) - m_uiSlamTimer = 11000; - } - else - m_uiSlamTimer -= uiDiff; - - break; - } - } - - DoMeleeAttackIfReady(); - } -}; - -CreatureAI* GetAI_boss_mr_smite(Creature* pCreature) -{ - return new boss_mr_smiteAI(pCreature); -} - bool GOUse_go_door_lever_dm(Player* pPlayer, GameObject* pGo) { ScriptedInstance* pInstance = (ScriptedInstance*)pGo->GetInstanceData(); @@ -302,20 +55,10 @@ bool GOUse_go_defias_cannon(Player* pPlayer, GameObject* pGo) void AddSC_deadmines() { - Script *newscript; - - newscript = new Script; - newscript->Name = "boss_mr_smite"; - newscript->GetAI = &GetAI_boss_mr_smite; - newscript->RegisterSelf(); - - newscript = new Script; - newscript->Name = "go_door_lever_dm"; - newscript->pGOUse = &GOUse_go_door_lever_dm; - newscript->RegisterSelf(); + Script* pNewScript; - newscript = new Script; - newscript->Name = "go_defias_cannon"; - newscript->pGOUse = &GOUse_go_defias_cannon; - newscript->RegisterSelf(); + pNewScript = new Script; + pNewScript->Name = "go_defias_cannon"; + pNewScript->pGOUse = &GOUse_go_defias_cannon; + pNewScript->RegisterSelf(); } diff --git a/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp b/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp index 56aa05f73..2e4ce2838 100644 --- a/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp +++ b/scripts/eastern_kingdoms/molten_core/boss_majordomo_executus.cpp @@ -135,7 +135,6 @@ struct MANGOS_DLL_DECL boss_majordomoAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); m_creature->SetLootRecipient(NULL); // Set friendly diff --git a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp index e39c6901d..09b2e3482 100644 --- a/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp +++ b/scripts/eastern_kingdoms/shadowfang_keep/shadowfang_keep.cpp @@ -374,7 +374,7 @@ struct MANGOS_DLL_DECL mob_arugal_voidwalkerAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); + m_creature->LoadCreatureAddon(true); m_creature->SetLootRecipient(NULL); @@ -888,7 +888,7 @@ struct MANGOS_DLL_DECL npc_deathstalker_vincentAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); + m_creature->LoadCreatureAddon(true); m_creature->SetLootRecipient(NULL); Reset(); } diff --git a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp index 302d924da..e75aaf065 100644 --- a/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp +++ b/scripts/kalimdor/caverns_of_time/hyjal/hyjalAI.cpp @@ -138,7 +138,6 @@ void hyjalAI::EnterEvadeMode() m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); if (m_creature->isAlive()) m_creature->GetMotionMaster()->MoveTargetedHome(); diff --git a/scripts/kalimdor/moonglade.cpp b/scripts/kalimdor/moonglade.cpp index 7f982e884..a28893d32 100644 --- a/scripts/kalimdor/moonglade.cpp +++ b/scripts/kalimdor/moonglade.cpp @@ -825,7 +825,7 @@ struct MANGOS_DLL_DECL boss_eranikusAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); + m_creature->LoadCreatureAddon(true); m_creature->SetLootRecipient(NULL); diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp index 57838d23c..d50f3eb04 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/blood_prince_council.cpp @@ -30,7 +30,7 @@ enum SAY_KELESETH_INVOCATION = -1631103, SAY_KELESETH_SPECIAL = -1631104, SAY_KELESETH_SLAY_1 = -1631105, - SAY_SKELESETH_SLAY_2 = -1631106, + SAY_KELESETH_SLAY_2 = -1631106, SAY_KELESETH_BERSERK = -1631107, SAY_KELESETH_DEATH = -1631108, SAY_TALDARAM_INVOCATION = -1631109, diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp index d0ce13034..30ec25ed7 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/boss_festergut.cpp @@ -36,8 +36,61 @@ enum SAY_BERSERK = -1631089, SAY_DEATH = -1631090, SAY_FESTERGUT_DEATH = -1631091, + + SPELL_BERSERK = 47008, +}; + +struct MANGOS_DLL_DECL boss_festergutAI : public ScriptedAI +{ + boss_festergutAI(Creature* pCreature) : ScriptedAI(pCreature) + { + Reset(); + } + + uint32 m_uiBerserkTimer; + + void Reset() + { + m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS; + } + + void Aggro(Unit* pWho) + { + DoScriptText(SAY_AGGRO, m_creature); + } + + void KilledUnit(Unit* pVictim) + { + DoScriptText(urand(0, 1) ? SAY_SLAY_1 : SAY_SLAY_2, m_creature); + } + + void UpdateAI(const uint32 uiDiff) + { + if (!m_creature->SelectHostileTarget() || !m_creature->getVictim()) + return; + + if (m_uiBerserkTimer < uiDiff) + { + DoCastSpellIfCan(m_creature, SPELL_BERSERK); + DoScriptText(SAY_BERSERK, m_creature); + m_uiBerserkTimer = 5*MINUTE*IN_MILLISECONDS; + } + else + m_uiBerserkTimer -= uiDiff; + } }; +CreatureAI* GetAI_boss_festergut(Creature* pCreature) +{ + return new boss_festergutAI(pCreature); +} + void AddSC_boss_festergut() { + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "boss_festergut"; + pNewScript->GetAI = &GetAI_boss_festergut; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h index b254d65cd..1efe456cc 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/icecrown_citadel.h @@ -1,3 +1,47 @@ /* Copyright (C) 2006 - 2011 ScriptDev2 * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ + + +#ifndef DEF_ICCRAID_H +#define DEF_ICCRAID_H + +enum +{ + MAX_ENCOUNTER = 12, + + TYPE_MARROWGAR = 0, + TYPE_DEATHWHISPER = 1, + TYPE_GUNSHIP = 2, + TYPE_SAURFANG = 3, + TYPE_FESTERGUT = 4, + TYPE_ROTFACE = 5, + TYPE_PUTRICIDE = 6, + TYPE_COUNCIL = 7, + TYPE_BLOOD_QUEEN = 8, + TYPE_VALITHRIA = 9, + TYPE_SINDRAGOSA = 10, + TYPE_LICH_KING = 11, +}; + +class MANGOS_DLL_DECL instance_icecrown_citadel : public ScriptedInstance +{ + public: + instance_icecrown_citadel(Map* pMap); + + void Initialize(); + + bool IsEncounterInProgress() const; + + void SetData(uint32 uiType, uint32 uiData); + uint32 GetData(uint32 uiType); + + const char* Save() { return m_strInstData.c_str(); } + void Load(const char* chrIn); + + private: + uint32 m_auiEncounter[MAX_ENCOUNTER]; + std::string m_strInstData; +}; + +#endif diff --git a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp index dbdb66ef1..1851d2081 100644 --- a/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp +++ b/scripts/northrend/icecrown_citadel/icecrown_citadel/instance_icecrown_citadel.cpp @@ -22,7 +22,109 @@ SDCategory: Icecrown Citadel EndScriptData */ #include "precompiled.h" +#include "icecrown_citadel.h" + +instance_icecrown_citadel::instance_icecrown_citadel(Map* pMap) : ScriptedInstance(pMap) +{ + Initialize(); +} + +void instance_icecrown_citadel::Initialize() +{ + memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); +} + +bool instance_icecrown_citadel::IsEncounterInProgress() const +{ + for (uint8 i = TYPE_MARROWGAR; i <= TYPE_LICH_KING; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + return true; + } + + return false; +} + +void instance_icecrown_citadel::SetData(uint32 uiType, uint32 uiData) +{ + switch (uiType) + { + case TYPE_MARROWGAR: + case TYPE_DEATHWHISPER: + case TYPE_GUNSHIP: + case TYPE_SAURFANG: + case TYPE_FESTERGUT: + case TYPE_ROTFACE: + case TYPE_PUTRICIDE: + case TYPE_COUNCIL: + case TYPE_BLOOD_QUEEN: + case TYPE_VALITHRIA: + case TYPE_SINDRAGOSA: + case TYPE_LICH_KING: + m_auiEncounter[uiType] = uiData; + break; + } + + if (uiData == DONE) + { + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " + << m_auiEncounter[3] << " " << m_auiEncounter[4] << " " << m_auiEncounter[5] << " " + << m_auiEncounter[6] << " " << m_auiEncounter[7] << " " << m_auiEncounter[8] << " " + << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11]; + + m_strInstData = saveStream.str(); + + SaveToDB(); + OUT_SAVE_INST_DATA_COMPLETE; + } +} + +void instance_icecrown_citadel::Load(const char* chrIn) +{ + if (!chrIn) + { + OUT_LOAD_INST_DATA_FAIL; + return; + } + + OUT_LOAD_INST_DATA(chrIn); + + std::istringstream loadStream(chrIn); + loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2] >> m_auiEncounter[3] + >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6] >> m_auiEncounter[7] + >> m_auiEncounter[8] >> m_auiEncounter[9] >> m_auiEncounter[10] >> m_auiEncounter[11]; + + for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) + { + if (m_auiEncounter[i] == IN_PROGRESS) + m_auiEncounter[i] = NOT_STARTED; + } + + OUT_LOAD_INST_DATA_COMPLETE; +} + +uint32 instance_icecrown_citadel::GetData(uint32 uiType) +{ + if (uiType < MAX_ENCOUNTER) + return m_auiEncounter[uiType]; + + return 0; +} + +InstanceData* GetInstanceData_instance_icecrown_citadel(Map* pMap) +{ + return new instance_icecrown_citadel(pMap); +} void AddSC_instance_icecrown_citadel() { + Script* pNewScript; + + pNewScript = new Script; + pNewScript->Name = "instance_icecrown_citadel"; + pNewScript->GetInstanceData = &GetInstanceData_instance_icecrown_citadel; + pNewScript->RegisterSelf(); } diff --git a/scripts/northrend/naxxramas/boss_thaddius.cpp b/scripts/northrend/naxxramas/boss_thaddius.cpp index 2ec1a316c..4f08913e9 100644 --- a/scripts/northrend/naxxramas/boss_thaddius.cpp +++ b/scripts/northrend/naxxramas/boss_thaddius.cpp @@ -118,6 +118,8 @@ struct MANGOS_DLL_DECL boss_thaddiusAI : public Scripted_NoMovementAI m_uiChainLightningTimer = 8*IN_MILLISECONDS; m_uiBallLightningTimer = 1*IN_MILLISECONDS; m_uiBerserkTimer = 6*MINUTE*IN_MILLISECONDS; + + m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } void Aggro(Unit* pWho) @@ -133,7 +135,7 @@ struct MANGOS_DLL_DECL boss_thaddiusAI : public Scripted_NoMovementAI m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } - void EnterEvadeMode() + void JustReachedHome() { if (m_pInstance) { @@ -153,23 +155,6 @@ struct MANGOS_DLL_DECL boss_thaddiusAI : public Scripted_NoMovementAI pStalagg->Respawn(); } } - - // Reset - m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - - // Delay reloading of CreatureAddon until Reached home for proper handling - // Also note that m_creature->LoadCreatureAddon(); must _not_ be called before m_creature->GetMotionMaster()->MoveTargetedHome(); - // Done this way, because MoveTargetHome ensures proper positioning (orientation) - m_creature->RemoveAllAuras(); - m_creature->DeleteThreatList(); - m_creature->CombatStop(true); - - if (m_creature->isAlive()) - m_creature->GetMotionMaster()->MoveTargetedHome(); - - m_creature->SetLootRecipient(NULL); - - Reset(); } void KilledUnit(Unit* pVictim) diff --git a/scripts/northrend/nexus/oculus/boss_eregos.cpp b/scripts/northrend/nexus/oculus/boss_eregos.cpp new file mode 100644 index 000000000..47c879394 --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_eregos.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2012 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: boss_eregos +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_eregos() +{ +} diff --git a/scripts/northrend/nexus/oculus/boss_urom.cpp b/scripts/northrend/nexus/oculus/boss_urom.cpp new file mode 100644 index 000000000..9fdb91b75 --- /dev/null +++ b/scripts/northrend/nexus/oculus/boss_urom.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2012 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: boss_urom +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" + +void AddSC_boss_urom() +{ +} diff --git a/scripts/northrend/nexus/oculus/instance_oculus.cpp b/scripts/northrend/nexus/oculus/instance_oculus.cpp new file mode 100644 index 000000000..e8659606e --- /dev/null +++ b/scripts/northrend/nexus/oculus/instance_oculus.cpp @@ -0,0 +1,28 @@ +/* Copyright (C) 2006 - 2012 ScriptDev2 + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* ScriptData +SDName: instance_oculus +SD%Complete: 0 +SDComment: Placeholder +SDCategory: Oculus +EndScriptData */ + +#include "precompiled.h" + +void AddSC_instance_oculus() +{ +} diff --git a/scripts/northrend/nexus/oculus/oculus.h b/scripts/northrend/nexus/oculus/oculus.h new file mode 100644 index 000000000..5871a49a1 --- /dev/null +++ b/scripts/northrend/nexus/oculus/oculus.h @@ -0,0 +1,3 @@ +/* Copyright (C) 2006 - 2012 ScriptDev2 + * This program is free software licensed under GPL version 2 + * Please see the included DOCS/LICENSE.TXT for more information */ diff --git a/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp b/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp index 096de3448..ddbdb8a0b 100644 --- a/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp +++ b/scripts/outland/hellfire_citadel/blood_furnace/boss_broggok.cpp @@ -90,7 +90,7 @@ struct MANGOS_DLL_DECL boss_broggokAI : public ScriptedAI m_creature->RemoveAllAuras(); m_creature->DeleteThreatList(); m_creature->CombatStop(true); - m_creature->LoadCreatureAddon(); + m_creature->LoadCreatureAddon(true); m_creature->SetLootRecipient(NULL); diff --git a/sql/mangos_scriptname_full.sql b/sql/mangos_scriptname_full.sql index 8d95c69f5..45cda1cf6 100644 --- a/sql/mangos_scriptname_full.sql +++ b/sql/mangos_scriptname_full.sql @@ -707,11 +707,15 @@ UPDATE creature_template SET ScriptName='npc_silvermoon_harry' WHERE entry=24539 /* ICECROWN CITADEL */ /* */ +/* ICECROWN CITADEL */ +UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626; +UPDATE instance_template SET ScriptName='instance_icecrown_citadel' WHERE map=631; + /* FORGE OF SOULS */ +UPDATE instance_template SET ScriptName='instance_forge_of_souls' WHERE map=632; UPDATE creature_template SET ScriptName='boss_bronjahm' WHERE entry=36497; UPDATE creature_template SET ScriptName='npc_corrupted_soul_fragment' WHERE entry=36535; UPDATE creature_template SET ScriptName='boss_devourer_of_souls' WHERE entry=36502; -UPDATE instance_template SET ScriptName='instance_forge_of_souls' WHERE map=632; /* HALLS OF REFLECTION */ diff --git a/sql/scriptdev2_script_full.sql b/sql/scriptdev2_script_full.sql index afa7819ec..9cfc8f625 100644 --- a/sql/scriptdev2_script_full.sql +++ b/sql/scriptdev2_script_full.sql @@ -791,8 +791,8 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen -- -1 036 000 DEADMINES INSERT INTO script_texts (entry,content_default,sound,type,language,emote,comment) VALUES -(-1036000,'You there, check out that noise.',5775,6,7,0,'smite INST_SAY_ALARM1'), -(-1036001,'We\'re under attack! A vast, ye swabs! Repel the invaders!',5777,6,7,0,'smite INST_SAY_ALARM2'), +(-1036000,'You there! Check out that noise.',5775,6,7,0,'smite INST_SAY_ALARM1'), +(-1036001,'We\'re under attack! A vast, ye swabs! Repel the invaders!',5777,6,7,0,'smite INST_SAY_ALARM2'), (-1036002,'You land lubbers are tougher than I thought! I\'ll have to improvise!',5778,0,0,21,'smite SAY_PHASE_2'), (-1036003,'D\'ah! Now you\'re making me angry!',5779,0,0,15,'smite SAY_PHASE_3'); @@ -3534,7 +3534,7 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,commen (-1631103,'Such wondrous power! The Darkfallen Orb has made me INVINCIBLE!',16727,1,0,0,'keleseth SAY_KELESETH_INVOCATION'), (-1631104,'Blood will flow!',16728,1,0,0,'keleseth SAY_KELESETH_SPECIAL'), (-1631105,'Were you ever a threat?',16723,1,0,0,'keleseth SAY_KELESETH_SLAY_1'), -(-1631106,'Truth is found in death.',16724,1,0,0,'keleseth SAY_SKELESETH_SLAY_2'), +(-1631106,'Truth is found in death.',16724,1,0,0,'keleseth SAY_KELESETH_SLAY_2'), (-1631107,'%s cackles maniacally!',16726,2,0,0,'keleseth SAY_KELESETH_BERSERK'), -- TODO Can be wrong (-1631108,'My queen... they come...',16725,1,0,0,'keleseth SAY_KELESETH_DEATH'), diff --git a/sql/updates/r2321_scriptdev2.sql b/sql/updates/r2321_scriptdev2.sql new file mode 100644 index 000000000..884319617 --- /dev/null +++ b/sql/updates/r2321_scriptdev2.sql @@ -0,0 +1,2 @@ +UPDATE script_texts SET content_default='You there! Check out that noise.' WHERE entry=-1036000; +UPDATE script_texts SET content_default='We\'re under attack! A vast, ye swabs! Repel the invaders!' WHERE entry=-1036001; diff --git a/sql/updates/r8800_mangos.sql b/sql/updates/r8800_mangos.sql new file mode 100644 index 000000000..262da6df8 --- /dev/null +++ b/sql/updates/r8800_mangos.sql @@ -0,0 +1 @@ +UPDATE creature_template SET ScriptName='boss_festergut' WHERE entry=36626; diff --git a/sql/updates/r8801_mangos.sql b/sql/updates/r8801_mangos.sql new file mode 100644 index 000000000..2a166591e --- /dev/null +++ b/sql/updates/r8801_mangos.sql @@ -0,0 +1 @@ +UPDATE instance_template SET ScriptName='instance_icecrown_citadel' WHERE map=631; diff --git a/system/ScriptLoader.cpp b/system/ScriptLoader.cpp index eb2ca2537..5798811bd 100644 --- a/system/ScriptLoader.cpp +++ b/system/ScriptLoader.cpp @@ -63,7 +63,8 @@ extern void AddSC_boss_chromaggus(); extern void AddSC_boss_nefarian(); extern void AddSC_boss_victor_nefarius(); extern void AddSC_instance_blackwing_lair(); -extern void AddSC_deadmines(); // deadmines +extern void AddSC_boss_mr_smite(); // deadmines +extern void AddSC_deadmines(); extern void AddSC_instance_deadmines(); extern void AddSC_gnomeregan(); // gnomeregan extern void AddSC_boss_thermaplugg(); @@ -347,6 +348,9 @@ extern void AddSC_boss_keristrasza(); extern void AddSC_boss_ormorok(); extern void AddSC_boss_telestra(); extern void AddSC_instance_nexus(); +extern void AddSC_boss_eregos(); // nexus, oculus +extern void AddSC_boss_urom(); +extern void AddSC_instance_oculus(); extern void AddSC_boss_sartharion(); // obsidian_sanctum extern void AddSC_instance_obsidian_sanctum(); extern void AddSC_boss_baltharus(); // ruby_sanctum @@ -837,6 +841,9 @@ void AddScripts() AddSC_boss_ormorok(); AddSC_boss_telestra(); AddSC_instance_nexus(); + AddSC_boss_eregos(); // nexus, oculus + AddSC_boss_urom(); + AddSC_instance_oculus(); AddSC_boss_sartharion(); // obsidian_sanctum AddSC_instance_obsidian_sanctum(); AddSC_boss_baltharus(); // ruby_sanctum