[C++] Boss Timer

Guten Tag @ALL!

Da ich im Momment nicht mit den Flugpunkten weiterkomme, habe ich mir zur Abwechslung mal überlegt ein Boss Script zu schreiben. Da ich das ja noch nicht gut kann und am lernen bin, stoße ich nun auf Hürden.

Hier mal mein bisheriges Script


#include "ScriptPCH.h"


// Was der Boss so alles sagen soll!

#define SAY_BATTLE_START	"Endlich frisches Fleisch..."

#define SAY_WIN_PLAYER		"Diese Runde geht an dich... ich werde wieder auferstehen!"

#define SAY_YOU_LOOSE		"Mehr habt ihr nicht drauf? Ihr seid nicht meiner würdig!"


// Zauber die der Boss wirken soll!

enum Spells

{

	SPELL_SHIELD	=	61570,

	SPELL_BLITZ	=	36915

};


// Hier die Hauptklasse des Bosses.

class boss_meiner : public CreatureScript

{

public:

	boss_meiner() : CreatureScript("boss_meiner") { }


	// Hier wird eine neue AI (Virtuelle Intelligenz) erstelle.

	CreatureAI* GetAI(Creature* pCreature) const

	{

		return new boss_meinerAI( pCreature );

	}


	struct boss_meinerAI : public ScriptedAI

	{

		boss_meinerAI( Creature *c ) : ScriptedAI(c) { }


		// Wenn der Boss in den Kampf geht, dann wird

		// hier die Funktion ausgeführt!

		void EnterCombat( Unit* /*who*/ )

		{

			// Kampf Einleitungstext

			me->MonsterYell( SAY_BATTLE_START, 0, 0 );

		}


		// Wenn der Boss stirbt!

		void JustDied( Unit* )

		{

			// Kampf Gewinner Text

			me->MonsterYell( SAY_WIN_PLAYER, 0, 0 );

		}


		// Wenn der Spieler stirbt!

		void KilledUnit( Unit* /*victim*/)

		{

			// Kampf verlohren Text

			me->MonsterYell( SAY_YOU_LOOSE, 0, 0 );

		}


		// Der Kampfverlauf

		void UpdateAI( const uint32 diff )

		{

			uint32 meinshild = 0;

			uint32 phase = 0;


			// Ist UpdateVictim gesetzt?

			// Wenn nicht, dann abbruch!

			if ( !UpdateVictim() )

				return;


			// Gesundheit über 75% dann

			if ( HealthAbovePct(75) || meinshild == 0 && !HealthAbovePct(25) )

			{

				// Nutze Blitzschlagschild

				DoCast(me->getVictim(), SPELL_SHIELD );

				meinshild++;

			}

			// Gesundheit unter 25% dann soll er Zaubern!

			// Phase 1 vom Enrage

			if ( HealthBelowPct(25) && phase == 0 )

			{

				// DMG Zauber!

				DoCast(me->getVictim(), SPELL_BLITZ );

				meinshild = 0;

				phase++;

			}


			// Phase 1 vom Enrage

			if ( HealthBelowPct(15) && phase == 1 )

			{

				// DMG Zauber!

				DoCast(me->getVictim(), SPELL_BLITZ );

				meinshild = 0;

				phase++;

			}


			// Phase 1 vom Enrage

			if ( HealthBelowPct(5) && phase == 2 )

			{

				// DMG Zauber!

				DoCast(me->getVictim(), SPELL_BLITZ );

				meinshild = 0;

				phase++;

			}


			DoMeleeAttackIfReady();

		}

	};

};


// Script Adden

void AddSC_boss_meiner()

{

	new boss_meiner();

}

Ich habe versucht mit Variablen sowas wie Phasen zu bauen. Aber leider Castet der Constant.

Also Zauber eins, ist ein Blizschlagschild das er sich geben soll. Das castet der fast unendlich! Genauso soll er ab 25% leben 1x einen Blizschock casten. Das macht der aber als hintereinander.

Nun zu meiner Frage: “Wie kann ich einen guten Timer einbauen?”.

Es sollte bitte Anfänger freundlich sein^^.

PS: Ich kenne durch andere Scripte sowas wie HealthAbovePct() und HealtBelowPct(). Gibt es auch eines was Healt GLEICH Pct oder sowas? /emoticons/default_biggrin.png

Liebe grüße aus Kassler Raum

Yellow

Schau mal hier.

Habs selbst noch nicht getestet, werde es aber tun^^

Ich versuch mich auch mal an nem Custom Script.

Gruß Pig

Danke erstmal PigPriest!

Ansich ein tolltes Tutorial… doch leider habe ich dann doch noch fragen dazu^^

Was genau ist der Inhalt von diff bsw uiDiff? /emoticons/default_blink.png

Zeitdifferenz in Millisekunden seit dem letzten Aufruf der Funktion (bzw. dem letzten Tick).

Damit kannst du dir dann Timer bauen… Einfach uiDiff von deinem Timer abziehen, bis dieser <= 0 ist. Dann ist die vom Timer definierte Zeit rum und du kannst deinen Code ausführen lassen. Danach setzt du den Timer wieder hoch

Super danke… ich denke und hoffe das mir das reichen wird^^.

Davon ab ist da aus Programmiertechnischer Hinsicht ein Fehler. Schau dir das mal genau an:

if ( HealthAbovePct(75) || meinshild == 0 && !HealthAbovePct(25) )

Da steht, wenn Lebn über 75% oder (mein Schild == 0 und Leben über 25%)

Die Bedingung über 75% reicht schon aus, um das if zu erfüllen, wodurch er eben von Anfang an einfach mal durchcastet und das zu jedem MapUpadte, was nen ziemlicher Spam sein dürfte. Solche Dinge müsstest du als aller erstes mal ausmerzen. Ansonsten wie gesagt mit Milliseks Timer arbeiten. Ganz einfach so:


uint32 timer;


void Reset()

{

	uint32 timer = 10000; // für 10 Sekunden

}


void UpdateAI(uint32 uiDiff)

{

	if (timer < uiDiff)

	{

    	me->CastSpell(me, SPELLID, true); // oder anders, je nachdem, was gezaubert oder gemacht werden soll

    	timer = 5000; // timer wieder neu setzen

	}

	else

    	timer -= uiDiff;

}

Das war schon der ganze Spaß.

das ist sehr schön einfach erklärt /emoticons/default_smile.png Danke… doch was genau macht noch

time -= uiDiff

In deinem Beispiel sind 10 Sec als Start Schwinger. Dann 5 Sekunden bei Ausführung aber was genau bewirkt dieses else time -= uiDiff? /emoticons/default_mellow.png

EDIT: Omg jetzt wo ich es gepostet habe, ist der Groschen gefallen^^. Timer - differenz . Und wenn das sooft gemacht wurde bis 0 erreicht wurde, dann Zaubert er^^ ok /emoticons/default_smile.png

Aber du nutzt zum Zaubern


me->CastSpell(me, SPELLID, true);

Ist die besser als

DoCast(me->getVictim(), SPELL_SHIELD );

Und das Zaubert auf mich, was muß statt me drinnen stehen um auf den Boss selber zu casten? Heilung zum beispiel? Habe das mal getestet… da heilte der mich^^

Das war wie immer einfach ausm Kopf. DoCast ist besser, ja. Der erste Übergabeparameter ist das Target und dieses wiederum ein Pointer auf eine Unit. me represnetiert hier ja den Boss und das ist ebenso ein Pointer auf Unit. Also einfach DoCast(me, SPELLID);

herzlichen dank… hatte es mit einem pointer auf c versucht aber ging leider nicht ! ^^

Hab zwar keine Ahnung, was du meinst, aber schön, dass du es nun verstanden hast.

Hehe ich wollte ja auf die Creature Casten lassen also versuchte ich

[CODE]boss_meinerAI( Creature *c ) : ScriptedAI(c) { }

DoCast(c, SPELL_HEAL); // so versuchte ich es [/code][/CODE]

was natürlich nicht geht wenn der *p auf me liegt /emoticons/default_biggrin.png

DoCast(me, SPELL_ID);

Na Gott sei dank, hast du das endlich mal aufgeklärt. Seit 3 Monaten warten wir nun schon auf eine Lösung. Ich liege dir zu Füßen. Bist mein Held des Tages!

^^