Created
May 8, 2011 18:44
-
-
Save angavrilov/961587 to your computer and use it in GitHub Desktop.
895d540: compute creature temperature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
args: eax, edx, ecx, stack | |
args: creature, arg_temp, arg2#1, arg3/*10*/ | |
/* offsets: | |
creature: | |
0x308 vector* body_part_info_vec | |
0x654 vector body_part_temp_vec | |
inventory item: | |
0x0 item* item | |
0x6 short body_part_id | |
caste raw: | |
0x92 unsigned short homeo_temp; | |
0x98 unsigned short fixed_temp; | |
body part raw: | |
0x8 signed short con_part_id // parent part | |
0x60 unsigned short min_temp | |
0x62 unsigned short max_temp | |
0x64 unsigned short temp_factor | |
*/ | |
struct TempRec { | |
// Temperature is split into an integer part, and | |
// a remainder. The factor is stored elsewhere. | |
unsigned short temp, temp_rem; | |
inline void incrementTemp(long delta, unsigned short factor) { | |
if (factor == 60001 || delta == 0) return; | |
if (factor > 1) { | |
long tmp = temp*factor + delta + temp_rem; | |
if (tmp < 0) tmp = 0; | |
temp_rem = tmp%factor; | |
tmp = tmp/factor; | |
if (tmp >= 60001) tmp = 60000; | |
temp = tmp; | |
} else { | |
long tmp = temp + delta; | |
if (tmp < 0) tmp = 0; | |
if (tmp >= 60001) tmp = 60000; | |
temp = tmp; | |
temp_rem = 0; | |
} | |
} | |
}; | |
inline void reduceTempDelta(int &delta, unsigned margin, unsigned factor) { | |
if (delta > 0 && margin > 0) { | |
delta -= margin/factor + (margin%factor > random(factor)); | |
if (delta <= 1) | |
delta = 1; | |
} | |
} | |
if (!d_init_flags.has_flag(0)) return; // temperature | |
// creature.race: 44; creature.caste: a4 | |
fixed_temp = (valid creature->race and caste | |
? creature_type_vector[race]->caste_vector[caste]->fixed_temp | |
: 0); | |
// 895d5df | |
tvec = creature->inventory_vector; | |
for (i = tvec.length-1; i >= 0; i = min<unsigned>(i,tvec.length)-1) { | |
// inv_item: 0 = item | |
if (arg2 == 0) { | |
inv_item = tvec[i]; | |
} else { | |
if (i >=#4u tvec.length) continue; | |
inv_item = tvec[i]; | |
if (creature->body_part_temp_vec.length | |
&& inv_item->body_part_id != -1 | |
&& (item_temp = inv_item->item->vcall<0x9c>()#2u) != 60001) | |
{ | |
// 895d657 | |
TempRec *body_part_temp = creature->body_part_temp_vec[inv_item->body_part_id]; | |
cur_temp = body_part_temp->temp; | |
if (fixed_temp != 60001) | |
goto done; | |
if (arg_temp <= item_temp && item_temp < cur_temp && arg_temp < cur_temp) | |
goto done; | |
if (cur_temp < item_temp && item_temp <= arg_temp && cur_temp < arg_temp) | |
goto done; | |
// 895e2f5 | |
body_part_info = creature->body_part_info_vec->[inv_item->6#2s]; | |
if (item_temp != cur_temp) { | |
// 895e48b; 895e320 | |
td = 10*signed(item_temp - cur_temp); | |
body_part_temp->incrementTemp(td, body_part_info->temp_factor); | |
if (cur_temp != body_part_temp->temp) { | |
cur_temp = body_part_temp->temp; | |
if (creature->flags3 & 1) { | |
// damage? | |
if ((cur_temp >= body_part_info->max_temp // fat melting, etc | |
&& body_part_info->max_temp != 60001) | |
|| (cur_temp <= body_part_info->min_temp // water freezing | |
&& body_part_info->min_temp != 60001)) | |
creature->flags3 &= ~0x100; | |
} | |
} | |
} | |
done: | |
if (cur_temp != 60001) | |
inv_item->item->vcall<0xa0>(cur_temp,10); | |
} | |
} | |
inv_item->item->vcall<0x238>(arg_temp, 1, 1, arg2, 1); | |
} | |
// 895d83b | |
if (arg2 && creature->5ac.length) { | |
// 78: i*4 | |
for (i/*7c*/ = creature->5ac.length-1; i >= 0; i--) { | |
t_70 = creature->5ac[i]; | |
t_5c = t_70->8; | |
if (t_5c + 1 == 0) { | |
if (t_70->18 == -1) continue; | |
td = binsearch(940b1f0, key:$->14, value:t_70->18); // item vector | |
if (!td) continue; | |
t_74 = td->vcall<0x9c>(); | |
} else { | |
if (t_70->0 == -1) continue; | |
td = binsearch(940b174, key:$->id, value:t70->0); // creature vector | |
if (!td) continue; | |
if (!td->body_part_temp_vec.length) continue; | |
t_74 = td->body_part_temp_vec[t_5c]->temp; | |
} | |
if (t_74 == 60001) continue; | |
// 895de73 | |
if (t_70->4 == -1) { | |
// 895e168 | |
if (t70->14 == -1) continue; | |
// item vector | |
td = binsearch(940b1f0, key:x->14, value:t_70->14); | |
if (td) | |
td->vcall<0x238>(t_74, 1, 0, 0, 10); | |
} else { | |
88f04c0(creature); | |
td = creature->body_part_info_vec; | |
ta = t_70->4#2s; | |
if (ta >= 0 && ta < td.length && td[ta]->c.has_flag(0xd)) { | |
t = td[ta]->con_part_id; | |
if (t != -1) ta = t; | |
} | |
idx_84 = creature->748[ta]#2s; | |
if (ta+1 < creature->748.length) { | |
idx_6c = creature->748[ta+1]-1; | |
} else { | |
idx_6c = creature->754.length-1; | |
} | |
for (i = idx_6c; i >= idx_84; i--) { | |
t_5c = min(creature->760[i]#2s, 0x64); | |
if (creature->754[i] != -1) { | |
// item vector | |
ts = binsearch(940b1f0, key:x->14, value:creature->754[i]); | |
if (ts) | |
ts->vcall<0x238>(t_74, 1, 1, 0, 10); | |
} | |
if (t_5c == 0x64) break; | |
if (... random ... t_5c ...) break; | |
} | |
if (i != idx_84-1) | |
computeBodyPartTemp(creature, t_74, t_70->4, 10, 1); | |
} | |
} | |
} | |
// 895d920 | |
if (!arg2 || creature->6fc < 9451b38#4) { | |
if (arg2) | |
creature->6fc = 9451b38#4; | |
homeo_temp = (valid race & caste ? $caste_info->homeo_temp : 0); // 84 | |
creature->computeClothingInsulation(); | |
if (!creature->body_part_temp_vec.length) { | |
creature->body_part_temp_vec.resize(creature->270.length); | |
for i in 0..creature->270.length-1 | |
creature->body_part_temp_vec[i] = new TempRec(10050, 0); | |
creature->flags3 &= ~0x100; | |
} | |
fixed_temp = (valid race & caste ? $caste_info->fixed_temp : 0); // 68 | |
if (creature->body_part_temp_vec.length) { | |
temp_cnt = 0; // 6c | |
temp_sum = 0; // 70 | |
for (i = 0; i < creature->body_part_temp_vec.length; i++) { | |
body_part_info = creature->body_part_info_vec->[i]; // 64 | |
TempRec *body_part_temp = creature->body_part_temp_vec[i]; // edi | |
if (fixed_temp == 60001) { | |
// t_74 = body_part_info->temp_factor; | |
cur_temp = body_part_temp->temp; // eax | |
if (cur_temp != arg_temp) { | |
if (cur_temp < arg_temp) | |
tc = arg3*(arg_temp - cur_temp); | |
else | |
tc = arg3*(cur_temp - arg_temp); | |
// 895dc84 | |
reduceTempDelta(tc, creature->730[i]#2s, 4); | |
// 895da85 | |
tc = (arg_temp < cur_temp ? -tc : tc); | |
body_part_temp->incrementTemp(tc, body_part_info->temp_factor); | |
cur_temp = body_part_temp->temp; | |
} | |
// 895dadc | |
if (arg2) { | |
if (homeo_temp != 60001 && homeo_temp != cur_temp) { | |
t_2c = 0x1e; | |
if (cur_temp > homeo_temp) { | |
// 898db33 | |
reduceTempDelta(t_2c, creature->730[i]#2s, 16); | |
t_2c = -t_2c; | |
} | |
body_part_temp->incrementTemp(t_2c, body_part_info->temp_factor); | |
cur_temp = body_part_temp->temp; | |
} | |
// 895dbc8 | |
if ((tc = body_part_info->con_part_id) != -1) { | |
t_74 = creature->body_part_temp_vec[tc]->temp; | |
if (t_74 - cur_temp > 4 || cur_temp - t_74 > 4) { | |
computeBodyPartTemp(creature,cur_temp,tc,3,0); | |
computeBodyPartTemp(creature,t_74,i,3,0); | |
} | |
} | |
} | |
} | |
if (arg2 && body_part_temp->temp != 60001) { | |
temp_sum += body_part_temp->temp; | |
temp_cnt++; | |
} | |
} | |
// 895d71b | |
if (temp_cnt) { | |
edi = temp_sum/temp_cnt; | |
int x = -30000, y, z; | |
if (creature->flags1.caged) { | |
for obj in creature->f4[] { | |
if (obj->vcall<0x8>() == 0xb && | |
(t = obj->vcall<0xc>()) != 0) { | |
85d1880(t,&x,&y,&z); | |
break; | |
} | |
} | |
} else { | |
x = creature->pos.x; | |
y = creature->pos.y; | |
z = creature->pos.z; | |
} | |
89c6310(world,x,y,z,edi,7,8); | |
} | |
} | |
// 895d807 | |
if (fixed_temp == 60001 && arg2) | |
8957d70(creature); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment