Skip to content

Instantly share code, notes, and snippets.

@angavrilov
Created May 8, 2011 18:44
Show Gist options
  • Save angavrilov/961587 to your computer and use it in GitHub Desktop.
Save angavrilov/961587 to your computer and use it in GitHub Desktop.
895d540: compute creature temperature
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