Sfoglia il codice sorgente

增加了Sequence和Selector节点

tanghai 14 anni fa
parent
commit
5ac988604c

+ 4 - 0
Cpp/Game/Event/BuffType.cc

@@ -9,6 +9,10 @@ BuffType::BuffType(int buff_type): buff_type(buff_type)
 {
 }
 
+BuffType::~BuffType()
+{
+}
+
 bool BuffType::Run(ContexIf* contex)
 {
 	Buff* buff = contex->GetBuff();

+ 2 - 0
Cpp/Game/Event/BuffType.h

@@ -18,6 +18,8 @@ private:
 public:
 	BuffType(int buff_type);
 
+	virtual ~BuffType();
+
 	virtual bool Run(ContexIf* contex);
 
 	virtual std::string ToString();

+ 3 - 1
Cpp/Game/Event/CMakeLists.txt

@@ -1,4 +1,4 @@
-PROTOBUF_GENERATE_CPP(proto_srcs proto_hdrs 
+PROTOBUF_GENERATE_CPP(proto_srcs proto_hdrs
 	EventConf.proto
 )
 
@@ -12,6 +12,8 @@ SET(EventSrc
 	NodeFactories.cc
 	NotNode.cc
 	OrNode.cc
+	SelectorNode.cc
+	SequenceNode.cc
 	${proto_srcs}
 )
 

+ 1 - 1
Cpp/Game/Event/ChangeHealth.cc

@@ -29,7 +29,7 @@ bool ChangeHealth::Run(ContexIf *contex)
 		target = spell->victim;
 	}
 
-	target->health -= value;
+	target->health += value;
 
 	return true;
 }

+ 0 - 30
Cpp/Game/Event/Defines.proto

@@ -1,30 +0,0 @@
-package Egametang
-
-enum EventType
-{
-	ON_SPELL_START     = 0,
-	ON_SPELL_FINISH    = 1,
-	ON_ADD_BUFF        = 2,
-	ON_REMOVE_BUFF     = 3,
-	ON_HIT             = 4,
-	ON_HITTED          = 5,
-};
-
-enum NodeType
-{
-	AND = 0;
-	OR = 1;
-	NOT = 2;
-
-	// 条件子节点100 - 1001
-	BUFF_TYPE = 100;
-
-	// 行为节点
-	CHANGE_HEALTH = 1001
-};
-
-enum SpellUnit
-{
-	CASTER = 0;
-	VICTIM = 1;
-};

+ 0 - 18
Cpp/Game/Event/DotFirstDamage.txt

@@ -1,18 +0,0 @@
-type: 5
-condition:
-{
-	node:
-	{
-		type: 101
-		args: 2
-	}
-}
-action:
-{
-	node: 
-	{
-		type: 1001
-		args: 1
-		args: 100
-	}
-}

+ 2 - 2
Cpp/Game/Event/Event.cc

@@ -33,9 +33,9 @@ void Event::BuildTree(
 {
 	int32 type = conf.type();
 	node = factories.GetInstance(conf);
-	for (int i = 0; i < conf.nodes_size(); ++i)
+	for (int i = 0; i < conf.node_size(); ++i)
 	{
-		const EventNode& logic_node_conf = conf.nodes(i);
+		const EventNode& logic_node_conf = conf.node(i);
 		NodeIf* logic_node = NULL;
 		BuildTree(factories, logic_node_conf, logic_node);
 		node->AddChildNode(logic_node);

+ 1 - 1
Cpp/Game/Event/EventConf.proto

@@ -6,7 +6,7 @@ message EventNode
 	// 条件需要的参数
 	repeated int32 args = 3;
 	// 包含多个子节点
-	repeated EventNode nodes = 4;
+	repeated EventNode node = 4;
 };
 
 message ConditionConf

+ 36 - 0
Cpp/Game/Event/EventDefine.h

@@ -0,0 +1,36 @@
+#ifndef EVENT_EVENTDEFINE_H
+#define EVENT_EVENTDEFINE_H
+
+enum EventType
+{
+	ON_SPELL_START     = 0,
+	ON_SPELL_FINISH    = 1,
+	ON_ADD_BUFF        = 2,
+	ON_REMOVE_BUFF     = 3,
+	ON_HITTED          = 4,
+	ON_HIT             = 5,
+};
+
+enum NodeType
+{
+	AND                = 0,
+	OR                 = 1,
+	NOT                = 2,
+
+	SEQUENCE           = 6,
+	SELECTOR           = 7,
+
+	// 条件子节点100 - 1001
+	BUFF_TYPE          = 101,
+
+	// 动作子节点
+	CHANGE_HEALTH      = 1001,
+};
+
+enum SpellUnit
+{
+	CASTER = 0,
+	VICTIM = 1,
+};
+
+#endif // EVENT_EVENTDEFINE_H

+ 1 - 0
Cpp/Game/Event/GameEvents.cc

@@ -36,6 +36,7 @@ void GameEvents::Excute(int type, ContexIf* contex)
 
 	for (std::list<Event*>::iterator iter = es.begin(); iter != es.end(); ++iter)
 	{
+		CHECK(*iter);
 		(*iter)->Run(contex);
 	}
 }

+ 7 - 4
Cpp/Game/Event/GameEventsTest.cc

@@ -9,6 +9,7 @@
 #include "Event/EventConf.pb.h"
 #include "Event/SpellBuff.h"
 #include "Event/CombatContex.h"
+#include "Event/EventDefine.h"
 
 namespace Egametang {
 
@@ -39,7 +40,7 @@ static void FileToString(const std::string& file, std::string& string)
 
 TEST_F(GameEventsTest, DotChangeHealth)
 {
-	std::string file = "../Cpp/Game/Event/DotFirstDamage.txt";
+	std::string file = "../Cpp/Game/Event/Vampire.txt";
 	std::string string;
 	FileToString(file, string);
 	EventConf conf;
@@ -48,7 +49,7 @@ TEST_F(GameEventsTest, DotChangeHealth)
 
 	Unit caster;
 	Unit victim;
-	caster.health = 1000;
+	caster.health = 2000;
 	victim.health = 2000;
 	Spell spell;
 	Buff buff;
@@ -56,11 +57,13 @@ TEST_F(GameEventsTest, DotChangeHealth)
 	spell.victim = &victim;
 	CombatContex contex(&spell, &buff);
 
-	game_events.Excute(5, &contex);
+	game_events.Excute(ON_HIT, &contex);
+	ASSERT_EQ(2000, caster.health);
 	ASSERT_EQ(2000, victim.health);
 
 	buff.buff_type = 2;
-	game_events.Excute(5, &contex);
+	game_events.Excute(ON_HIT, &contex);
+	ASSERT_EQ(2100, caster.health);
 	ASSERT_EQ(1900, victim.health);
 }
 

+ 15 - 7
Cpp/Game/Event/NodeFactories.cc

@@ -3,24 +3,32 @@
 #include "Event/AndNode.h"
 #include "Event/OrNode.h"
 #include "Event/NotNode.h"
+#include "Event/SequenceNode.h"
+#include "Event/SelectorNode.h"
 #include "Event/BuffType.h"
 #include "Event/ChangeHealth.h"
 #include "Event/NodeFactories.h"
 #include "Event/EventConf.pb.h"
+#include "Event/EventDefine.h"
 
 namespace Egametang {
 
 NodeFactories::NodeFactories(): factories(2000, NULL)
 {
-	factories[0] = new AndNodeFactory();
-	factories[1] = new OrNodeFactory();
-	factories[2] = new NotNodeFactory();
-
 	// 条件节点
-	factories[101] = new BuffTypeFactory();
+	factories[AND] = new AndNodeFactory();
+	factories[OR] = new OrNodeFactory();
+	factories[NOT] = new NotNodeFactory();
+
+	// 动作节点
+	factories[SEQUENCE] = new SequenceNodeFactory();
+	factories[SELECTOR] = new SelectorNodeFactory();
+
+	// 条件叶子节点
+	factories[BUFF_TYPE] = new BuffTypeFactory();
 
-	// 行为节点
-	factories[1001] = new ChangeHealthFactory();
+	// 动作叶子节点
+	factories[CHANGE_HEALTH] = new ChangeHealthFactory();
 }
 
 NodeFactories::~NodeFactories()

+ 3 - 0
Cpp/Game/Event/NodeIf.h

@@ -11,6 +11,9 @@ class EventNode;
 class NodeIf
 {
 public:
+	virtual ~NodeIf()
+	{
+	}
 	virtual bool Run(ContexIf* contex) = 0;
 
 	virtual void AddChildNode(NodeIf *node)

+ 49 - 0
Cpp/Game/Event/SelectorNode.cc

@@ -0,0 +1,49 @@
+#include <boost/foreach.hpp>
+#include "Base/Marcos.h"
+#include "Event/SelectorNode.h"
+
+namespace Egametang {
+
+SelectorNode::~SelectorNode()
+{
+	foreach(NodeIf* node, nodes)
+	{
+		delete node;
+	}
+}
+
+bool SelectorNode::Run(ContexIf* contex)
+{
+	foreach(NodeIf* node, nodes)
+	{
+		if (node->Run(contex))
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+void SelectorNode::AddChildNode(NodeIf *node)
+{
+	nodes.push_back(node);
+}
+
+std::string SelectorNode::ToString()
+{
+	std::string s;
+	s += "SelectorNode: \n";
+	foreach(NodeIf* node, nodes)
+	{
+		s += "    " + node->ToString() + "\n";
+	}
+	return s;
+}
+
+NodeIf* SelectorNodeFactory::GetInstance(const EventNode& conf)
+{
+	return new SelectorNode();
+}
+
+} // namespace Egametang
+

+ 33 - 0
Cpp/Game/Event/SelectorNode.h

@@ -0,0 +1,33 @@
+#ifndef EVENT_SELECTORNODE_H
+#define EVENT_SELECTORNODE_H
+
+#include <list>
+#include "Event/NodeIf.h"
+
+namespace Egametang {
+
+class SelectorNode: public NodeIf
+{
+private:
+	std::list<NodeIf*> nodes;
+
+public:
+	virtual ~SelectorNode();
+
+	virtual bool Run(ContexIf* contex);
+
+	virtual void AddChildNode(NodeIf *node);
+
+	virtual std::string ToString();
+};
+
+class SelectorNodeFactory: public NodeFactoryIf
+{
+public:
+	virtual NodeIf* GetInstance(const EventNode& conf);
+};
+
+} // namespace Egametang
+
+
+#endif // EVENT_SELECTORNODE_H

+ 50 - 0
Cpp/Game/Event/SequenceNode.cc

@@ -0,0 +1,50 @@
+#include <glog/logging.h>
+#include <boost/foreach.hpp>
+#include "Base/Marcos.h"
+#include "Event/SequenceNode.h"
+
+namespace Egametang {
+
+SequenceNode::~SequenceNode()
+{
+	foreach(NodeIf* node, nodes)
+	{
+		delete node;
+	}
+}
+
+bool SequenceNode::Run(ContexIf* contex)
+{
+	foreach(NodeIf* node, nodes)
+	{
+		if (!node->Run(contex))
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+void SequenceNode::AddChildNode(NodeIf *node)
+{
+	nodes.push_back(node);
+}
+
+std::string SequenceNode::ToString()
+{
+	std::string s;
+	s += "SequenceNode: \n";
+	foreach(NodeIf* node, nodes)
+	{
+		s += "    " + node->ToString() + "\n";
+	}
+	return s;
+}
+
+NodeIf* SequenceNodeFactory::GetInstance(const EventNode& conf)
+{
+	return new SequenceNode();
+}
+
+} // namespace Egametang
+

+ 33 - 0
Cpp/Game/Event/SequenceNode.h

@@ -0,0 +1,33 @@
+#ifndef EVENT_SEQUENCENODE_H
+#define EVENT_SEQUENCENODE_H
+
+#include <list>
+#include "Event/NodeIf.h"
+
+namespace Egametang {
+
+class SequenceNode: public NodeIf
+{
+private:
+	std::list<NodeIf*> nodes;
+
+public:
+	virtual ~SequenceNode();
+
+	virtual bool Run(ContexIf* contex);
+
+	virtual void AddChildNode(NodeIf *node);
+
+	virtual std::string ToString();
+};
+
+class SequenceNodeFactory: public NodeFactoryIf
+{
+public:
+	virtual NodeIf* GetInstance(const EventNode& conf);
+};
+
+} // namespace Egametang
+
+
+#endif // EVENT_SEQUENCENODE_H

+ 28 - 0
Cpp/Game/Event/Vampire.txt

@@ -0,0 +1,28 @@
+type: 5
+condition:
+{
+	node:
+	{
+		type: 101
+		args: 2
+	}
+}
+action:
+{
+	node:
+	{
+		type: 6
+		node: 
+		{
+			type: 1001
+			args: 0
+			args: 100
+		}
+		node:
+		{
+			type: 1001
+			args: 1
+			args: -100
+		}
+	}
+}