diff options
Diffstat (limited to 'src/object_properties.cpp')
-rw-r--r-- | src/object_properties.cpp | 280 |
1 files changed, 175 insertions, 105 deletions
diff --git a/src/object_properties.cpp b/src/object_properties.cpp index 89ca26274..c7f6becf0 100644 --- a/src/object_properties.cpp +++ b/src/object_properties.cpp @@ -21,104 +21,153 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "irrlichttypes_bloated.h" #include "exceptions.h" #include "util/serialize.h" +#include "util/basic_macros.h" #include <sstream> -#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" -#define PP2(x) "("<<(x).X<<","<<(x).Y<<")" - -ObjectProperties::ObjectProperties(): - hp_max(1), - physical(false), - collideWithObjects(true), - weight(5), - collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5), - visual("sprite"), - mesh(""), - visual_size(1,1), - spritediv(1,1), - initial_sprite_basepos(0,0), - is_visible(true), - makes_footstep_sound(false), - automatic_rotate(0), - stepheight(0), - automatic_face_movement_dir(false), - automatic_face_movement_dir_offset(0.0), - backface_culling(true), - nametag(""), - nametag_color(255, 255, 255, 255), - automatic_face_movement_max_rotation_per_sec(-1) +static const video::SColor NULL_BGCOLOR{0, 1, 1, 1}; + +ObjectProperties::ObjectProperties() { - textures.push_back("unknown_object.png"); - colors.push_back(video::SColor(255,255,255,255)); + textures.emplace_back("no_texture.png"); + colors.emplace_back(255,255,255,255); } std::string ObjectProperties::dump() { std::ostringstream os(std::ios::binary); - os<<"hp_max="<<hp_max; - os<<", physical="<<physical; - os<<", collideWithObjects="<<collideWithObjects; - os<<", weight="<<weight; - os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge); - os<<", visual="<<visual; - os<<", mesh="<<mesh; - os<<", visual_size="<<PP2(visual_size); - os<<", textures=["; - for(u32 i=0; i<textures.size(); i++){ - os<<"\""<<textures[i]<<"\" "; + os << "hp_max=" << hp_max; + os << ", breath_max=" << breath_max; + os << ", physical=" << physical; + os << ", collideWithObjects=" << collideWithObjects; + os << ", collisionbox=" << PP(collisionbox.MinEdge) << "," << PP(collisionbox.MaxEdge); + os << ", visual=" << visual; + os << ", mesh=" << mesh; + os << ", visual_size=" << PP(visual_size); + os << ", textures=["; + for (const std::string &texture : textures) { + os << "\"" << texture << "\" "; } - os<<"]"; - os<<", colors=["; - for(u32 i=0; i<colors.size(); i++){ - os<<"\""<<colors[i].getAlpha()<<","<<colors[i].getRed()<<","<<colors[i].getGreen()<<","<<colors[i].getBlue()<<"\" "; + os << "]"; + os << ", colors=["; + for (const video::SColor &color : colors) { + os << "\"" << color.getAlpha() << "," << color.getRed() << "," + << color.getGreen() << "," << color.getBlue() << "\" "; } - os<<"]"; - os<<", spritediv="<<PP2(spritediv); - os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos); - os<<", is_visible="<<is_visible; - os<<", makes_footstep_sound="<<makes_footstep_sound; - os<<", automatic_rotate="<<automatic_rotate; - os<<", backface_culling="<<backface_culling; + os << "]"; + os << ", spritediv=" << PP2(spritediv); + os << ", initial_sprite_basepos=" << PP2(initial_sprite_basepos); + os << ", is_visible=" << is_visible; + os << ", makes_footstep_sound=" << makes_footstep_sound; + os << ", automatic_rotate="<< automatic_rotate; + os << ", backface_culling="<< backface_culling; + os << ", glow=" << glow; os << ", nametag=" << nametag; os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed() << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" "; + + if (nametag_bgcolor) + os << ", nametag_bgcolor=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed() + << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" "; + else + os << ", nametag_bgcolor=null "; + + os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge); + os << ", pointable=" << pointable; + os << ", static_save=" << static_save; + os << ", eye_height=" << eye_height; + os << ", zoom_fov=" << zoom_fov; + os << ", use_texture_alpha=" << use_texture_alpha; + os << ", damage_texture_modifier=" << damage_texture_modifier; + os << ", shaded=" << shaded; + os << ", show_on_minimap=" << show_on_minimap; return os.str(); } +bool ObjectProperties::validate() +{ + const char *func = "ObjectProperties::validate(): "; + bool ret = true; + + // cf. where serializeString16 is used below + for (u32 i = 0; i < textures.size(); i++) { + if (textures[i].size() > U16_MAX) { + warningstream << func << "texture " << (i+1) << " has excessive length, " + "clearing it." << std::endl; + textures[i].clear(); + ret = false; + } + } + if (nametag.length() > U16_MAX) { + warningstream << func << "nametag has excessive length, clearing it." << std::endl; + nametag.clear(); + ret = false; + } + if (infotext.length() > U16_MAX) { + warningstream << func << "infotext has excessive length, clearing it." << std::endl; + infotext.clear(); + ret = false; + } + if (wield_item.length() > U16_MAX) { + warningstream << func << "wield_item has excessive length, clearing it." << std::endl; + wield_item.clear(); + ret = false; + } + + return ret; +} + void ObjectProperties::serialize(std::ostream &os) const { - writeU8(os, 1); // version - writeS16(os, hp_max); + writeU8(os, 4); // PROTOCOL_VERSION >= 37 + writeU16(os, hp_max); writeU8(os, physical); - writeF1000(os, weight); - writeV3F1000(os, collisionbox.MinEdge); - writeV3F1000(os, collisionbox.MaxEdge); - os<<serializeString(visual); - writeV2F1000(os, visual_size); + writeF32(os, 0.f); // Removed property (weight) + writeV3F32(os, collisionbox.MinEdge); + writeV3F32(os, collisionbox.MaxEdge); + writeV3F32(os, selectionbox.MinEdge); + writeV3F32(os, selectionbox.MaxEdge); + writeU8(os, pointable); + os << serializeString16(visual); + writeV3F32(os, visual_size); writeU16(os, textures.size()); - for(u32 i=0; i<textures.size(); i++){ - os<<serializeString(textures[i]); + for (const std::string &texture : textures) { + os << serializeString16(texture); } writeV2S16(os, spritediv); writeV2S16(os, initial_sprite_basepos); writeU8(os, is_visible); writeU8(os, makes_footstep_sound); - writeF1000(os, automatic_rotate); - // Added in protocol version 14 - os<<serializeString(mesh); + writeF32(os, automatic_rotate); + os << serializeString16(mesh); writeU16(os, colors.size()); - for(u32 i=0; i<colors.size(); i++){ - writeARGB8(os, colors[i]); + for (video::SColor color : colors) { + writeARGB8(os, color); } writeU8(os, collideWithObjects); - writeF1000(os,stepheight); + writeF32(os, stepheight); writeU8(os, automatic_face_movement_dir); - writeF1000(os, automatic_face_movement_dir_offset); + writeF32(os, automatic_face_movement_dir_offset); writeU8(os, backface_culling); - os << serializeString(nametag); + os << serializeString16(nametag); writeARGB8(os, nametag_color); - writeF1000(os, automatic_face_movement_max_rotation_per_sec); - os << serializeString(infotext); + writeF32(os, automatic_face_movement_max_rotation_per_sec); + os << serializeString16(infotext); + os << serializeString16(wield_item); + writeS8(os, glow); + writeU16(os, breath_max); + writeF32(os, eye_height); + writeF32(os, zoom_fov); + writeU8(os, use_texture_alpha); + os << serializeString16(damage_texture_modifier); + writeU8(os, shaded); + writeU8(os, show_on_minimap); + + if (!nametag_bgcolor) + writeARGB8(os, NULL_BGCOLOR); + else if (nametag_bgcolor.value().getAlpha() == 0) + writeARGB8(os, video::SColor(0, 0, 0, 0)); + else + writeARGB8(os, nametag_bgcolor.value()); // Add stuff only at the bottom. // Never remove anything, because we don't want new versions of this @@ -127,44 +176,65 @@ void ObjectProperties::serialize(std::ostream &os) const void ObjectProperties::deSerialize(std::istream &is) { int version = readU8(is); - if(version == 1) - { - try{ - hp_max = readS16(is); - physical = readU8(is); - weight = readF1000(is); - collisionbox.MinEdge = readV3F1000(is); - collisionbox.MaxEdge = readV3F1000(is); - visual = deSerializeString(is); - visual_size = readV2F1000(is); - textures.clear(); - u32 texture_count = readU16(is); - for(u32 i=0; i<texture_count; i++){ - textures.push_back(deSerializeString(is)); - } - spritediv = readV2S16(is); - initial_sprite_basepos = readV2S16(is); - is_visible = readU8(is); - makes_footstep_sound = readU8(is); - automatic_rotate = readF1000(is); - mesh = deSerializeString(is); - u32 color_count = readU16(is); - for(u32 i=0; i<color_count; i++){ - colors.push_back(readARGB8(is)); - } - collideWithObjects = readU8(is); - stepheight = readF1000(is); - automatic_face_movement_dir = readU8(is); - automatic_face_movement_dir_offset = readF1000(is); - backface_culling = readU8(is); - nametag = deSerializeString(is); - nametag_color = readARGB8(is); - automatic_face_movement_max_rotation_per_sec = readF1000(is); - infotext = deSerializeString(is); - }catch(SerializationError &e){} - } - else - { + if (version != 4) throw SerializationError("unsupported ObjectProperties version"); + + hp_max = readU16(is); + physical = readU8(is); + readU32(is); // removed property (weight) + collisionbox.MinEdge = readV3F32(is); + collisionbox.MaxEdge = readV3F32(is); + selectionbox.MinEdge = readV3F32(is); + selectionbox.MaxEdge = readV3F32(is); + pointable = readU8(is); + visual = deSerializeString16(is); + visual_size = readV3F32(is); + textures.clear(); + u32 texture_count = readU16(is); + for (u32 i = 0; i < texture_count; i++){ + textures.push_back(deSerializeString16(is)); } + spritediv = readV2S16(is); + initial_sprite_basepos = readV2S16(is); + is_visible = readU8(is); + makes_footstep_sound = readU8(is); + automatic_rotate = readF32(is); + mesh = deSerializeString16(is); + colors.clear(); + u32 color_count = readU16(is); + for (u32 i = 0; i < color_count; i++){ + colors.push_back(readARGB8(is)); + } + collideWithObjects = readU8(is); + stepheight = readF32(is); + automatic_face_movement_dir = readU8(is); + automatic_face_movement_dir_offset = readF32(is); + backface_culling = readU8(is); + nametag = deSerializeString16(is); + nametag_color = readARGB8(is); + automatic_face_movement_max_rotation_per_sec = readF32(is); + infotext = deSerializeString16(is); + wield_item = deSerializeString16(is); + glow = readS8(is); + breath_max = readU16(is); + eye_height = readF32(is); + zoom_fov = readF32(is); + use_texture_alpha = readU8(is); + try { + damage_texture_modifier = deSerializeString16(is); + u8 tmp = readU8(is); + if (is.eof()) + return; + shaded = tmp; + tmp = readU8(is); + if (is.eof()) + return; + show_on_minimap = tmp; + + auto bgcolor = readARGB8(is); + if (bgcolor != NULL_BGCOLOR) + nametag_bgcolor = bgcolor; + else + nametag_bgcolor = nullopt; + } catch (SerializationError &e) {} } |