some more mobs and various tweaks

This commit is contained in:
darkrose 2014-09-28 06:39:08 +10:00
parent dffca1b832
commit b83023f828
15 changed files with 212 additions and 2903 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

BIN
data/models/fish.b3d Normal file

Binary file not shown.

View File

@ -1002,7 +1002,6 @@ Frame Root {
96.078431;
0.500000; 0.500000; 0.500000;;
0.000000; 0.000000; 0.000000;;
TextureFilename {"oerkki.png";}
}
} //End of Plane_009 Material List
MeshTextureCoords { //Plane_009 UV Coordinates

View File

@ -513,7 +513,6 @@ Frame Root {
96.078431;
0.500000; 0.500000; 0.500000;;
0.000000; 0.000000; 0.000000;;
TextureFilename {"data/textures/rat_mob.png";}
}
} //End of Cube_005 Material List
MeshTextureCoords { //Cube_005 UV Coordinates

BIN
data/models/shark.b3d Normal file

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 349 B

BIN
data/textures/mob_fish.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 KiB

BIN
data/textures/mob_shark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -230,7 +230,8 @@ MobCAO::MobCAO():
m_shooting(false),
m_shooting_unset_timer(0),
m_walking(false),
m_walking_unset_timer(0)
m_walking_unset_timer(0),
m_draw_type(MDT_NOTHING)
{
ClientActiveObject::registerType(getType(), create);
}
@ -253,35 +254,56 @@ void MobCAO::addToScene(scene::ISceneManager *smgr)
if (!mesh)
return;
m_node = smgr->addAnimatedMeshSceneNode(mesh);
scene::IAnimatedMeshSceneNode* node;
if (m_node) {
node = smgr->addAnimatedMeshSceneNode(mesh);
if (node) {
int s;
int e;
m.getAnimationFrames(MA_STAND,&s,&e);
m_node->setFrameLoop(s,e);
m_node->setScale(m.model_scale);
setMeshColor(m_node->getMesh(), video::SColor(255,255,255,255));
node->setFrameLoop(s,e);
node->setScale(m.model_scale);
setMeshColor(node->getMesh(), video::SColor(255,255,255,255));
bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");
// Set material flags and texture
m_node->setMaterialTexture( 0, driver->getTexture(getTexturePath(m.texture).c_str()));
video::SMaterial& material = m_node->getMaterial(0);
node->setMaterialTexture( 0, driver->getTexture(getTexturePath(m.texture).c_str()));
video::SMaterial& material = node->getMaterial(0);
material.setFlag(video::EMF_LIGHTING, false);
material.setFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
material.setFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
material.setFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
m_node->setVisible(true);
node->setVisible(true);
m_draw_type = MDT_MODEL;
}
m_node = (scene::IMeshSceneNode*)node;
#if (IRRLICHT_VERSION_MAJOR >= 1 && IRRLICHT_VERSION_MINOR >= 8) || IRRLICHT_VERSION_MAJOR >= 2
mesh->drop();
#endif
updateNodePos();
}else if (m.nodeboxes.size() > 0) {
}else if (m.texture != "") {
bool use_trilinear_filter = g_settings->getBool("trilinear_filter");
bool use_bilinear_filter = g_settings->getBool("bilinear_filter");
bool use_anisotropic_filter = g_settings->getBool("anisotropic_filter");
scene::IBillboardSceneNode *bill = smgr->addBillboardSceneNode(NULL, v2f(1, 1), v3f(0,0,0), -1);
bill->setMaterialTexture(0, driver->getTexture(getTexturePath(m.texture).c_str()));
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialFlag(video::EMF_TRILINEAR_FILTER, use_trilinear_filter);
bill->setMaterialFlag(video::EMF_BILINEAR_FILTER, use_bilinear_filter);
bill->setMaterialFlag(video::EMF_ANISOTROPIC_FILTER, use_anisotropic_filter);
bill->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
bill->setMaterialFlag(video::EMF_FOG_ENABLE, true);
bill->setColor(video::SColor(255,0,0,0));
bill->setVisible(true);
bill->setSize(BS,BS,BS);
m_node = (scene::IMeshSceneNode*)bill;
m_draw_type = MDT_SPRITE;
}
}
void MobCAO::removeFromScene()
@ -308,8 +330,11 @@ void MobCAO::updateLight(u8 light_at_pos)
video::SColor color(255,li,li,li);
if (m_node != NULL) {
m_node->setVisible(true);
setMeshVerticesColor(m_node->getMesh(), color);
if (m_draw_type == MDT_MODEL) {
setMeshVerticesColor(((scene::IAnimatedMeshSceneNode*)m_node)->getMesh(), color);
}else if (m_draw_type == MDT_SPRITE) {
((scene::IBillboardSceneNode*)m_node)->setColor(color);
}
}
}
v3s16 MobCAO::getLightPosition()
@ -328,7 +353,11 @@ void MobCAO::updateNodePos()
m_node->setPosition(offset-intToFloat(m_camera_offset, BS));
v3f rot = m_node->getRotation();
rot.Y = 90-m_yaw;
if (m_draw_type == MDT_MODEL) {
rot.Y = (90-m_yaw)+content_mob_features(m_content).model_rotation.Y;
}else if (m_draw_type == MDT_SPRITE) {
rot.Y = m_yaw+content_mob_features(m_content).model_rotation.Y;
}
m_node->setRotation(rot);
}
void MobCAO::step(float dtime, ClientEnvironment *env)
@ -343,13 +372,11 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
updateNodePos();
/* Damage local player */
if (m.attack_player_damage && m_player_hit_timer <= 0.0){
if (m.attack_player_damage && m_player_hit_timer <= 0.0) {
LocalPlayer *player = env->getLocalPlayer();
assert(player);
v3f playerpos = player->getPosition();
v2f playerpos_2d(playerpos.X,playerpos.Z);
v2f objectpos_2d(m_position.X,m_position.Z);
if (
fabs(m_position.X - playerpos.X) < m.attack_player_range.X*BS
@ -374,10 +401,7 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
m_walking_unset_timer += dtime;
if (m_walking_unset_timer >= 1.0) {
m_walking = false;
int s;
int e;
content_mob_features(m_content).getAnimationFrames(MA_STAND,&s,&e);
m_node->setFrameLoop(s,e);
setAnimation(MA_STAND);
}
m_shooting_unset_timer -= dtime;
@ -385,9 +409,18 @@ void MobCAO::step(float dtime, ClientEnvironment *env)
if (m.attack_glow_light) {
u8 li = decode_light(m_last_light);
video::SColor color(255,li,li,li);
setMeshVerticesColor(m_node->getMesh(), color);
if (m_draw_type == MDT_MODEL) {
setMeshVerticesColor(((scene::IAnimatedMeshSceneNode*)m_node)->getMesh(), color);
}else if (m_draw_type == MDT_SPRITE) {
((scene::IBillboardSceneNode*)m_node)->setColor(color);
}
}
m_shooting = false;
if (m_walking) {
setAnimation(MA_MOVE);
}else{
setAnimation(MA_STAND);
}
}
}
void MobCAO::processMessage(const std::string &data)
@ -405,12 +438,11 @@ void MobCAO::processMessage(const std::string &data)
// yaw
m_yaw = readF1000(is);
m_walking = true;
m_walking_unset_timer = 0;
int s;
int e;
content_mob_features(m_content).getAnimationFrames(MA_MOVE,&s,&e);
m_node->setFrameLoop(s,e);
if (!m_walking) {
m_walking = true;
m_walking_unset_timer = 0;
setAnimation(MA_MOVE);
}
updateNodePos();
}
@ -423,12 +455,18 @@ void MobCAO::processMessage(const std::string &data)
u8 li = decode_light(content_mob_features(m_content).attack_glow_light);
video::SColor color(255,li,li,li);
if (m_node != NULL) {
m_node->setVisible(true);
setMeshVerticesColor(m_node->getMesh(), color);
if (m_draw_type == MDT_MODEL) {
setMeshVerticesColor(((scene::IAnimatedMeshSceneNode*)m_node)->getMesh(), color);
}else if (m_draw_type == MDT_SPRITE) {
((scene::IBillboardSceneNode*)m_node)->setColor(color);
}
}
}
m_shooting = true;
if (!m_shooting) {
m_shooting = true;
setAnimation(MA_ATTACK);
}
}
}
void MobCAO::initialize(const std::string &data)
@ -467,8 +505,11 @@ bool MobCAO::directReportPunch(const std::string &toolname, v3f dir)
video::SColor color(255,255,0,0);
if (m_node != NULL) {
m_node->setVisible(true);
setMeshVerticesColor(m_node->getMesh(), color);
if (m_draw_type == MDT_MODEL) {
setMeshVerticesColor(((scene::IAnimatedMeshSceneNode*)m_node)->getMesh(), color);
}else if (m_draw_type == MDT_SPRITE) {
((scene::IBillboardSceneNode*)m_node)->setColor(color);
}
}
m_damage_visual_timer = 0.05;
@ -480,3 +521,12 @@ bool MobCAO::directReportPunch(const std::string &toolname, v3f dir)
return false;
}
void MobCAO::setAnimation(MobAnimation anim)
{
if (m_draw_type != MDT_MODEL)
return;
int s;
int e;
content_mob_features(m_content).getAnimationFrames(anim,&s,&e);
((scene::IAnimatedMeshSceneNode*)m_node)->setFrameLoop(s,e);
}

View File

@ -184,9 +184,10 @@ public:
// If returns true, punch will not be sent to the server
bool directReportPunch(const std::string &toolname, v3f dir);
private:
void setAnimation(MobAnimation anim);
aabb3f m_selection_box;
content_t m_content;
scene::IAnimatedMeshSceneNode *m_node;
scene::IMeshSceneNode *m_node;
v3f m_position;
v3s16 m_camera_offset;
float m_yaw;
@ -198,6 +199,8 @@ private:
float m_shooting_unset_timer;
bool m_walking;
float m_walking_unset_timer;
MobDrawType m_draw_type;
};

View File

@ -230,25 +230,40 @@ void content_mob_init()
i = CONTENT_MOB_DUNGEON_MASTER;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_DESTRUCTIVE;
f->model = "dungeon_master.x";
f->model = "dungeon_master.b3d";
f->model_rotation = v3f(0,-90,0);
f->model_offset = v3f(0,1.0,0);
f->setTexture("mob_dungeon_master.png");
f->setAnimationFrames(MA_STAND,1,30);
f->setAnimationFrames(MA_MOVE,31,60);
f->setAnimationFrames(MA_ATTACK,61,90);
f->punch_action = MPA_HARM;
f->motion = MM_SENTRY;
f->spawn_on = CONTENT_STONE;
f->spawn_in = CONTENT_AIR;
f->spawn_max_light = LIGHT_MAX/2;
f->notices_player = true;
f->attack_throw_object = CONTENT_MOB_FIREBALL;
f->attack_glow_light = LIGHT_MAX-1;
f->setCollisionBox(aabb3f(-0.4*BS,-0.4*BS,-0.4*BS, 0.4*BS,0.8*BS,0.4*BS));
f->attack_throw_offset = v3f(0,1.4,-1.0);
f->setCollisionBox(aabb3f(-0.75*BS, 0.*BS, -0.75*BS, 0.75*BS, 2.0*BS, 0.75*BS));
i = CONTENT_MOB_FIREBALL;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_DESTRUCTIVE;
//f->model = "rat.x";
f->setTexture("mob_fireball.png");
f->punch_action = MPA_IGNORE;
f->motion = MM_CONSTANT;
f->motion_type = MMT_FLY;
f->glow_light = LIGHT_MAX-1;
f->notices_player = true;
f->attack_player_damage = 3;
f->attack_player_range = v3f(2,2,2);
f->contact_explosion_diameter = 3;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_DEER;
@ -257,12 +272,50 @@ void content_mob_init()
i = CONTENT_MOB_SHEEP;
f = &g_content_mob_features[i];
//f->content = i;
i = CONTENT_MOB_FISH;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_PASSIVE;
f->model = "fish.b3d";
f->model_rotation = v3f(0,-90,0);
f->model_offset = v3f(0,0.5,0);
f->setTexture("mob_fish.png");
f->setAnimationFrames(MA_STAND,1,80);
f->setAnimationFrames(MA_MOVE,81,155);
f->motion = MM_WANDER;
f->motion_type = MMT_SWIM;
f->spawn_on = CONTENT_SAND;
f->spawn_in = CONTENT_WATERSOURCE;
f->spawn_min_height = -30;
f->spawn_max_height = -2;
f->setCollisionBox(aabb3f(-0.25*BS, 0., -0.25*BS, 0.25*BS, 0.5*BS, 0.25*BS));
i = CONTENT_MOB_SHARK;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_AGGRESSIVE;
f->hp = 40;
f->model = "shark.b3d";
f->model_scale = v3f(1,1,1);
f->model_rotation = v3f(0,-90,0);
f->model_offset = v3f(0,0.5,0);
f->setTexture("mob_shark.png");
f->setAnimationFrames(MA_STAND,1,80);
f->setAnimationFrames(MA_MOVE,80,160);
f->setAnimationFrames(MA_ATTACK,80,160);
f->punch_action = MPA_HARM;
f->motion = MM_SEEKER;
f->motion_type = MMT_SWIM;
f->spawn_on = CONTENT_SAND;
f->spawn_in = CONTENT_WATERSOURCE;
f->spawn_min_height = -30;
f->spawn_max_height = -2;
f->notices_player = true;
f->attack_player_damage = 3;
f->attack_player_range = v3f(1,1,1);
f->setCollisionBox(aabb3f(-0.75*BS, 0., -0.75*BS, 0.75*BS, 1.*BS, 0.75*BS));
i = CONTENT_MOB_WOLF;
f = &g_content_mob_features[i];
//f->content = i;

View File

@ -79,6 +79,14 @@ enum MobAnimationKey
MA_ATTACK_END
};
enum MobDrawType
{
MDT_NOTHING = 0,
MDT_MODEL,
MDT_BLOCK,
MDT_SPRITE
};
#define CONTENT_MOB_MASK 0x2000
struct MobFeatures {
@ -92,6 +100,7 @@ struct MobFeatures {
std::map<MobAnimationKey,int> animations;
v3f model_scale;
v3f model_offset;
v3f model_rotation;
std::vector<aabb3f> nodeboxes;
aabb3f collisionbox;
@ -200,6 +209,7 @@ struct MobFeatures {
model = "";
model_scale = v3f(1.0,1.0,1.0);
model_offset = v3f(0,0,0);
model_rotation = v3f(0,0,0);
nodeboxes.clear();
punch_action = MPA_DIE;
motion = MM_STATIC;

View File

@ -249,6 +249,8 @@ MobSAO::MobSAO(ServerEnvironment *env, u16 id, v3f pos, content_t type):
m_shoot_y(0)
{
ServerActiveObject::registerType(getType(), create);
if ((type&CONTENT_MOB_MASK) == CONTENT_MOB_MASK)
m_hp = content_mob_features(type).hp;
}
MobSAO::MobSAO(ServerEnvironment *env, u16 id, v3f pos, v3f speed, content_t type):
ServerActiveObject(env, id, pos),
@ -273,6 +275,8 @@ MobSAO::MobSAO(ServerEnvironment *env, u16 id, v3f pos, v3f speed, content_t typ
m_shoot_y(0)
{
ServerActiveObject::registerType(getType(), create);
if ((type&CONTENT_MOB_MASK) == CONTENT_MOB_MASK)
m_hp = content_mob_features(type).hp;
}
MobSAO::~MobSAO()
{
@ -345,22 +349,27 @@ void MobSAO::step(float dtime, bool send_recommended)
if (m.notices_player) {
if (m_random_disturb_timer >= 5.0) {
m_random_disturb_timer = 0;
m_disturbing_player = "";
// Check connected players
core::list<Player*> players = m_env->getPlayers(true);
for (core::list<Player*>::Iterator i = players.begin(); i != players.end(); i++) {
Player *player = *i;
v3f playerpos = player->getPosition();
f32 dist = m_base_position.getDistanceFrom(playerpos);
if (dist < BS*16) {
if (dist < BS*3 || myrand_range(0,3) == 0) {
actionstream<<"Mob id="<<m_id<<" at "
<<PP(m_base_position/BS)
<<" got randomly disturbed by "
<<player->getName()<<std::endl;
m_disturbing_player = player->getName();
m_disturb_timer = 0;
break;
if (
m_disturbing_player == ""
|| m_base_position.getDistanceFrom(m_env->getPlayer(m_disturbing_player.c_str())->getPosition()) > BS*16
) {
m_disturbing_player = "";
// Check connected players
core::list<Player*> players = m_env->getPlayers(true);
for (core::list<Player*>::Iterator i = players.begin(); i != players.end(); i++) {
Player *player = *i;
v3f playerpos = player->getPosition();
f32 dist = m_base_position.getDistanceFrom(playerpos);
if (dist < BS*16) {
if (dist < BS*3 || myrand_range(0,3) == 0) {
actionstream<<"Mob id="<<m_id<<" at "
<<PP(m_base_position/BS)
<<" got randomly disturbed by "
<<player->getName()<<std::endl;
m_disturbing_player = player->getName();
m_disturb_timer = 0;
break;
}
}
}
}
@ -382,18 +391,16 @@ void MobSAO::step(float dtime, bool send_recommended)
if (m_shooting_timer <= 0.0 && m_shooting) {
m_shooting = false;
v3f shoot_pos = m.attack_throw_offset * BS;
if (0) {
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
dir.Y = m_shoot_y;
dir.normalize();
v3f speed = dir * BS * 10.0;
v3f pos = m_base_position + shoot_pos;
infostream<<__FUNCTION_NAME<<": Mob id="<<m_id
<<" shooting from "<<PP(pos)
<<" at speed "<<PP(speed)<<std::endl;
ServerActiveObject *obj = new MobSAO(m_env, 0, pos, speed, m.attack_throw_object);
m_env->addActiveObject(obj);
}
v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI));
dir.Y = m_shoot_y;
dir.normalize();
v3f speed = dir * BS * 10.0;
v3f pos = m_base_position + shoot_pos;
infostream<<__FUNCTION_NAME<<": Mob id="<<m_id
<<" shooting from "<<PP(pos)
<<" at speed "<<PP(speed)<<std::endl;
ServerActiveObject *obj = new MobSAO(m_env, 0, pos, speed, m.attack_throw_object);
m_env->addActiveObject(obj);
}
m_shoot_reload_timer += dtime;
@ -443,7 +450,7 @@ void MobSAO::step(float dtime, bool send_recommended)
if (m_walk_around_timer <= 0.0) {
if (m.motion_type == MMT_FLY || (disturbing_player && m.motion == MM_SEEKER)) {
if (!m_walk_around) {
m_walk_around_timer = 1.0;
m_walk_around_timer = 0.5;
m_walk_around = true;
}
}else{
@ -777,11 +784,27 @@ void MobSAO::stepMotionSeeker(float dtime)
}
}else if (m.motion_type == MMT_FLYLOW || m.motion_type == MMT_SWIM) {
bool falling = false;
bool raising = false;
if (!m_next_pos_exists) {
/* Check whether to drop down */
if (checkFreePosition(pos_i + pos_size_off + v3s16(0,-1,0))) {
m_next_pos_i = pos_i + v3s16(0,-1,0);
falling = true;
u16 above;
v3s16 p = pos_i + pos_size_off;
for (above=0; above < 6; above++) {
p.Y--;
if (!checkFreePosition(p))
break;
}
if (above > 5) {
/* Check whether to drop down */
if (checkFreePosition(pos_i + pos_size_off + v3s16(0,-1,0))) {
m_next_pos_i = pos_i + v3s16(0,-1,0);
falling = true;
}
}else if (above < 2) {
/* Check whether to rise up */
if (checkFreePosition(pos_i + pos_size_off + v3s16(0,1,0))) {
m_next_pos_i = pos_i + v3s16(0,1,0);
raising = true;
}
}
}
@ -798,6 +821,8 @@ void MobSAO::stepMotionSeeker(float dtime)
continue;
if (falling && dy > 0)
continue;
if (raising && dy < 0)
continue;
if ((m_base_position+intToFloat(v3s16(dx,dy,dz),BS)).getDistanceFrom(player_pos) > distance)
continue;
dps[num_dps++] = v3s16(dx,dy,dz);