add support for tools that throw objects, add bow and arrow
This commit is contained in:
parent
0460fa439b
commit
bb7cbedc7e
Binary file not shown.
After Width: | Height: | Size: 492 B |
Binary file not shown.
After Width: | Height: | Size: 484 B |
|
@ -1602,8 +1602,9 @@ void Client::throwItem(v3f dir, u16 item)
|
|||
writeU16(buf, TOSERVER_THROWITEM);
|
||||
os.write((char*)buf, 2);
|
||||
|
||||
// Write position
|
||||
v3f pf = player->getEyePosition();
|
||||
// Write position - this is one node ahead of the player
|
||||
// to prevent damage occurring to the thrower
|
||||
v3f pf = player->getEyePosition()+(dir*BS);
|
||||
v3s32 position(pf.X*100, pf.Y*100, pf.Z*100);
|
||||
writeV3S32(buf,position);
|
||||
os.write((char*)buf, 12);
|
||||
|
|
|
@ -233,7 +233,7 @@ MobCAO::MobCAO():
|
|||
m_shooting_unset_timer(0),
|
||||
m_walking(false),
|
||||
m_walking_unset_timer(0),
|
||||
m_draw_type(MDT_NOTHING)
|
||||
m_draw_type(MDT_AUTO)
|
||||
{
|
||||
ClientActiveObject::registerType(getType(), create);
|
||||
}
|
||||
|
@ -251,14 +251,19 @@ void MobCAO::addToScene(scene::ISceneManager *smgr)
|
|||
|
||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||
MobFeatures m = content_mob_features(m_content);
|
||||
if (m.model != "") {
|
||||
if (m.texture_display == MDT_EXTRUDED) {
|
||||
ExtrudedSpriteSceneNode *node = new ExtrudedSpriteSceneNode(smgr->getRootSceneNode(),smgr,-1,v3f(0,0,0),v3f(0,0,0),v3f(5,5,5));
|
||||
node->setVisible(true);
|
||||
node->setSprite(g_texturesource->getTextureRaw(m.texture));
|
||||
m_node = (scene::IMeshSceneNode*)node;
|
||||
m_draw_type = MDT_EXTRUDED;
|
||||
updateNodePos();
|
||||
}else if (m.model != "") {
|
||||
scene::IAnimatedMesh* mesh = createModelMesh(smgr,m.model.c_str(),true);
|
||||
if (!mesh)
|
||||
return;
|
||||
|
||||
scene::IAnimatedMeshSceneNode* node;
|
||||
|
||||
node = smgr->addAnimatedMeshSceneNode(mesh);
|
||||
scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode(mesh);
|
||||
|
||||
if (node) {
|
||||
int s;
|
||||
|
@ -334,6 +339,8 @@ void MobCAO::updateLight(u8 light_at_pos)
|
|||
setMeshVerticesColor(((scene::IAnimatedMeshSceneNode*)m_node)->getMesh(), color);
|
||||
}else if (m_draw_type == MDT_SPRITE) {
|
||||
((scene::IBillboardSceneNode*)m_node)->setColor(color);
|
||||
}else if (m_draw_type == MDT_EXTRUDED) {
|
||||
((ExtrudedSpriteSceneNode*)m_node)->updateLight(li);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -357,6 +364,8 @@ void MobCAO::updateNodePos()
|
|||
rot.Y = (90-pos_translator.yaw_show)+content_mob_features(m_content).model_rotation.Y;
|
||||
}else if (m_draw_type == MDT_SPRITE) {
|
||||
rot.Y = pos_translator.yaw_show+content_mob_features(m_content).model_rotation.Y;
|
||||
}else if (m_draw_type == MDT_EXTRUDED) {
|
||||
rot.Y = (180-pos_translator.yaw_show)+content_mob_features(m_content).model_rotation.Y;
|
||||
}
|
||||
m_node->setRotation(rot);
|
||||
}
|
||||
|
@ -488,6 +497,7 @@ void MobCAO::initialize(const std::string &data)
|
|||
pos_translator.init(m_position);
|
||||
// content
|
||||
m_content = readU16(is);
|
||||
m_draw_type = content_mob_features(m_content).texture_display;
|
||||
// yaw
|
||||
m_yaw = readF1000(is);
|
||||
// speed
|
||||
|
|
|
@ -1096,4 +1096,15 @@ void content_craftitem_init()
|
|||
crafting::set1Any2Recipe(CONTENT_CRAFTITEM_LEATHER,CONTENT_CRAFTITEM_DYE_BLACK,CONTENT_CRAFTITEM_LEATHER_BLACK);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_CRAFTITEM_ARROW;
|
||||
f = &g_content_craftitem_features[i];
|
||||
f->content = CONTENT_CRAFTITEM_ARROW;
|
||||
f->texture = "arrow.png";
|
||||
f->name = "arrow";
|
||||
f->description = wgettext("Arrow");
|
||||
f->shot_item = CONTENT_MOB_ARROW;
|
||||
crafting::set1over4Recipe(CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_CRAFTITEM_STICK,CONTENT_CRAFTITEM_ARROW);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,8 @@ struct CraftItemFeatures {
|
|||
content_t drop_item;
|
||||
// used by snowballs and such... things that are thrown
|
||||
content_t thrown_item;
|
||||
// used by arrows and such... things that are shot by a tool
|
||||
content_t shot_item;
|
||||
|
||||
CraftItemFeatures():
|
||||
content(CONTENT_IGNORE),
|
||||
|
@ -57,7 +59,8 @@ struct CraftItemFeatures {
|
|||
edible(0),
|
||||
drop_count(-1),
|
||||
drop_item(CONTENT_IGNORE),
|
||||
thrown_item(CONTENT_IGNORE)
|
||||
thrown_item(CONTENT_IGNORE),
|
||||
shot_item(CONTENT_IGNORE)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -166,5 +169,6 @@ CraftItemFeatures & content_craftitem_features(std::string subname);
|
|||
#define CONTENT_CRAFTITEM_LEATHER_RED (CONTENT_CRAFTITEM_MASK | 0x68)
|
||||
#define CONTENT_CRAFTITEM_LEATHER_YELLOW (CONTENT_CRAFTITEM_MASK | 0x69)
|
||||
#define CONTENT_CRAFTITEM_LEATHER_BLACK (CONTENT_CRAFTITEM_MASK | 0x6A)
|
||||
#define CONTENT_CRAFTITEM_ARROW (CONTENT_CRAFTITEM_MASK | 0x6B)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -530,4 +530,21 @@ void content_mob_init()
|
|||
f->contact_place_node = CONTENT_SNOW;
|
||||
f->contact_drop_item = CONTENT_CRAFTITEM_SNOW_BALL;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
|
||||
|
||||
i = CONTENT_MOB_ARROW;
|
||||
f = &g_content_mob_features[i];
|
||||
f->content = i;
|
||||
f->level = MOB_AGGRESSIVE;
|
||||
f->setTexture("arrow.png");
|
||||
f->texture_display = MDT_EXTRUDED;
|
||||
f->model_offset = v3f(0,0.2,0);
|
||||
f->punch_action = MPA_IGNORE;
|
||||
f->motion = MM_THROWN;
|
||||
f->motion_type = MMT_FLY;
|
||||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->lifetime = 20.0;
|
||||
f->contact_drop_item = CONTENT_CRAFTITEM_ARROW;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
|
||||
}
|
||||
|
|
|
@ -79,11 +79,14 @@ enum MobAnimationKey
|
|||
enum MobDrawType
|
||||
{
|
||||
MDT_NOTHING = 0,
|
||||
MDT_AUTO,
|
||||
MDT_MODEL,
|
||||
MDT_BLOCK,
|
||||
MDT_SPRITE
|
||||
MDT_SPRITE,
|
||||
MDT_EXTRUDED
|
||||
};
|
||||
|
||||
|
||||
#define CONTENT_MOB_MASK 0x2000
|
||||
|
||||
struct MobFeatures {
|
||||
|
@ -93,6 +96,7 @@ struct MobFeatures {
|
|||
TileSpec tiles[6];
|
||||
#endif
|
||||
std::string texture;
|
||||
MobDrawType texture_display;
|
||||
std::string model;
|
||||
std::map<MobAnimationKey,int> animations;
|
||||
v3f model_scale;
|
||||
|
@ -219,6 +223,7 @@ struct MobFeatures {
|
|||
{
|
||||
content = CONTENT_IGNORE;
|
||||
texture = "";
|
||||
texture_display = MDT_AUTO;
|
||||
model = "";
|
||||
model_scale = v3f(1.0,1.0,1.0);
|
||||
model_offset = v3f(0,0,0);
|
||||
|
@ -307,5 +312,6 @@ void content_mob_init();
|
|||
#define CONTENT_MOB_TAMEWOLF (CONTENT_MOB_MASK | 0x0C)
|
||||
#define CONTENT_MOB_SHEEP (CONTENT_MOB_MASK | 0x0D)
|
||||
#define CONTENT_MOB_SNOWBALL (CONTENT_MOB_MASK | 0x0E)
|
||||
#define CONTENT_MOB_ARROW (CONTENT_MOB_MASK | 0x0F)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1093,6 +1093,8 @@ void MobSAO::stepMotionThrown(float dtime)
|
|||
m_base_position += m_speed * dtime;
|
||||
m_speed.Y -= 10.0*BS*dtime;
|
||||
|
||||
m_yaw = wrapDegrees_180(180./PI*atan2(m_speed.Z, m_speed.X));
|
||||
|
||||
v3s16 pos_i = floatToInt(m_base_position, BS);
|
||||
if (!checkFreePosition(pos_i)) {
|
||||
if (m.contact_explosion_diameter > 0)
|
||||
|
@ -1118,6 +1120,8 @@ void MobSAO::stepMotionConstant(float dtime)
|
|||
MobFeatures m = content_mob_features(m_content);
|
||||
m_base_position += m_speed * dtime;
|
||||
|
||||
m_yaw = wrapDegrees_180(180./PI*atan2(m_speed.Z, m_speed.X));
|
||||
|
||||
v3s16 pos_i = floatToInt(m_base_position, BS);
|
||||
if (!checkFreePosition(pos_i)) {
|
||||
if (m.contact_explosion_diameter > 0)
|
||||
|
|
|
@ -505,4 +505,23 @@ void content_toolitem_init()
|
|||
crafting::setSpearRecipe(CONTENT_CRAFTITEM_STEEL_INGOT,CONTENT_TOOLITEM_STEELSPEAR);
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
|
||||
i = CONTENT_TOOLITEM_BOW;
|
||||
f = &g_content_toolitem_features[i];
|
||||
f->content = i;
|
||||
f->texture = "tool_bow.png";
|
||||
f->name = "bow";
|
||||
f->description = wgettext("Bow");
|
||||
f->type = TT_SPECIAL;
|
||||
f->thrown_item = CONTENT_CRAFTITEM_ARROW;
|
||||
{
|
||||
content_t r[9] = {
|
||||
CONTENT_CRAFTITEM_STRING, CONTENT_CRAFTITEM_STICK, CONTENT_IGNORE,
|
||||
CONTENT_CRAFTITEM_STRING, CONTENT_IGNORE, CONTENT_CRAFTITEM_STICK,
|
||||
CONTENT_CRAFTITEM_STRING, CONTENT_CRAFTITEM_STICK, CONTENT_IGNORE
|
||||
};
|
||||
crafting::setRecipe(r,i,1);
|
||||
}
|
||||
lists::add("craftguide",i);
|
||||
lists::add("creative",i);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,8 @@ struct ToolItemFeatures {
|
|||
f32 hardness;
|
||||
// the dig time of this tool
|
||||
f32 dig_time;
|
||||
// used for eg. bows throwing an arrow
|
||||
content_t thrown_item;
|
||||
|
||||
ToolItemFeatures():
|
||||
content(CONTENT_IGNORE),
|
||||
|
@ -53,7 +55,8 @@ struct ToolItemFeatures {
|
|||
liquids_pointable(false),
|
||||
type(TT_NONE),
|
||||
hardness(0.),
|
||||
dig_time(3.)
|
||||
dig_time(3.),
|
||||
thrown_item(CONTENT_IGNORE)
|
||||
{}
|
||||
};
|
||||
struct DiggingProperties
|
||||
|
@ -114,5 +117,6 @@ ToolItemFeatures & content_toolitem_features(std::string subname);
|
|||
#define CONTENT_TOOLITEM_STONESPEAR (CONTENT_TOOLITEM_MASK | 0x1D)
|
||||
#define CONTENT_TOOLITEM_FLINTSPEAR (CONTENT_TOOLITEM_MASK | 0x1E)
|
||||
#define CONTENT_TOOLITEM_STEELSPEAR (CONTENT_TOOLITEM_MASK | 0x1F)
|
||||
#define CONTENT_TOOLITEM_BOW (CONTENT_TOOLITEM_MASK | 0x20)
|
||||
|
||||
#endif
|
||||
|
|
10
src/game.cpp
10
src/game.cpp
|
@ -1678,14 +1678,16 @@ void the_game(
|
|||
bool left_punch_muted = false;
|
||||
|
||||
InventoryItem *wield = (InventoryItem*)client.getLocalPlayer()->getWieldItem();
|
||||
InventoryList *ilist;
|
||||
if (
|
||||
wield
|
||||
&& (
|
||||
content_craftitem_features(wield->getContent()).thrown_item != CONTENT_IGNORE
|
||||
//|| (
|
||||
//content_toolitem_features(wield->getContent()).thrown_item != CONTENT_IGNORE
|
||||
//&& client.getLocalPlayer()->inventory.find(content_toolitem_features(wield->getContent()).thrown_item) > -1
|
||||
//)
|
||||
|| (
|
||||
content_toolitem_features(wield->getContent()).thrown_item != CONTENT_IGNORE
|
||||
&& (ilist = client.getLocalPlayer()->inventory.getList("main")) != NULL
|
||||
&& ilist->findItem(content_toolitem_features(wield->getContent()).thrown_item) != NULL
|
||||
)
|
||||
) && input->getLeftClicked()
|
||||
) {
|
||||
client.throwItem(camera_direction,g_selected_item);
|
||||
|
|
|
@ -672,6 +672,19 @@ InventoryItem * InventoryList::takeItem(u32 i, u32 count)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
InventoryItem * InventoryList::findItem(content_t c, u16 *item_i)
|
||||
{
|
||||
for (u32 i=0; i<m_items.size(); i++) {
|
||||
InventoryItem *item = getItem(i);
|
||||
if (item && item->getContent() == c) {
|
||||
if (item_i)
|
||||
*item_i = i;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void InventoryList::decrementMaterials(u16 count)
|
||||
{
|
||||
for (u32 i=0; i<m_items.size(); i++) {
|
||||
|
|
|
@ -591,6 +591,9 @@ public:
|
|||
// Returns NULL if couldn't take any.
|
||||
InventoryItem * takeItem(u32 i, u32 count);
|
||||
|
||||
// find a stack containing an item
|
||||
InventoryItem *findItem(content_t item, u16 *item_i = NULL);
|
||||
|
||||
// Decrements amount of every material item
|
||||
void decrementMaterials(u16 count);
|
||||
|
||||
|
|
|
@ -2125,8 +2125,20 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
|
|||
|
||||
content_t thrown = content_craftitem_features(item->getContent()).thrown_item;
|
||||
// We can throw it, right?
|
||||
if (thrown == CONTENT_IGNORE)
|
||||
return;
|
||||
if (thrown == CONTENT_IGNORE) {
|
||||
// it may be a tool that throws something else
|
||||
thrown = content_toolitem_features(item->getContent()).thrown_item;
|
||||
if (thrown == CONTENT_IGNORE)
|
||||
return;
|
||||
u16 i;
|
||||
item = ilist->findItem(thrown,&i);
|
||||
if (!item)
|
||||
return;
|
||||
// We can throw it, right?
|
||||
thrown = content_craftitem_features(item->getContent()).shot_item;
|
||||
if (thrown == CONTENT_IGNORE)
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_settings->getBool("droppable_inventory") == false || (getPlayerPrivs(player) & PRIV_BUILD) == 0) {
|
||||
infostream<<"Not allowing player to drop item: creative mode and no build privs"<<std::endl;
|
||||
|
|
Loading…
Reference in New Issue