Improve mobv2

This commit is contained in:
Perttu Ahola 2011-10-15 12:17:21 +03:00
parent 43a28f04fa
commit 5341bf59c2
11 changed files with 221 additions and 78 deletions

@ -1523,7 +1523,7 @@ void Client::groundAction(u8 action, v3s16 nodepos_undersurface,
Send(0, data, true); Send(0, data, true);
} }
void Client::clickActiveObject(u8 button, u16 id, u16 item) void Client::clickActiveObject(u8 button, u16 id, u16 item_i)
{ {
if(connectedAndInitialized() == false){ if(connectedAndInitialized() == false){
dout_client<<DTIME<<"Client::clickActiveObject() " dout_client<<DTIME<<"Client::clickActiveObject() "
@ -1531,6 +1531,38 @@ void Client::clickActiveObject(u8 button, u16 id, u16 item)
<<std::endl; <<std::endl;
return; return;
} }
Player *player = m_env.getLocalPlayer();
if(player == NULL)
return;
ClientActiveObject *obj = m_env.getActiveObject(id);
if(obj){
if(button == 0){
ToolItem *titem = NULL;
std::string toolname = "";
InventoryList *mlist = player->inventory.getList("main");
if(mlist != NULL)
{
InventoryItem *item = mlist->getItem(item_i);
if(item && (std::string)item->getName() == "ToolItem")
{
titem = (ToolItem*)item;
toolname = titem->getToolName();
}
}
v3f playerpos = player->getPosition();
v3f objpos = obj->getPosition();
v3f dir = (objpos - playerpos).normalize();
bool disable_send = obj->directReportPunch(toolname, dir);
if(disable_send)
return;
}
}
/* /*
length: 7 length: 7
@ -1544,7 +1576,7 @@ void Client::clickActiveObject(u8 button, u16 id, u16 item)
writeU16(&data[0], TOSERVER_CLICK_ACTIVEOBJECT); writeU16(&data[0], TOSERVER_CLICK_ACTIVEOBJECT);
writeU8(&data[2], button); writeU8(&data[2], button);
writeU16(&data[3], id); writeU16(&data[3], id);
writeU16(&data[5], item); writeU16(&data[5], item_i);
Send(0, data, true); Send(0, data, true);
} }

@ -183,7 +183,7 @@ public:
void groundAction(u8 action, v3s16 nodepos_undersurface, void groundAction(u8 action, v3s16 nodepos_undersurface,
v3s16 nodepos_oversurface, u16 item); v3s16 nodepos_oversurface, u16 item);
void clickActiveObject(u8 button, u16 id, u16 item); void clickActiveObject(u8 button, u16 id, u16 item_i);
void sendSignNodeText(v3s16 p, std::string text); void sendSignNodeText(v3s16 p, std::string text);
void sendInventoryAction(InventoryAction *a); void sendInventoryAction(InventoryAction *a);

@ -60,7 +60,7 @@ public:
virtual void processMessage(const std::string &data){} virtual void processMessage(const std::string &data){}
virtual std::string infoText() {return "";} virtual std::string infoText() {return "";}
/* /*
This takes the return value of This takes the return value of
ServerActiveObject::getClientInitializationData ServerActiveObject::getClientInitializationData
@ -70,6 +70,10 @@ public:
// Create a certain type of ClientActiveObject // Create a certain type of ClientActiveObject
static ClientActiveObject* create(u8 type); static ClientActiveObject* create(u8 type);
// If returns true, punch will not be sent to the server
virtual bool directReportPunch(const std::string &toolname, v3f dir)
{ return false; }
protected: protected:
// Used for creating objects based on type // Used for creating objects based on type
typedef ClientActiveObject* (*Factory)(); typedef ClientActiveObject* (*Factory)();

@ -874,7 +874,10 @@ MobV2CAO::MobV2CAO():
m_last_light(0), m_last_light(0),
m_shooting(0), m_shooting(0),
m_shooting_unset_timer(0), m_shooting_unset_timer(0),
m_sprite_size(BS,BS),
m_sprite_y(0),
m_bright_shooting(false), m_bright_shooting(false),
m_lock_full_brightness(false),
m_player_hit_timer(0) m_player_hit_timer(0)
{ {
ClientActiveObject::registerType(getType(), create); ClientActiveObject::registerType(getType(), create);
@ -897,10 +900,10 @@ void MobV2CAO::addToScene(scene::ISceneManager *smgr)
if(m_node != NULL) if(m_node != NULL)
return; return;
std::string texture_name = m_properties->get("texture_name"); /*dstream<<"MobV2CAO::addToScene using texture_name="<<
//dstream<<"MobV2CAO::addToScene using texture_name="<<texture_name<<std::endl; m_texture_name<<std::endl;*/
std::string texture_string = "[makealpha2:128,0,0;128,128,0:"; std::string texture_string = "[makealpha2:128,0,0;128,128,0:";
texture_string += texture_name; texture_string += m_texture_name;
scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode( scene::MyBillboardSceneNode *bill = new scene::MyBillboardSceneNode(
smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1)); smgr->getRootSceneNode(), smgr, -1, v3f(0,0,0), v2f(1,1));
@ -986,7 +989,7 @@ void MobV2CAO::updateNodePos()
if(m_node == NULL) if(m_node == NULL)
return; return;
m_node->setPosition(pos_translator.vect_show + m_sprite_pos); m_node->setPosition(pos_translator.vect_show + v3f(0,m_sprite_y,0));
} }
void MobV2CAO::step(float dtime, ClientEnvironment *env) void MobV2CAO::step(float dtime, ClientEnvironment *env)
@ -1137,15 +1140,16 @@ void MobV2CAO::processMessage(const std::string &data)
{ {
//u16 damage = readU16(is); //u16 damage = readU16(is);
u8 li = decode_light(m_last_light); /*u8 li = decode_light(m_last_light);
if(li >= 100) if(li >= 100)
li = 30; li = 30;
else else
li = 255; li = 255;*/
video::SColor color(255,li,li,li);
/*video::SColor color(255,255,0,0);
m_node->setColor(color); m_node->setColor(color);
m_damage_visual_timer = 0.2; m_damage_visual_timer = 0.2;*/
} }
// Trigger shooting // Trigger shooting
else if(cmd == 2) else if(cmd == 2)
@ -1183,38 +1187,19 @@ void MobV2CAO::initialize(const std::string &data)
std::istringstream tmp_is(tmp_os.str(), std::ios::binary); std::istringstream tmp_is(tmp_os.str(), std::ios::binary);
m_properties->parseConfigLines(tmp_is, "MobArgsEnd"); m_properties->parseConfigLines(tmp_is, "MobArgsEnd");
/*dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl; dstream<<"INFO: MobV2CAO::initialize(): got properties:"<<std::endl;
m_properties->writeLines(dstream);*/ m_properties->writeLines(dstream);
m_properties->setDefault("texture_name", "stone.png"); m_properties->setDefault("looks", "dummy_default");
m_properties->setDefault("yaw", "0"); m_properties->setDefault("yaw", "0");
m_properties->setDefault("pos", "(0,0,0)"); m_properties->setDefault("pos", "(0,0,0)");
m_properties->setDefault("sprite_size", "(1,1)");
m_properties->setDefault("sprite_pos", "(0,0,0)");
m_properties->setDefault("selection_size", "(0.4,0.4)");
m_properties->setDefault("selection_y", "-0.4");
m_properties->setDefault("sprite_type", "humanoid_1");
m_properties->setDefault("simple_anim_frames", "1");
m_properties->setDefault("simple_anim_frametime", "0.5");
m_properties->setDefault("lock_full_brightness", "false");
m_properties->setDefault("player_hit_damage", "0"); m_properties->setDefault("player_hit_damage", "0");
m_properties->setDefault("player_hit_distance", "1.5"); m_properties->setDefault("player_hit_distance", "1.5");
m_properties->setDefault("player_hit_interval", "1.5"); m_properties->setDefault("player_hit_interval", "1.5");
setLooks(m_properties->get("looks"));
m_yaw = m_properties->getFloat("yaw"); m_yaw = m_properties->getFloat("yaw");
m_position = m_properties->getV3F("pos"); m_position = m_properties->getV3F("pos");
m_sprite_size = m_properties->getV2F("sprite_size") * BS;
m_sprite_pos = m_properties->getV3F("sprite_pos") * BS;
v2f selection_size = m_properties->getV2F("selection_size") * BS;
float selection_y = m_properties->getFloat("selection_y") * BS;
m_selection_box = core::aabbox3d<f32>(
-selection_size.X, selection_y, -selection_size.X,
selection_size.X, selection_y+selection_size.Y,
selection_size.X);
m_sprite_type = m_properties->get("sprite_type");
m_simple_anim_frames = m_properties->getS32("simple_anim_frames");
m_simple_anim_frametime = m_properties->getFloat("simple_anim_frametime");
m_lock_full_brightness = m_properties->getBool("lock_full_brightness");
m_player_hit_damage = m_properties->getS32("player_hit_damage"); m_player_hit_damage = m_properties->getS32("player_hit_damage");
m_player_hit_distance = m_properties->getFloat("player_hit_distance"); m_player_hit_distance = m_properties->getFloat("player_hit_distance");
m_player_hit_interval = m_properties->getFloat("player_hit_interval"); m_player_hit_interval = m_properties->getFloat("player_hit_interval");
@ -1225,4 +1210,55 @@ void MobV2CAO::initialize(const std::string &data)
updateNodePos(); updateNodePos();
} }
bool MobV2CAO::directReportPunch(const std::string &toolname, v3f dir)
{
video::SColor color(255,255,0,0);
m_node->setColor(color);
m_damage_visual_timer = 0.05;
m_position += dir * BS;
pos_translator.sharpen();
pos_translator.update(m_position);
updateNodePos();
return false;
}
void MobV2CAO::setLooks(const std::string &looks)
{
v2f selection_size = v2f(0.4, 0.4) * BS;
float selection_y = 0 * BS;
if(looks == "dungeon_master"){
m_texture_name = "dungeon_master.png";
m_sprite_type = "humanoid_1";
m_sprite_size = v2f(2, 3) * BS;
m_sprite_y = 0.85 * BS;
selection_size = v2f(0.4, 2.6) * BS;
selection_y = -0.4 * BS;
}
else if(looks == "fireball"){
m_texture_name = "fireball.png";
m_sprite_type = "simple";
m_sprite_size = v2f(1, 1) * BS;
m_simple_anim_frames = 3;
m_simple_anim_frametime = 0.1;
m_lock_full_brightness = true;
}
else{
m_texture_name = "stone.png";
m_sprite_type = "simple";
m_sprite_size = v2f(1, 1) * BS;
m_simple_anim_frames = 3;
m_simple_anim_frametime = 0.333;
selection_size = v2f(0.4, 0.4) * BS;
selection_y = 0 * BS;
}
m_selection_box = core::aabbox3d<f32>(
-selection_size.X, selection_y, -selection_size.X,
selection_size.X, selection_y+selection_size.Y,
selection_size.X);
}

@ -33,19 +33,19 @@ class Settings;
struct SmoothTranslator struct SmoothTranslator
{ {
v3f vect_old; v3f vect_old;
v3f vect_show;
v3f vect_aim;
f32 anim_counter; f32 anim_counter;
f32 anim_time; f32 anim_time;
f32 anim_time_counter; f32 anim_time_counter;
v3f vect_show;
v3f vect_aim;
SmoothTranslator(): SmoothTranslator():
vect_old(0,0,0), vect_old(0,0,0),
vect_show(0,0,0),
vect_aim(0,0,0),
anim_counter(0), anim_counter(0),
anim_time(0), anim_time(0),
anim_time_counter(0), anim_time_counter(0)
vect_show(0,0,0),
vect_aim(0,0,0)
{} {}
void init(v3f vect) void init(v3f vect)
@ -53,6 +53,14 @@ struct SmoothTranslator
vect_old = vect; vect_old = vect;
vect_show = vect; vect_show = vect;
vect_aim = vect; vect_aim = vect;
anim_counter = 0;
anim_time = 0;
anim_time_counter = 0;
}
void sharpen()
{
init(vect_show);
} }
void update(v3f vect_new) void update(v3f vect_new)
@ -329,11 +337,17 @@ public:
//{return m_position;} //{return m_position;}
bool doShowSelectionBox(){return false;} bool doShowSelectionBox(){return false;}
// If returns true, punch will not be sent to the server
bool directReportPunch(const std::string &toolname, v3f dir);
private: private:
void setLooks(const std::string &looks);
IntervalLimiter m_attack_interval; IntervalLimiter m_attack_interval;
core::aabbox3d<f32> m_selection_box; core::aabbox3d<f32> m_selection_box;
scene::MyBillboardSceneNode *m_node; scene::MyBillboardSceneNode *m_node;
v3f m_position; v3f m_position;
std::string m_texture_name;
float m_yaw; float m_yaw;
SmoothTranslator pos_translator; SmoothTranslator pos_translator;
bool m_walking; bool m_walking;
@ -345,7 +359,7 @@ private:
bool m_shooting; bool m_shooting;
float m_shooting_unset_timer; float m_shooting_unset_timer;
v2f m_sprite_size; v2f m_sprite_size;
v3f m_sprite_pos; float m_sprite_y;
bool m_bright_shooting; bool m_bright_shooting;
std::string m_sprite_type; std::string m_sprite_type;
int m_simple_anim_frames; int m_simple_anim_frames;

@ -916,7 +916,8 @@ MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos,
m_shoot_reload_timer(0), m_shoot_reload_timer(0),
m_shooting(false), m_shooting(false),
m_shooting_timer(0), m_shooting_timer(0),
m_falling(false) m_falling(false),
m_disturb_timer(100000)
{ {
ServerActiveObject::registerType(getType(), create); ServerActiveObject::registerType(getType(), create);
@ -1071,6 +1072,22 @@ void MobV2SAO::step(float dtime, bool send_recommended)
m_removed = true; m_removed = true;
return; return;
} }
Player *disturbing_player =
m_env->getPlayer(m_disturbing_player.c_str());
v3f disturbing_player_off = v3f(0,1,0);
float disturbing_player_distance = 1000000;
float disturbing_player_dir = 0;
if(disturbing_player){
disturbing_player_off =
disturbing_player->getPosition() - m_base_position;
disturbing_player_distance = disturbing_player_off.getLength();
disturbing_player_off.normalize();
disturbing_player_dir = 180./M_PI*atan2(disturbing_player_off.Z,
disturbing_player_off.X);
}
m_disturb_timer += dtime;
if(!m_falling) if(!m_falling)
{ {
@ -1088,15 +1105,10 @@ void MobV2SAO::step(float dtime, bool send_recommended)
dstream<<__FUNCTION_NAME<<": Shooting fireball from "<<PP(pos) dstream<<__FUNCTION_NAME<<": Shooting fireball from "<<PP(pos)
<<" at speed "<<PP(speed)<<std::endl; <<" at speed "<<PP(speed)<<std::endl;
Settings properties; Settings properties;
properties.set("looks", "fireball");
properties.setV3F("speed", speed); properties.setV3F("speed", speed);
properties.setFloat("die_age", 5.0); properties.setFloat("die_age", 5.0);
properties.set("move_type", "constant_speed"); properties.set("move_type", "constant_speed");
properties.set("texture_name", "fireball.png");
properties.setV3F("sprite_pos", v3f(0.0, 0.0, 0.0));
properties.setV2F("sprite_size", v2f(1.0, 1.0));
properties.set("sprite_type", "simple");
properties.set("simple_anim_frames", "3");
properties.set("simple_anim_frametime", "0.1");
properties.setFloat("hp", 1000); properties.setFloat("hp", 1000);
properties.set("lock_full_brightness", "true"); properties.set("lock_full_brightness", "true");
properties.set("player_hit_damage", "9"); properties.set("player_hit_damage", "9");
@ -1114,8 +1126,18 @@ void MobV2SAO::step(float dtime, bool send_recommended)
m_shoot_reload_timer += dtime; m_shoot_reload_timer += dtime;
if(m_shoot_reload_timer >= 5.0 && !m_next_pos_exists) float reload_time = 15.0;
if(m_disturb_timer <= 15.0)
reload_time = 3.0;
if(m_shoot_reload_timer >= reload_time && !m_next_pos_exists)
{ {
if(m_disturb_timer < 30.0 && disturbing_player &&
disturbing_player_distance < 16*BS &&
fabs(disturbing_player_off.Y) < 5*BS){
m_yaw = disturbing_player_dir;
sendPosition();
}
m_shoot_reload_timer = 0.0; m_shoot_reload_timer = 0.0;
m_shooting = true; m_shooting = true;
m_shooting_timer = 1.5; m_shooting_timer = 1.5;
@ -1261,23 +1283,35 @@ void MobV2SAO::step(float dtime, bool send_recommended)
if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS) if(m_base_position.getDistanceFrom(m_last_sent_position) > 0.05*BS)
{ {
m_last_sent_position = m_base_position; sendPosition();
std::ostringstream os(std::ios::binary);
// command (0 = update position)
writeU8(os, 0);
// pos
writeV3F1000(os, m_base_position);
// yaw
writeF1000(os, m_yaw);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
} }
} }
u16 MobV2SAO::punch(const std::string &toolname, v3f dir) u16 MobV2SAO::punch(const std::string &toolname, v3f dir,
const std::string &playername)
{ {
assert(m_env);
Map *map = &m_env->getMap();
m_disturb_timer = 0;
m_disturbing_player = playername;
m_yaw = wrapDegrees_180(180./M_PI*atan2(dir.Z, dir.X) + 180.);
v3f new_base_position = m_base_position + dir * BS;
{
v3s16 pos_i = floatToInt(new_base_position, BS);
v3s16 size_blocks = v3s16(m_size.X+0.5,m_size.Y+0.5,m_size.X+0.5);
v3s16 pos_size_off(0,0,0);
if(m_size.X >= 2.5){
pos_size_off.X = -1;
pos_size_off.Y = -1;
}
bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks);
if(free)
m_base_position = new_base_position;
}
sendPosition();
u16 amount = 2; u16 amount = 2;
dstream<<"id="<<m_id<<": punch with \""<<toolname<<"\""<<std::endl; dstream<<"id="<<m_id<<": punch with \""<<toolname<<"\""<<std::endl;
/* See tool names in inventory.h */ /* See tool names in inventory.h */
@ -1297,6 +1331,22 @@ u16 MobV2SAO::punch(const std::string &toolname, v3f dir)
return 65536/100; return 65536/100;
} }
void MobV2SAO::sendPosition()
{
m_last_sent_position = m_base_position;
std::ostringstream os(std::ios::binary);
// command (0 = update position)
writeU8(os, 0);
// pos
writeV3F1000(os, m_base_position);
// yaw
writeF1000(os, m_yaw);
// create message and add to list
ActiveObjectMessage aom(getId(), false, os.str());
m_messages_out.push_back(aom);
}
void MobV2SAO::setPropertyDefaults() void MobV2SAO::setPropertyDefaults()
{ {
m_properties->setDefault("move_type", "ground_nodes"); m_properties->setDefault("move_type", "ground_nodes");

@ -155,8 +155,10 @@ public:
std::string getClientInitializationData(); std::string getClientInitializationData();
void step(float dtime, bool send_recommended); void step(float dtime, bool send_recommended);
InventoryItem* createPickedUpItem(){return NULL;} InventoryItem* createPickedUpItem(){return NULL;}
u16 punch(const std::string &toolname, v3f dir); u16 punch(const std::string &toolname, v3f dir,
const std::string &playername);
private: private:
void sendPosition();
void setPropertyDefaults(); void setPropertyDefaults();
void readProperties(); void readProperties();
void updateProperties(); void updateProperties();
@ -182,6 +184,8 @@ private:
float m_die_age; float m_die_age;
v2f m_size; v2f m_size;
bool m_falling; bool m_falling;
float m_disturb_timer;
std::string m_disturbing_player;
Settings *m_properties; Settings *m_properties;
}; };

@ -645,17 +645,12 @@ void ServerEnvironment::activateBlock(MapBlock *block, u32 additional_dtime)
static void getMob_dungeon_master(Settings &properties) static void getMob_dungeon_master(Settings &properties)
{ {
properties.set("texture_name", "dungeon_master.png"); properties.set("looks", "dungeon_master");
properties.setV3F("sprite_pos", v3f(0.0, 0.85, 0.0));
properties.setV2F("sprite_size", v2f(2.0, 3.0));
properties.setFloat("selection_y", -0.4);
properties.setV2F("selection_size", v2f(0.4, 2.6));
properties.setFloat("yaw", 1.57); properties.setFloat("yaw", 1.57);
properties.setFloat("hp", 20); properties.setFloat("hp", 20);
properties.setBool("bright_shooting", true); properties.setBool("bright_shooting", true);
properties.set("shoot_type", "fireball"); properties.set("shoot_type", "fireball");
properties.set("shoot_y", "0.7"); properties.set("shoot_y", "0.7");
properties.set("sprite_type", "humanoid_1");
properties.set("player_hit_damage", "1"); properties.set("player_hit_damage", "1");
properties.set("player_hit_distance", "1.0"); properties.set("player_hit_distance", "1.0");
properties.set("player_hit_interval", "0.5"); properties.set("player_hit_interval", "0.5");

@ -1532,16 +1532,23 @@ void the_game(
//if(input->getLeftClicked()) //if(input->getLeftClicked())
if(input->getLeftState()) if(input->getLeftState())
{ {
bool do_punch = false;
bool do_punch_damage = false;
if(object_hit_delay_timer <= 0.0){ if(object_hit_delay_timer <= 0.0){
do_punch = true;
do_punch_damage = true;
object_hit_delay_timer = object_hit_delay;
}
if(input->getLeftClicked()){
do_punch = true;
}
if(do_punch){
dstream<<DTIME<<"Left-clicked object"<<std::endl; dstream<<DTIME<<"Left-clicked object"<<std::endl;
left_punch = true;
}
if(do_punch_damage){
client.clickActiveObject(0, client.clickActiveObject(0,
selected_active_object->getId(), g_selected_item); selected_active_object->getId(), g_selected_item);
object_hit_delay_timer = object_hit_delay;
left_punch = true;
} else {
dstream<<DTIME<<"Left-clicked object faster than allowed"
<<std::endl;
left_punch_muted = true;
} }
} }
else if(input->getRightClicked()) else if(input->getRightClicked())

@ -2340,7 +2340,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
v3f objpos = obj->getBasePosition(); v3f objpos = obj->getBasePosition();
v3f dir = (objpos - playerpos).normalize(); v3f dir = (objpos - playerpos).normalize();
u16 wear = obj->punch(toolname, dir); u16 wear = obj->punch(toolname, dir, player->getName());
if(titem) if(titem)
{ {

@ -104,7 +104,8 @@ public:
If the object doesn't return an item, this will be called. If the object doesn't return an item, this will be called.
Return value is tool wear. Return value is tool wear.
*/ */
virtual u16 punch(const std::string &toolname, v3f dir) virtual u16 punch(const std::string &toolname, v3f dir,
const std::string &playername)
{return 0;} {return 0;}
/* /*