2013-09-07 16:19:56 -04:00
|
|
|
|
|
|
|
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
|
|
|
|
|
|
|
|
#include "MobTypesManager.h"
|
|
|
|
#include "MersenneTwister.h"
|
|
|
|
#include "Mobs/Monster.h"
|
|
|
|
#include "Mobs/IncludeAllMonsters.h"
|
|
|
|
#include "FastRandom.h"
|
|
|
|
|
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
2013-10-20 07:10:21 -04:00
|
|
|
/** Map for cMonster::eType <-> string
|
|
|
|
Needs to be alpha-sorted by the strings, because binary search is used in StringToMobType()
|
|
|
|
The strings need to be lowercase (for more efficient comparisons in StringToMobType())
|
|
|
|
*/
|
|
|
|
static const struct
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
cMonster::eType m_Type;
|
|
|
|
const char * m_lcName;
|
|
|
|
} g_MobTypeNames[] =
|
2013-09-07 19:21:43 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
{cMonster::mtBat, "bat"},
|
|
|
|
{cMonster::mtBlaze, "blaze"},
|
|
|
|
{cMonster::mtCaveSpider, "cavespider"},
|
|
|
|
{cMonster::mtChicken, "chicken"},
|
|
|
|
{cMonster::mtCow, "cow"},
|
|
|
|
{cMonster::mtCreeper, "creeper"},
|
|
|
|
{cMonster::mtEnderman, "enderman"},
|
|
|
|
{cMonster::mtGhast, "ghast"},
|
|
|
|
{cMonster::mtHorse, "horse"},
|
|
|
|
{cMonster::mtMagmaCube, "magmacube"},
|
|
|
|
{cMonster::mtMooshroom, "mooshroom"},
|
|
|
|
{cMonster::mtOcelot, "ocelot"},
|
|
|
|
{cMonster::mtPig, "pig"},
|
|
|
|
{cMonster::mtSheep, "sheep"},
|
|
|
|
{cMonster::mtSilverfish, "silverfish"},
|
|
|
|
{cMonster::mtSkeleton, "skeleton"},
|
|
|
|
{cMonster::mtSlime, "slime"},
|
|
|
|
{cMonster::mtSpider, "spider"},
|
|
|
|
{cMonster::mtSquid, "squid"},
|
|
|
|
{cMonster::mtVillager, "villager"},
|
|
|
|
{cMonster::mtWitch, "witch"},
|
|
|
|
{cMonster::mtWolf, "wolf"},
|
|
|
|
{cMonster::mtZombie, "zombie"},
|
|
|
|
{cMonster::mtZombiePigman, "zombiepigman"},
|
|
|
|
} ;
|
2013-09-07 16:19:56 -04:00
|
|
|
|
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cMonster * cMobTypesManager::NewMonsterFromType(cMonster::eType a_MobType, int a_Size)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
cFastRandom Random;
|
|
|
|
|
2013-09-07 16:19:56 -04:00
|
|
|
cMonster * toReturn = NULL;
|
|
|
|
|
|
|
|
// unspecified size get rand[1,3] for Monsters that need size
|
|
|
|
switch (a_MobType)
|
|
|
|
{
|
|
|
|
case cMonster::mtMagmaCube:
|
|
|
|
case cMonster::mtSlime:
|
2013-10-20 04:23:30 -04:00
|
|
|
{
|
2013-09-07 16:19:56 -04:00
|
|
|
if (a_Size == -1)
|
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
a_Size = Random.NextInt(2, a_MobType) + 1;
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
2013-10-20 04:23:30 -04:00
|
|
|
if ((a_Size <= 0) || (a_Size >= 4))
|
2013-09-08 06:20:19 -04:00
|
|
|
{
|
|
|
|
ASSERT(!"Random for size was supposed to pick in [1..3] and picked outside");
|
|
|
|
a_Size = 1;
|
|
|
|
}
|
2013-09-07 16:19:56 -04:00
|
|
|
break;
|
2013-10-20 04:23:30 -04:00
|
|
|
}
|
|
|
|
default: break;
|
|
|
|
} // switch (a_MobType)
|
2013-09-07 16:19:56 -04:00
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
// Create the mob entity
|
2013-09-07 16:19:56 -04:00
|
|
|
switch (a_MobType)
|
|
|
|
{
|
2013-10-14 12:03:47 -04:00
|
|
|
case cMonster::mtMagmaCube: toReturn = new cMagmaCube(a_Size); break;
|
|
|
|
case cMonster::mtSlime: toReturn = new cSlime(a_Size); break;
|
|
|
|
case cMonster::mtBat: toReturn = new cBat(); break;
|
|
|
|
case cMonster::mtBlaze: toReturn = new cBlaze(); break;
|
|
|
|
case cMonster::mtCaveSpider: toReturn = new cCavespider(); break;
|
|
|
|
case cMonster::mtChicken: toReturn = new cChicken(); break;
|
|
|
|
case cMonster::mtCow: toReturn = new cCow(); break;
|
|
|
|
case cMonster::mtCreeper: toReturn = new cCreeper(); break;
|
|
|
|
case cMonster::mtEnderman: toReturn = new cEnderman(); break;
|
|
|
|
case cMonster::mtGhast: toReturn = new cGhast(); break;
|
2013-10-20 04:23:30 -04:00
|
|
|
// TODO:
|
|
|
|
// case cMonster::mtHorse: toReturn = new cHorse(); break;
|
2013-10-14 12:03:47 -04:00
|
|
|
case cMonster::mtMooshroom: toReturn = new cMooshroom(); break;
|
|
|
|
case cMonster::mtOcelot: toReturn = new cOcelot(); break;
|
|
|
|
case cMonster::mtPig: toReturn = new cPig(); break;
|
|
|
|
// TODO: Implement sheep color
|
|
|
|
case cMonster::mtSheep: toReturn = new cSheep(0); break;
|
|
|
|
case cMonster::mtSilverfish: toReturn = new cSilverfish(); break;
|
2013-10-20 04:23:30 -04:00
|
|
|
// TODO: Implement wither skeleton geration
|
2013-10-14 12:03:47 -04:00
|
|
|
case cMonster::mtSkeleton: toReturn = new cSkeleton(false); break;
|
|
|
|
case cMonster::mtSpider: toReturn = new cSpider(); break;
|
|
|
|
case cMonster::mtSquid: toReturn = new cSquid(); break;
|
|
|
|
case cMonster::mtVillager: toReturn = new cVillager(cVillager::vtFarmer); break;
|
|
|
|
case cMonster::mtWitch: toReturn = new cWitch(); break;
|
|
|
|
case cMonster::mtWolf: toReturn = new cWolf(); break;
|
|
|
|
case cMonster::mtZombie: toReturn = new cZombie(false); break;
|
|
|
|
case cMonster::mtZombiePigman: toReturn = new cZombiePigman(); break;
|
2013-09-07 16:19:56 -04:00
|
|
|
default:
|
|
|
|
{
|
2013-09-08 06:20:19 -04:00
|
|
|
ASSERT(!"Unhandled Mob type");
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return toReturn;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AString cMobTypesManager::MobTypeToString(cMonster::eType a_MobType)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
// Mob types aren't sorted, so we need to search linearly:
|
|
|
|
for (int i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
if (g_MobTypeNames[i].m_Type == a_MobType)
|
|
|
|
{
|
|
|
|
return g_MobTypeNames[i].m_lcName;
|
|
|
|
}
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
2013-10-20 07:10:21 -04:00
|
|
|
|
|
|
|
// Not found:
|
2013-10-20 04:23:30 -04:00
|
|
|
return "";
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cMonster::eType cMobTypesManager::StringToMobType(const AString & a_Name)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 04:23:30 -04:00
|
|
|
AString lcName(a_Name);
|
|
|
|
StrToLower(lcName);
|
2013-10-20 07:10:21 -04:00
|
|
|
|
|
|
|
// Binary-search for the lowercase name:
|
|
|
|
int lo = 0, hi = ARRAYCOUNT(g_MobTypeNames);
|
|
|
|
while (hi - lo > 1)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
int mid = (lo + hi) / 2;
|
|
|
|
int res = strcmp(g_MobTypeNames[mid].m_lcName, lcName.c_str());
|
|
|
|
if (res == 0)
|
|
|
|
{
|
|
|
|
return g_MobTypeNames[mid].m_Type;
|
|
|
|
}
|
|
|
|
if (res < 0)
|
2013-09-07 16:19:56 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
hi = mid;
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
2013-10-20 07:10:21 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
lo = mid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Range has collapsed to at most two elements, compare each:
|
|
|
|
if (strcmp(g_MobTypeNames[lo].m_lcName, lcName.c_str()) == 0)
|
|
|
|
{
|
|
|
|
return g_MobTypeNames[lo].m_Type;
|
|
|
|
}
|
|
|
|
if ((lo != hi) && (strcmp(g_MobTypeNames[hi].m_lcName, lcName.c_str()) == 0))
|
|
|
|
{
|
|
|
|
return g_MobTypeNames[hi].m_Type;
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
2013-10-20 07:10:21 -04:00
|
|
|
|
|
|
|
// Not found:
|
2013-09-07 19:21:43 -04:00
|
|
|
return cMonster::mtInvalidType;
|
|
|
|
}
|
|
|
|
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cMonster::eFamily cMobTypesManager::FamilyFromType(cMonster::eType a_Type)
|
2013-09-07 19:21:43 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
static const struct
|
2013-09-07 19:21:43 -04:00
|
|
|
{
|
2013-10-20 07:10:21 -04:00
|
|
|
cMonster::eType m_Type;
|
|
|
|
cMonster::eFamily m_Family;
|
|
|
|
} TypeMap[] =
|
|
|
|
{
|
|
|
|
{cMonster::mtBat, cMonster::mfAmbient},
|
|
|
|
{cMonster::mtBlaze, cMonster::mfHostile},
|
|
|
|
{cMonster::mtCaveSpider, cMonster::mfHostile},
|
|
|
|
{cMonster::mtChicken, cMonster::mfPassive},
|
|
|
|
{cMonster::mtCow, cMonster::mfPassive},
|
|
|
|
{cMonster::mtCreeper, cMonster::mfHostile},
|
|
|
|
{cMonster::mtEnderman, cMonster::mfHostile},
|
|
|
|
{cMonster::mtGhast, cMonster::mfHostile},
|
|
|
|
{cMonster::mtHorse, cMonster::mfPassive},
|
|
|
|
{cMonster::mtMagmaCube, cMonster::mfHostile},
|
|
|
|
{cMonster::mtMooshroom, cMonster::mfHostile},
|
|
|
|
{cMonster::mtOcelot, cMonster::mfHostile},
|
|
|
|
{cMonster::mtPig, cMonster::mfPassive},
|
|
|
|
{cMonster::mtSheep, cMonster::mfPassive},
|
|
|
|
{cMonster::mtSilverfish, cMonster::mfHostile},
|
|
|
|
{cMonster::mtSkeleton, cMonster::mfHostile},
|
|
|
|
{cMonster::mtSlime, cMonster::mfHostile},
|
|
|
|
{cMonster::mtSpider, cMonster::mfHostile},
|
|
|
|
{cMonster::mtSquid, cMonster::mfWater},
|
|
|
|
{cMonster::mtVillager, cMonster::mfPassive},
|
|
|
|
{cMonster::mtWitch, cMonster::mfHostile},
|
|
|
|
{cMonster::mtWolf, cMonster::mfHostile},
|
|
|
|
{cMonster::mtZombie, cMonster::mfHostile},
|
|
|
|
{cMonster::mtZombiePigman, cMonster::mfHostile},
|
|
|
|
} ;
|
|
|
|
|
|
|
|
for (int i = 0; i < ARRAYCOUNT(TypeMap); i++)
|
|
|
|
{
|
|
|
|
if (TypeMap[i].m_Type == a_Type)
|
|
|
|
{
|
|
|
|
return TypeMap[i].m_Family;
|
|
|
|
}
|
2013-09-07 19:21:43 -04:00
|
|
|
}
|
2013-10-20 07:10:21 -04:00
|
|
|
return cMonster::mfMaxplusone;
|
2013-09-07 16:19:56 -04:00
|
|
|
}
|
2013-10-20 04:23:30 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|