aboutsummaryrefslogtreecommitdiff
path: root/lib/lua/src/lcode.h
blob: b941c607212bf5255be169d202af6617b5a99ed7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
** $Id: lcode.h,v 1.48.1.1 2007/12/27 13:02:25 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/

#ifndef lcode_h
#define lcode_h

#include "llex.h"
#include "lobject.h"
#include "lopcodes.h"
#include "lparser.h"


/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)


/*
** grep "ORDER OPR" if you change these enums
*/
typedef enum BinOpr {
  OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
  OPR_CONCAT,
  OPR_NE, OPR_EQ,
  OPR_LT, OPR_LE, OPR_GT, OPR_GE,
  OPR_AND, OPR_OR,
  OPR_NOBINOPR
} BinOpr;


typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;


#define getcode(fs,e)	((fs)->f->code[(e)->u.s.info])

#define luaK_codeAsBx(fs,o,A,sBx)	luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx)

#define luaK_setmultret(fs,e)	luaK_setreturns(fs, e, LUA_MULTRET)

LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e);
LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults);
LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_jump (FuncState *fs);
LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret);
LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target);
LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list);
LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2);
LUAI_FUNC int luaK_getlabel (FuncState *fs);
LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v);
LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);


#endif
()); for(std::map<std::string, s16>::const_iterator i = damageGroups.begin(); i != damageGroups.end(); i++){ os<<serializeString(i->first); writeS16(os, i->second); } } } void ToolCapabilities::deSerialize(std::istream &is) { int version = readU8(is); if(version != 1 && version != 2) throw SerializationError( "unsupported ToolCapabilities version"); full_punch_interval = readF1000(is); max_drop_level = readS16(is); groupcaps.clear(); u32 groupcaps_size = readU32(is); for(u32 i=0; i<groupcaps_size; i++){ std::string name = deSerializeString(is); ToolGroupCap cap; cap.uses = readS16(is); cap.maxlevel = readS16(is); u32 times_size = readU32(is); for(u32 i=0; i<times_size; i++){ int level = readS16(is); float time = readF1000(is); cap.times[level] = time; } groupcaps[name] = cap; } if(version == 2) { u32 damage_groups_size = readU32(is); for(u32 i=0; i<damage_groups_size; i++){ std::string name = deSerializeString(is); s16 rating = readS16(is); damageGroups[name] = rating; } } } DigParams getDigParams(const ItemGroupList &groups, const ToolCapabilities *tp, float time_from_last_punch) { //infostream<<"getDigParams"<<std::endl; /* Check group dig_immediate */ switch(itemgroup_get(groups, "dig_immediate")){ case 2: //infostream<<"dig_immediate=2"<<std::endl; return DigParams(true, 0.5, 0, "dig_immediate"); case 3: //infostream<<"dig_immediate=3"<<std::endl; return DigParams(true, 0.0, 0, "dig_immediate"); default: break; } // Values to be returned (with a bit of conversion) bool result_diggable = false; float result_time = 0.0; float result_wear = 0.0; std::string result_main_group = ""; int level = itemgroup_get(groups, "level"); //infostream<<"level="<<level<<std::endl; for(std::map<std::string, ToolGroupCap>::const_iterator i = tp->groupcaps.begin(); i != tp->groupcaps.end(); i++){ const std::string &name = i->first; //infostream<<"group="<<name<<std::endl; const ToolGroupCap &cap = i->second; int rating = itemgroup_get(groups, name); float time = 0; bool time_exists = cap.getTime(rating, &time); if(!result_diggable || time < result_time){ if(cap.maxlevel >= level && time_exists){ result_diggable = true; int leveldiff = cap.maxlevel - level; result_time = time / MYMAX(1, leveldiff); if(cap.uses != 0) result_wear = 1.0 / cap.uses / pow(3.0, (double)leveldiff); else result_wear = 0; result_main_group = name; } } } //infostream<<"result_diggable="<<result_diggable<<std::endl; //infostream<<"result_time="<<result_time<<std::endl; //infostream<<"result_wear="<<result_wear<<std::endl; if(time_from_last_punch < tp->full_punch_interval){ float f = time_from_last_punch / tp->full_punch_interval; //infostream<<"f="<<f<<std::endl; result_time /= f; result_wear /= f; } u16 wear_i = 65535.*result_wear; return DigParams(result_diggable, result_time, wear_i, result_main_group); } DigParams getDigParams(const ItemGroupList &groups, const ToolCapabilities *tp) { return getDigParams(groups, tp, 1000000); } HitParams getHitParams(const ItemGroupList &armor_groups, const ToolCapabilities *tp, float time_from_last_punch) { s16 damage = 0; float full_punch_interval = tp->full_punch_interval; for(std::map<std::string, s16>::const_iterator i = tp->damageGroups.begin(); i != tp->damageGroups.end(); i++){ s16 armor = itemgroup_get(armor_groups, i->first); damage += i->second * rangelim(time_from_last_punch * full_punch_interval, 0.0, 1.0) * armor / 100.0; } return HitParams(damage, 0); } HitParams getHitParams(const ItemGroupList &armor_groups, const ToolCapabilities *tp) { return getHitParams(armor_groups, tp, 1000000); } PunchDamageResult getPunchDamage( const ItemGroupList &armor_groups, const ToolCapabilities *toolcap, const ItemStack *punchitem, float time_from_last_punch ){ bool do_hit = true; { if(do_hit && punchitem){ if(itemgroup_get(armor_groups, "punch_operable") && (toolcap == NULL || punchitem->name == "")) do_hit = false; } if(do_hit){ if(itemgroup_get(armor_groups, "immortal")) do_hit = false; } } PunchDamageResult result; if(do_hit) { HitParams hitparams = getHitParams(armor_groups, toolcap, time_from_last_punch); result.did_punch = true; result.wear = hitparams.wear; result.damage = hitparams.hp; } return result; }