void ShowInfoText() { DebugBox frameInfo = DebugBox(Vec2i(10, 10), "FrameInfo"); frameInfo.add("Platform time", prettyUs(toUs(g_platformTime.frameStart()))); frameInfo.add("Game time", prettyUs(toUs(g_gameTime.now()))); frameInfo.add("Prims", EERIEDrawnPolys); frameInfo.add("Particles", getParticleCount()); frameInfo.add("Sparks", ParticleSparkCount()); frameInfo.add("Polybooms", long(PolyBoomCount())); frameInfo.print(); DebugBox camBox = DebugBox(Vec2i(10, frameInfo.size().y + 5), "Camera"); camBox.add("Position", g_camera->m_pos); camBox.add("Rotation", g_camera->angle); camBox.add("Focal", g_camera->focal); camBox.print(); DebugBox playerBox = DebugBox(Vec2i(10, camBox.size().y + 5), "Player"); playerBox.add("Position", player.pos); playerBox.add("Rotation", player.angle); playerBox.add("Velocity", player.physics.velocity); EERIEPOLY * ep = CheckInPoly(player.pos); float truePolyY = -666.66f; if(ep) { float tempY = 0.f; if(GetTruePolyY(ep, player.pos, &tempY)) { truePolyY = tempY; } } ep = CheckInPoly(player.pos + Vec3f(0.f, -10.f, 0.f)); float slope = 0.f; if(ep) slope = ep->norm.y; long zap = IsAnyPolyThere(player.pos.x, player.pos.z); playerBox.add("Ground Slope", slope); playerBox.add("Ground truePolyY", truePolyY); playerBox.add("Ground POLY", zap); playerBox.add("Color", CURRENT_PLAYER_COLOR); playerBox.add("Stealth", GetPlayerStealth()); playerBox.add("Jump", player.jumplastposition); playerBox.add("OFFGRND", (!player.onfirmground ? "OFFGRND" : "")); playerBox.add("Life", player.lifePool); playerBox.add("Mana", player.manaPool); playerBox.add("Poisoned", player.poison); playerBox.add("Hunger", player.hunger); playerBox.add("Magic", static_cast<long>(player.doingmagic)); playerBox.print(); DebugBox miscBox = DebugBox(Vec2i(10, playerBox.size().y + 5), "Misc"); miscBox.add(arx_name + " version", arx_version); miscBox.add("Level", LastLoadedScene.string()); miscBox.add("Spell failed seq", LAST_FAILED_SEQUENCE); miscBox.add("Cinema", cinematicBorder.CINEMA_DECAL); miscBox.add("Mouse", Vec2i(DANAEMouse)); miscBox.add("Pathfind queue", EERIE_PATHFINDER_Get_Queued_Number()); miscBox.add("Pathfind status", EERIE_PATHFINDER_Is_Busy() ? "Working" : "Idled"); miscBox.print(); { struct ScriptDebugReport { std::string entityName; long events; long sends; ScriptDebugReport() : entityName("") , events(0) , sends(0) {} }; ScriptDebugReport maxEvents; Entity * io = ARX_SCRIPT_Get_IO_Max_Events(); if(io) { maxEvents.entityName = io->idString(); maxEvents.events = io->stat_count; } ScriptDebugReport maxSender; io = ARX_SCRIPT_Get_IO_Max_Events_Sent(); if(io) { maxSender.entityName = io->idString(); maxSender.sends = io->stat_sent; } DebugBox scriptBox = DebugBox(Vec2i(10, miscBox.size().y + 5), "Script"); scriptBox.add("Events", ScriptEvent::totalCount); scriptBox.add("Timers", ARX_SCRIPT_CountTimers()); scriptBox.add("Max events", maxEvents.entityName); scriptBox.add("Max events#", maxEvents.events); scriptBox.add("Max sender", maxSender.entityName); scriptBox.add("Max sender#", maxSender.sends); scriptBox.print(); } Entity * io = entities.get(LastSelectedIONum); if(io) { DebugBox entityBox = DebugBox(Vec2i(500, 10), "Entity " + io->idString()); entityBox.add("Pos", io->pos); entityBox.add("Angle", io->angle); entityBox.add("Room", static_cast<long>(io->room)); entityBox.add("Move", io->move); entityBox.add("Flags", flagNames(EntityFlagNames, io->ioflags)); entityBox.add("GFlags", flagNames(GameFlagNames, io->gameFlags)); entityBox.add("Show", entityVisilibityToString(io->show)); entityBox.print(); if(io->ioflags & IO_NPC) { IO_NPCDATA * npcData = io->_npcdata; DebugBox npcBox = DebugBox(Vec2i(500, entityBox.size().y + 5), "NPC"); npcBox.add("Life", npcData->lifePool); npcBox.add("Mana", npcData->manaPool); npcBox.add("Poisoned", npcData->poisonned); npcBox.add("ArmorClass", ARX_INTERACTIVE_GetArmorClass(io)); npcBox.add("Absorb", npcData->absorb); npcBox.add("Moveproblem", npcData->moveproblem); npcBox.add("Pathfind listpos", static_cast<long>(npcData->pathfind.listpos)); npcBox.add("Pathfind listnb", npcData->pathfind.listnb); npcBox.add("Pathfind targ", npcData->pathfind.truetarget.handleData()); npcBox.add("Behavior", flagNames(BehaviourFlagNames, npcData->behavior)); // TODO should those really be flags ? PathfindFlags pflag = io->_npcdata->pathfind.flags; std::string pflags; if(pflag & PATHFIND_ALWAYS) pflags += "ALWAYS "; if(pflag & PATHFIND_ONCE) pflags += "ONCE "; if(pflag & PATHFIND_NO_UPDATE) pflags += "NO_UPDATE "; npcBox.add("Pathfind flgs", pflags); npcBox.print(); } if(io->ioflags & (IO_FIX | IO_ITEM)) { DebugBox itemBox = DebugBox(Vec2i(500, entityBox.size().y + 5), "Item"); itemBox.add("Durability", io->durability); itemBox.add("Durability max", io->max_durability); itemBox.add("Poisonous", static_cast<long>(io->poisonous)); itemBox.add("Poisonous count", static_cast<long>(io->poisonous_count)); itemBox.print(); } long column2y = 400; for(size_t i = 0; i < MAX_ANIM_LAYERS; i++) { AnimLayer & layer = io->animlayer[i]; DebugBox animLayerBox = DebugBox(Vec2i(500, column2y), str(boost::format("Anim Layer %1%") % i)); animLayerBox.add("ctime", long(layer.ctime.t)); animLayerBox.add("flags", flagNames(AnimUseFlagNames, layer.flags)); animLayerBox.add("currentFrame", layer.currentFrame); if(layer.cur_anim) { animLayerBox.add("cur_anim", layer.cur_anim->path.string()); } else { animLayerBox.add("cur_anim", "none"); } animLayerBox.print(); column2y = animLayerBox.size().y + 5; } } ARX_SCRIPT_Init_Event_Stats(); }
static float ARX_THROWN_ComputeDamages(long thrownum, EntityHandle source, EntityHandle target) { float distance_limit = 1000.f; Entity * io_target = entities[target]; Entity * io_source = entities[source]; SendIOScriptEvent(io_target, SM_AGGRESSION); float distance = fdist(Thrown[thrownum].position, Thrown[thrownum].initial_position); float distance_modifier = 1.f; if(distance < distance_limit * 2.f) { distance_modifier = distance / distance_limit; if(distance_modifier < 0.5f) distance_modifier = 0.5f; } else { distance_modifier = 2.f; } float attack, dmgs, backstab, ac; backstab = 1.f; bool critical = false; if(source == 0) { attack = Thrown[thrownum].damages; if(Random::getf(0.f, 100.f) <= float(player.m_attributeFull.dexterity - 9) * 2.f + float(player.m_skillFull.projectile * 0.2f)) { if(SendIOScriptEvent(io_source, SM_CRITICAL, "bow") != REFUSE) critical = true; } dmgs = attack; if(io_target->_npcdata->npcflags & NPCFLAG_BACKSTAB) { if(Random::getf(0.f, 100.f) <= player.m_skillFull.stealth) { if(SendIOScriptEvent(io_source, SM_BACKSTAB, "bow") != REFUSE) backstab = 1.5f; } } } else { // TODO treat NPC !!! ARX_DEAD_CODE(); attack = 0; dmgs = 0; } float absorb; if(target == 0) { ac = player.m_miscFull.armorClass; absorb = player.m_skillFull.defense * .5f; } else { ac = ARX_INTERACTIVE_GetArmorClass(io_target); absorb = io_target->_npcdata->absorb; } char wmat[64]; std::string _amat = "flesh"; const std::string * amat = &_amat; strcpy(wmat, "dagger"); if(!io_target->armormaterial.empty()) { amat = &io_target->armormaterial; } if(io_target == entities.player()) { if(ValidIONum(player.equiped[EQUIP_SLOT_ARMOR])) { Entity * io = entities[player.equiped[EQUIP_SLOT_ARMOR]]; if(io && !io->armormaterial.empty()) { amat = &io->armormaterial; } } } float power; power = dmgs * ( 1.0f / 20 ); if(power > 1.f) power = 1.f; power = power * 0.15f + 0.85f; ARX_SOUND_PlayCollision(*amat, wmat, power, 1.f, Thrown[thrownum].position, io_source); dmgs *= backstab; dmgs -= dmgs * (absorb * ( 1.0f / 100 )); float chance = 100.f - (ac - attack); float dice = Random::getf(0.f, 100.f); if(dice <= chance) { if(dmgs > 0.f) { if(critical) dmgs *= 1.5f; dmgs *= distance_modifier; return dmgs; } } return 0.f; }
float ARX_EQUIPMENT_ComputeDamages(Entity * io_source, Entity * io_target, float ratioaim, Vec3f * position) { EVENT_SENDER = io_source; SendIOScriptEvent(io_target, SM_AGGRESSION); if(!io_source || !io_target) return 0.f; if(!(io_target->ioflags & IO_NPC)) { if(io_target->ioflags & IO_FIX) { if (io_source == entities.player()) ARX_DAMAGES_DamageFIX(io_target, player.m_miscFull.damages, PlayerEntityHandle, false); else if (io_source->ioflags & IO_NPC) ARX_DAMAGES_DamageFIX(io_target, io_source->_npcdata->damages, io_source->index(), false); else ARX_DAMAGES_DamageFIX(io_target, 1, io_source->index(), false); } return 0.f; } float attack, ac, damages; float backstab = 1.f; std::string _wmat = "bare"; const std::string * wmat = &_wmat; std::string _amat = "flesh"; const std::string * amat = &_amat; bool critical = false; if(io_source == entities.player()) { if(ValidIONum(player.equiped[EQUIP_SLOT_WEAPON])) { Entity * io = entities[player.equiped[EQUIP_SLOT_WEAPON]]; if(io && !io->weaponmaterial.empty()) { wmat = &io->weaponmaterial; } } attack = player.m_miscFull.damages; if(Random::getf(0.f, 100.f) <= player.m_miscFull.criticalHit) { if(SendIOScriptEvent(io_source, SM_CRITICAL) != REFUSE) critical = true; } else critical = false; damages = attack * ratioaim; if(io_target->_npcdata->npcflags & NPCFLAG_BACKSTAB) { if(Random::getf(0.f, 100.f) <= player.m_skillFull.stealth * ( 1.0f / 2 )) { if(SendIOScriptEvent(io_source, SM_BACKSTAB) != REFUSE) backstab = 1.5f; } } } else { if(!(io_source->ioflags & IO_NPC)) // no NPC source... return 0.f; if(!io_source->weaponmaterial.empty()) { wmat = &io_source->weaponmaterial; } if(io_source->_npcdata->weapon) { Entity * iow = io_source->_npcdata->weapon; if(!iow->weaponmaterial.empty()) { wmat = &iow->weaponmaterial; } } attack = io_source->_npcdata->tohit; damages = io_source->_npcdata->damages * ratioaim * Random::getf(0.5f, 1.0f); SpellBase * spell = spells.getSpellOnTarget(io_source->index(), SPELL_CURSE); if(spell) { damages *= (1 - spell->m_level * 0.05f); } if(Random::getf(0.f, 100) <= io_source->_npcdata->critical) { if(SendIOScriptEvent(io_source, SM_CRITICAL) != REFUSE) critical = true; } else critical = false; if(Random::getf(0.f, 100.f) <= (float)io_source->_npcdata->backstab_skill) { if(SendIOScriptEvent(io_source, SM_BACKSTAB) != REFUSE) backstab = 1.5f; } } float absorb; if(io_target == entities.player()) { ac = player.m_miscFull.armorClass; absorb = player.m_skillFull.defense * ( 1.0f / 2 ); } else { ac = ARX_INTERACTIVE_GetArmorClass(io_target); absorb = io_target->_npcdata->absorb; SpellBase * spell = spells.getSpellOnTarget(io_target->index(), SPELL_CURSE); if(spell) { float modif = (1 - spell->m_level * 0.05f); ac *= modif; absorb *= modif; } } if(!io_target->armormaterial.empty()) { amat = &io_target->armormaterial; } if(io_target == entities.player()) { if(ValidIONum(player.equiped[EQUIP_SLOT_ARMOR])) { Entity * io = entities[player.equiped[EQUIP_SLOT_ARMOR]]; if(io && !io->armormaterial.empty()) { amat = &io->armormaterial; } } } float dmgs = damages * backstab; dmgs -= dmgs * absorb * 0.01f; Vec3f pos = io_target->pos; float power = std::min(1.f, dmgs * 0.05f) * 0.1f + 0.9f; ARX_SOUND_PlayCollision(*amat, *wmat, power, 1.f, pos, io_source); float chance = 100.f - (ac - attack); if(Random::getf(0.f, 100.f) > chance) { return 0.f; } ARX_SOUND_PlayCollision("flesh", *wmat, power, 1.f, pos, io_source); if(dmgs > 0.f) { if(critical) { dmgs *= 1.5f; } if(io_target == entities.player()) { // TODO should this be player.pos - player.baseOffset() = player.basePosition()? Vec3f ppos = io_source->pos - (player.pos + player.baseOffset()); ppos = glm::normalize(ppos); // Push the player PUSH_PLAYER_FORCE += ppos * -dmgs * Vec3f(1.0f / 11, 1.0f / 30, 1.0f / 11); ARX_DAMAGES_DamagePlayer(dmgs, 0, io_source->index()); ARX_DAMAGES_DamagePlayerEquipment(dmgs); } else { Vec3f ppos = io_source->pos - io_target->pos; ppos = glm::normalize(ppos); // Push the NPC io_target->forcedmove += ppos * -dmgs; Vec3f * pos = position ? position : &io_target->pos; ARX_DAMAGES_DamageNPC(io_target, dmgs, io_source->index(), false, pos); } } return dmgs; }
void ShowInfoText() { DebugBox frameInfo = DebugBox(Vec2i(10, 10), "FrameInfo"); frameInfo.add("Prims", EERIEDrawnPolys); frameInfo.add("Particles", getParticleCount()); frameInfo.add("Polybooms", long(polyboom.size())); frameInfo.add("TIME", static_cast<long>(arxtime.now_ul() / 1000)); frameInfo.print(); DebugBox playerBox = DebugBox(Vec2i(10, frameInfo.size().y + 5), "Player"); playerBox.add("Position", player.pos); playerBox.add("AnchorPos", player.pos - Mscenepos); playerBox.add("Rotation", player.angle); playerBox.add("Velocity", player.physics.velocity); EERIEPOLY * ep = CheckInPoly(player.pos); float truePolyY = -666.66f; if(ep) { float tempY = 0.f; if(GetTruePolyY(ep, player.pos, &tempY)) { truePolyY = tempY; } } ep = CheckInPoly(player.pos + Vec3f(0.f, -10.f, 0.f)); float slope = 0.f; if(ep) slope = ep->norm.y; long zap = IsAnyPolyThere(player.pos.x,player.pos.z); playerBox.add("Ground Slope", slope); playerBox.add("Ground truePolyY", truePolyY); playerBox.add("Ground POLY", zap); playerBox.add("Color", CURRENT_PLAYER_COLOR); playerBox.add("Stealth", GetPlayerStealth()); playerBox.add("Jump", player.jumplastposition); playerBox.add("OFFGRND", (!player.onfirmground ? "OFFGRND" : "")); playerBox.add("Life", player.lifePool); playerBox.add("Mana", player.manaPool); playerBox.add("Poisoned", player.poison); playerBox.add("Hunger", player.hunger); playerBox.add("Magic", static_cast<long>(player.doingmagic)); playerBox.print(); DebugBox miscBox = DebugBox(Vec2i(10, playerBox.size().y + 5), "Misc"); miscBox.add("Arx version", arx_version); miscBox.add("Level", LastLoadedScene.string().c_str()); miscBox.add("Spell failed seq", LAST_FAILED_SEQUENCE.c_str()); miscBox.add("Camera focal", ACTIVECAM->focal); miscBox.add("Cinema", CINEMA_DECAL); miscBox.add("Mouse", Vec2i(DANAEMouse)); miscBox.add("Pathfind queue", EERIE_PATHFINDER_Get_Queued_Number()); miscBox.add("Pathfind status", (PATHFINDER_WORKING ? "Working" : "Idled")); miscBox.print(); { struct ScriptDebugReport { std::string entityName; long events; long sends; ScriptDebugReport() : entityName("") , events(0) , sends(0) {} }; ScriptDebugReport maxEvents; Entity * io = ARX_SCRIPT_Get_IO_Max_Events(); if(io) { maxEvents.entityName = io->idString(); maxEvents.events = io->stat_count; } ScriptDebugReport maxSender; io = ARX_SCRIPT_Get_IO_Max_Events_Sent(); if(io) { maxSender.entityName = io->idString(); maxSender.sends = io->stat_sent; } DebugBox scriptBox = DebugBox(Vec2i(10, miscBox.size().y + 5), "Script"); scriptBox.add("Events", ScriptEvent::totalCount); scriptBox.add("Timers", ARX_SCRIPT_CountTimers()); scriptBox.add("Max events", maxEvents.entityName); scriptBox.add("Max events#", maxEvents.events); scriptBox.add("Max sender", maxSender.entityName); scriptBox.add("Max sender#", maxSender.sends); scriptBox.print(); } if(ValidIONum(LastSelectedIONum)) { Entity * io = entities[LastSelectedIONum]; if(io) { DebugBox entityBox = DebugBox(Vec2i(500, 10), "Entity " + io->idString()); entityBox.add("Pos", io->pos); entityBox.add("Angle", io->angle); entityBox.add("Room", static_cast<long>(io->room)); entityBox.add("Move", io->move); entityBox.add("Flags", flagNames(EntityFlagNames, io->ioflags)); entityBox.add("Show", entityVisilibityToString(io->show)); entityBox.print(); if(io->ioflags & IO_NPC) { IO_NPCDATA * npcData = io->_npcdata; DebugBox npcBox = DebugBox(Vec2i(500, entityBox.size().y + 5), "NPC"); npcBox.add("Life", npcData->lifePool); npcBox.add("Mana", npcData->manaPool); npcBox.add("Poisoned", npcData->poisonned); npcBox.add("ArmorClass", ARX_INTERACTIVE_GetArmorClass(io)); npcBox.add("Absorb", npcData->absorb); npcBox.add("Moveproblem", npcData->moveproblem); npcBox.add("Pathfind listpos", static_cast<long>(npcData->pathfind.listpos)); npcBox.add("Pathfind listnb", npcData->pathfind.listnb); npcBox.add("Pathfind targ", npcData->pathfind.truetarget.handleData()); npcBox.add("Behavior", flagNames(BehaviourFlagNames, npcData->behavior)); // TODO should those really be flags ? PathfindFlags pflag = io->_npcdata->pathfind.flags; std::string pflags; if(pflag & PATHFIND_ALWAYS) pflags += "ALWAYS "; if(pflag & PATHFIND_ONCE) pflags += "ONCE "; if(pflag & PATHFIND_NO_UPDATE) pflags += "NO_UPDATE "; npcBox.add("Pathfind flgs", pflags); npcBox.print(); } if(io->ioflags & (IO_FIX | IO_ITEM)) { DebugBox itemBox = DebugBox(Vec2i(500, entityBox.size().y + 5), "Item"); itemBox.add("Durability", io->durability); itemBox.add("Durability max", io->max_durability); itemBox.add("Poisonous", static_cast<long>(io->poisonous)); itemBox.add("Poisonous count", static_cast<long>(io->poisonous_count)); itemBox.print(); } } } ARX_SCRIPT_Init_Event_Stats(); }