View Single Post
  #14  
Old 03-26-2002, 04:38 PM
Malevolent
Hill Giant
 
Join Date: Mar 2002
Posts: 171
Default

I decided against using an integer to represent what kind of thing a mob is (meat/vegie, etc.) and so settled on using boolean on whether

1. do you eat meat T/F
2. do you eat vegies T/F

Which pretty much get the vast majority of cases I could think of and since they're in the struct, it wouldn't take much to expand it later.

There was also the issue of expressing whether a mob is a meat or is a vegie.

1. i am meat T/F
2. i am vegie T/F

Same kind of thing, as described above, is happening here.

before I sat down to code this, the integer idea seemed like the way to go. Then i started looking at the chaos I'd have to deal with and decided some boolean checks would get the job done and be easier to put in place. And, as a bonus, might conserve on resources more than a sint8 (or whatever).

If my theory holds true, these simpler pieces, when and once assembled, will create a nifty illusion. Still a little while to go though

todo/notes:

mobs have properties of animalinstincts, but not methods like npcs

if the player doesn't have a target selected, then the npc can't eat (so if a player unselects target before death, then npc can't feast on body)
::Starve() needs done (just reverse of Eat but w/o having to do -'s)
need to think about what kind of benefits should fall onto a mob for having good health. For example, maybe if you aren't hungry then your stun timer doesn't last as long. And if you are hungry, then it lasts longer.

Phase 3 will consist of a few things that I pushed aside in p2. Namely, messing around with players giving npcs items and having that translate to food for the npc. Note to self: OP_Click_Give.

Anyhow, here's the bulk of phase 2 (I expect to amend this later), which is more proof of concept groundwork:

Code:
npc.h 

//malevolent
struct strctAnimalInstincts
{
	sint8 Hunger;	// -100<x<100 : 0 equilibrium [threshold]
	
	bool Meat;	  //do you eat meat?
	bool Vegetables; //do you eat vegetables?
};

class:

	//*****************************************************************//
	//Animal instincts: Hunger

	void Eat(int HowMuchFood); //malevolent: eat
	void Starve(int FastAmount);//malevolent: start
	int GetHungerStatus() { return AnimalInstincts->Hunger;}
	bool IsHungry(); //malevolent: checks to see if the npc is hungry


	//*****************************************************************//

Protected:
	//Malevolent: Animal Instincts
	strctAnimalInstincts* AnimalInstincts;


npc.cpp


//malevolent:: is the critter hungry? returns the int value representing their hunger
bool NPC::IsHungry()
{
	if (this->AnimalInstincts->Hunger >= 0) 
		return false;
		else
		return true;
}

//This should fire after npc has eaten
void NPC::Eat(int amount)
{
	strctAnimalInstincts* instincts=new strctAnimalInstincts;	
	instincts->Hunger=this->AnimalInstincts->Hunger + amount;

	//bounds checks

	//max
	if (instincts->Hunger >100)
		instincts->Hunger =100;

	//min
	if (instincts->Hunger <-100)
		instincts->Hunger =-100;

	//now assign
	this->AnimalInstincts=instincts;

}

mob.h

public:
	//*****************************************
	//malevolent
	bool IsMeat(){return foodtype->IsMeat;}
	bool IsVegie(){return foodtype->IsVegie;}
	//*******************************************

protected:
	//malevolent:
	FoodType* foodtype; //what kind of food am i? 

//Malevolent animal instincts
struct FoodType {
	bool IsMeat;	//is a meat-based mob
	bool IsVegie;	//is a vegie-based mob
};

mob.cpp

in constructor:
	//malevolent
	FoodType* ft = new FoodType;
	ft->IsMeat=true;
	ft->IsVegie=false;
	this->foodtype=ft;

client.cpp

		//Malevolent
		//hunger look up on target NPC
		else if (strcasecmp(sep.arg[0], "#Hungry") == 0)
		{
			
			if (target != 0 && target->IsNPC())
			{
				Message(0,"Asking target if they are hungry..");

				switch(target->CastToNPC()->IsHungry())
				{
				case false: 
					Message(0,"Hungry!");
					break;
				case true:
					Message(0,"Not hungry.");
					break;
				default:
					Message(0, "Does not eat.");
					break;
				}

				
			}
		}
		//Malevolent
		//ForceFeed the NPC
		else if (strcasecmp(sep.arg[0], "#ForceFeed") == 0)
		{
			
			if (target != 0 && target->IsNPC())
			{
				target->CastToNPC()->Eat(atoi(sep.arg[1]));
				Message(0,"Fed: %i",atoi(sep.arg[1]));				
			}
		}
		//Malevolent
		//Lookup the NPC's instinct values
		else if (strcasecmp(sep.arg[0], "#HungerThreshold") == 0)
		{
			
			if (target != 0 && target->IsNPC())
			{
				
				Message(0,"Hunger Value: %i",target->CastToNPC()->GetHungerStatus());				
			}
		}

		//Malevolent
		//Check to see if the npc can eat the user
		else if (strcasecmp(sep.arg[0], "#CanYouEatMe") == 0)
		{
			if (target !=0 && (target->IsNPC() || target->IsMob()) )
			{
				if(target->CastToNPC()->CanIEatYou(this->CastToMob()))
				{
					Message(0, "Yum, yum! I can eat you..");

					if(target->CastToNPC()->IsHungry())
						Message(0, "I'm going to eat you!");
					else
						Message(0, "I'm fine and full. I won't eat you.");

				}
				
			}
			 else  
			{
				Message(0, "You really think that such a thing could eat?");
			}
		
			 
		}

		//Malevolent
		//Check on whether they are meat or vegie
		else if (strcasecmp(sep.arg[0], "#voretype") == 0)
		{
			if (target !=0 && (target->IsNPC() || target->IsMob()) )
			{
				if(target->IsMeat())
					Message(0,"I'm meat.");
				else
					Message(0,"I'm not meat. Move along.");

				if(target->IsVegie())
					Message(0,"I'm vegie.");			
				else
					Message(0,"I'm not a vegie. You really think I'm green?");
			}
		
			 
		}

		//Malevolent
		//Check to see if the npc can eat the user
		else if (strcasecmp(sep.arg[0], "#EatMe") == 0)
		{
			if (target !=0 && (target->IsNPC()))
			{
				if(target->CastToNPC()->CanIEatYou(this->CastToMob()))
				{
					Message(0, "mmmm..foood");

					if(target->CastToNPC()->IsHungry())
					{
						Message(0, "I'm going to eat you!");
						target->CastToNPC()->AddToHateList(this,100); //be sure to *stick* to the target
						target->CastToNPC()->Attack(this); //attack 'm!
					}
					else
					{
						Message(0, "I'm fine and full. I won't eat you."); 
					}

				} else
				{
					Message(0, "%s says, \"I cannot eat you. You sure people eat your kind?.\"",target->GetName());
				}
				
			}
			 else  
			{
				Message(0, "You really think that such a thing could eat?");
			}
		
			 
		}

		//malevolent
		//using sic code, but adds if npc is hungry and if it can eat the target
		//todo add a method to npc with a sicifhungry() signature
		else if (strcasecmp(sep.arg[0], "#sicifhungry") == 0) 
		{
			if (target && target->IsNPC() && sep.arg[1] != 0) 
			{
				Mob* sictar = entity_list.GetMob(sep.arg[1]);
				
				if (sictar) 
				{
					if(target->CastToNPC()->CanIEatYou(this->CastToMob()))
					{
						Message(0, "mmmm..foood");

						if(target->CastToNPC()->IsHungry())
						{
							Message(0, "I'm going to eat you!");
							target->CastToNPC()->AddToHateList(sictar,100); //be sure to *stick* to the target
							target->CastToNPC()->Attack(this); //attack 'm!
						}
						else
						{
							Message(0, "I'm full. I won't eat."); 
						}
					}
				}
				else 
				{
					Message(0, "Error: %s not found", sep.arg[1]);
				}
			}
			else 
			{
				Message(0, "Usage: (needs NPC targeted) #sic targetname");
			}
		}



attack.cpp
::death
at end of the tunnel

	//malevolent
	if (other->IsNPC())
		other->CastToNPC()->Eat(pp.level);
--MV
Reply With Quote