some changes to mob movement

This commit is contained in:
darkrose 2014-09-27 06:10:36 +10:00
parent 6bbd7fe21c
commit dffca1b832
8 changed files with 84 additions and 29 deletions

View File

@ -1306,7 +1306,6 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
is.read(buf, 1);
u8 type = readU8((u8*)buf);
std::string data = deSerializeLongString(is);
printf("mob add: %d %d\n",id,type);
// Add it
{
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out

View File

@ -20,6 +20,7 @@
#include "content_craftitem.h"
#include "content_mapnode.h"
#include "content_craft.h"
#include "content_mob.h"
#include "content_list.h"
#include <map>
#include "gettext.h"
@ -225,6 +226,7 @@ void content_craftitem_init()
f->description = wgettext("Rat");
f->cook_result = "CraftItem cooked_rat 1";
f->drop_count = 1;
f->drop_item = CONTENT_MOB_RAT;
lists::add("creative",i);
lists::add("cooking",i);
@ -246,6 +248,7 @@ void content_craftitem_init()
f->name = "firefly";
f->description = wgettext("Firefly");
f->drop_count = 1;
f->drop_item = CONTENT_MOB_FIREFLY;
lists::add("creative",i);
i = CONTENT_CRAFTITEM_APPLE;

View File

@ -20,6 +20,8 @@ struct CraftItemFeatures {
s16 edible;
// the number dropped on right click, -1 for all
s16 drop_count;
// used by mobs that are picked up
content_t drop_item;
CraftItemFeatures():
content(CONTENT_IGNORE),
@ -29,7 +31,8 @@ struct CraftItemFeatures {
cook_result(""),
fuel_time(0.0),
edible(0),
drop_count(-1)
drop_count(-1),
drop_item(CONTENT_IGNORE)
{}
};

View File

@ -119,6 +119,10 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos)
MobFeatures m = i->second;
if (m.spawn_in == CONTENT_IGNORE && m.spawn_on == CONTENT_IGNORE)
continue;
if (m.spawn_min_height > pos.Y)
continue;
if (m.spawn_max_height < pos.Y)
continue;
if (m.spawn_in != CONTENT_IGNORE) {
if (m.spawn_in != c1)
continue;
@ -166,7 +170,6 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos)
void content_mob_init()
{
g_content_mob_features.clear();
printf("initialising mobs\n\n");
content_t i;
MobFeatures *f = NULL;
@ -183,31 +186,46 @@ printf("initialising mobs\n\n");
f->motion = MM_WANDER;
f->spawn_on = CONTENT_GRASS;
f->spawn_in = CONTENT_AIR;
f->spawn_max_height = 20;
f->spawn_max_light = LIGHT_MAX/2;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_FIREFLY;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_PASSIVE;
f->setTexture("mob_firefly.png");
f->model = "rat.x";
f->setTexture("ob_firefly.png");
f->punch_action = MPA_PICKUP;
f->dropped_item = std::string("CraftItem2 ")+itos(CONTENT_CRAFTITEM_FIREFLY)+" 1";
f->motion = MM_WANDER;
f->motion_type = MMT_FLYLOW;
f->glow_light = LIGHT_MAX-1;
f->spawn_on = CONTENT_JUNGLETREE;
f->spawn_in = CONTENT_AIR;
f->spawn_min_height = -5;
f->spawn_max_height = 20;
f->spawn_max_light = LIGHT_MAX/3;
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
i = CONTENT_MOB_OERKKI;
f = &g_content_mob_features[i];
//f->content = i;
f->content = i;
f->level = MOB_AGGRESSIVE;
f->model = "oerkki.x";
f->model_scale = v3f(4,4,4);
f->setTexture("mob_oerkki.png");
f->setAnimationFrames(MA_STAND,24,36);
f->setAnimationFrames(MA_ATTACK,37,49);
f->punch_action = MPA_HARM;
f->motion = MM_SEEKER;
f->spawn_on = CONTENT_STONE;
f->spawn_in = CONTENT_AIR;
f->spawn_max_height = 2;
f->spawn_max_light = LIGHT_MAX/4;
f->notices_player = true;
f->attack_player_damage = 3;
f->attack_player_range = v3f(1,1,1);
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS*2.,BS/3.));
i = CONTENT_MOB_DUNGEON_MASTER;

View File

@ -117,6 +117,8 @@ struct MobFeatures {
content_t spawn_in;
u8 spawn_min_light;
u8 spawn_max_light;
s16 spawn_min_height;
s16 spawn_max_height;
MobFeatures()
{
@ -220,6 +222,8 @@ struct MobFeatures {
spawn_in = CONTENT_IGNORE;
spawn_min_light = 0;
spawn_max_light = LIGHT_MAX;
spawn_min_height = -20000;
spawn_max_height = 100;
}
};

View File

@ -353,7 +353,7 @@ void MobSAO::step(float dtime, bool send_recommended)
v3f playerpos = player->getPosition();
f32 dist = m_base_position.getDistanceFrom(playerpos);
if (dist < BS*16) {
if (myrand_range(0,3) == 0) {
if (dist < BS*3 || myrand_range(0,3) == 0) {
actionstream<<"Mob id="<<m_id<<" at "
<<PP(m_base_position/BS)
<<" got randomly disturbed by "
@ -441,13 +441,20 @@ void MobSAO::step(float dtime, bool send_recommended)
if (m.motion != MM_CONSTANT && m.motion != MM_STATIC && !m_shooting) {
m_walk_around_timer -= dtime;
if (m_walk_around_timer <= 0.0) {
m_walk_around = !m_walk_around;
m_walk_around_timer = 1.0;
//if (m_walk_around) {
//m_walk_around_timer = 0.1*myrand_range(10,50);
//}else{
//m_walk_around_timer = 0.1*myrand_range(30,70);
//}
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 = true;
}
}else{
m_walk_around = !m_walk_around;
if (m_walk_around) {
if (!disturbing_player || m.motion != MM_SEEKER)
m_walk_around_timer = 0.1*myrand_range(10,30);
}else{
m_walk_around_timer = 0.1*myrand_range(30,70);
}
}
}
if (m_next_pos_exists) {
v3f pos_f = m_base_position;
@ -460,6 +467,8 @@ void MobSAO::step(float dtime, bool send_recommended)
v3f dir = diff;
dir.normalize();
float speed = BS * 0.5;
if (m.motion == MM_SEEKER && disturbing_player)
speed = BS;
if (m_falling)
speed = BS * 3.0;
dir *= dtime * speed;
@ -479,7 +488,7 @@ void MobSAO::step(float dtime, bool send_recommended)
if (m.motion == MM_WANDER) {
stepMotionWander(dtime);
}else if (m.motion == MM_SEEKER) {
if (disturbing_player) {
if (!disturbing_player) {
stepMotionWander(dtime);
}else{
stepMotionSeeker(dtime);
@ -601,11 +610,27 @@ void MobSAO::stepMotionWander(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;
}
}
}
@ -622,6 +647,8 @@ void MobSAO::stepMotionWander(float dtime)
continue;
if (falling && dy > 0)
continue;
if (raising && dy < 0)
continue;
dps[num_dps++] = v3s16(dx,dy,dz);
}
u32 order[3*3*3];
@ -986,6 +1013,9 @@ bool MobSAO::checkFreePosition(v3s16 p0)
if(n.getContent() != clear)
return false;
}
MapNode n = map->getNodeNoEx(p0+v3s16(0,-1,0));
if (!content_features(n).jumpable)
return false;
return true;
}
bool MobSAO::checkWalkablePosition(v3s16 p0)
@ -993,11 +1023,10 @@ bool MobSAO::checkWalkablePosition(v3s16 p0)
assert(m_env);
v3s16 p = p0 + v3s16(0,-1,0);
MapNode n = m_env->getMap().getNodeNoEx(p);
content_t clear = CONTENT_AIR;
if (content_mob_features(m_content).motion_type == MMT_SWIM)
clear = CONTENT_WATERSOURCE;
if (n.getContent() != clear)
return true;
if (n.getContent() != CONTENT_AIR) {
if (content_features(n).liquid_type == LIQUID_NONE)
return true;
}
return false;
}
bool MobSAO::checkFreeAndWalkablePosition(v3s16 p0)

View File

@ -206,8 +206,10 @@ std::wstring CraftItem::getGuiName()
ServerActiveObject* CraftItem::createSAO(ServerEnvironment *env, u16 id, v3f pos)
{
// Special cases
if ((m_content&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) {
ServerActiveObject *obj = new MobSAO(env,id,pos,m_content);
if ((content_craftitem_features(m_content).drop_item&CONTENT_MOB_MASK) == CONTENT_MOB_MASK) {
v3f p = pos;
p.Y += 0.5*BS;
ServerActiveObject *obj = new MobSAO(env,id,p,content_craftitem_features(m_content).drop_item);
if (obj)
return obj;
}

View File

@ -1402,8 +1402,6 @@ void Server::AsyncRunStep()
type = obj->getType();
}
printf("type == %u\n",type);
// Add to data buffer for sending
writeU16((u8*)buf, id);
data_buffer.append(buf, 2);
@ -1415,7 +1413,6 @@ printf("type == %u\n",type);
}else{
data_buffer.append(serializeLongString(""));
}
printf("data_buffer.size() == %u\n",(u32)data_buffer.size());
// Add to known objects
client->m_known_objects.insert(i.getNode()->getKey(), false);