Пример #1
0
void CoreScript::AddFlag(const Vector2I& _pos)
{
	Vector2I pos = _pos;
	// A little UI fixup: set the flag to a porch
	// if we click on the switch.
	Chit* building = Context()->chitBag->QueryBuilding(IString(), pos, 0);
	if (building && (building->GetItem()->IName() == ISC::switchOn || building->GetItem()->IName() == ISC::switchOff)) {
		MapSpatialComponent* msc = GET_SUB_COMPONENT(building, SpatialComponent, MapSpatialComponent);
		if (msc) {
			pos = msc->PorchPos().min;
		}
	}

	Flag f = { pos, 0 };
	if (flags.Find(f) < 0) {
		Chit* chit = Context()->chitBag->NewChit();
		RenderComponent* rc = new RenderComponent("flag");
		chit->Add(rc);
		ProcRenderInfo info;
		AssignProcedural(ISC::team,
							false,
							ParentChit()->GetItem()->ID(),
							ParentChit()->Team(),
							false,
							0,
							0,
							&info);
		rc->SetProcedural(0, info);
		chit->SetPosition(ToWorld3F(pos));
		f.chitID = chit->ID();
		flags.Push(f);
	}
}
Пример #2
0
Chit* LumosChitBag::NewMonsterChit(const Vector3F& pos, const char* name, int team)
{
	const ChitContext* context = Context();
	Chit* chit = NewChit();

	AddItem( name, chit, context->engine, team, 0 );

	chit->Add( new RenderComponent( chit->GetItem()->ResourceName() ));
	chit->Add( new PathMoveComponent());
	chit->Add( new AIComponent());

	chit->SetPosition( pos );

	chit->Add( new HealthComponent());

	IString mob = chit->GetItem()->keyValues.GetIString(ISC::mob);
	if (ReserveBank::Instance()) {
		ReserveBank::Instance()->WithdrawMonster(chit->GetWallet(), mob == ISC::greater);
	}
	if (mob == ISC::greater) {
		// Mark this item as important with a destroyMsg:
		chit->GetItem()->SetSignificant(GetNewsHistory(), ToWorld2F(pos), NewsEvent::GREATER_MOB_CREATED, NewsEvent::GREATER_MOB_KILLED, 0);
	}
	chit->GetItem()->GetTraitsMutable()->Roll(chit->ID());
	chit->GetItem()->FullHeal();

	if (XenoAudio::Instance()) {
		XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos);
	}
	return chit;
}
Пример #3
0
void LumosChitBag::HandleBolt( const Bolt& bolt, const ModelVoxel& mv )
{
	const ChitContext* context = Context();
	Chit* chitShooter = GetChit( bolt.chitID );	// may be null
	int shooterTeam = -1;
	if ( chitShooter && chitShooter->GetItemComponent() ) {
		shooterTeam = chitShooter->GetItemComponent()->GetItem()->Team();
	}
	int explosive = bolt.effect & GameItem::EFFECT_EXPLOSIVE;
 
	if ( !explosive ) {
		if ( mv.Hit() ) {
			Chit* chitHit = mv.ModelHit() ? mv.model->userData : 0;
			DamageDesc dd( bolt.damage, bolt.effect );

			if ( chitHit ) {
				GLASSERT( GetChit( chitHit->ID() ) == chitHit );
				if ( chitHit->GetItemComponent() &&
					 chitHit->GetItemComponent()->GetItem()->Team() == shooterTeam ) 
				{
					// do nothing. don't shoot own team.
				}
				else {
		
					ChitDamageInfo info( dd );
					info.originID = bolt.chitID;
					info.awardXP  = true;
					info.isMelee  = false;
					info.isExplosion = false;
					info.originOfImpact = mv.at;

					ChitMsg msg( ChitMsg::CHIT_DAMAGE, 0, &info );
					chitHit->SendMessage( msg, 0 );
				}
			}
			else if ( mv.VoxelHit() ) {
				context->worldMap->VoxelHit( mv.voxel, dd );
			}
		}
	}
	else {
		// How it used to work. Now only uses radius:
			// Here don't worry about the chit hit. Just ray cast to see
			// who is in range of the explosion and takes damage.
		
			// Back up the origin of the bolt just a bit, so it doesn't keep
			// intersecting the model it hit. Then do ray checks around to 
			// see what gets hit by the explosion.

		float rewind = Min( 0.1f, 0.5f*bolt.len );
		GLASSERT( Equal( bolt.dir.Length(), 1.f, 0.001f ));
		Vector3F origin = mv.at - bolt.dir * rewind;

		DamageDesc dd( bolt.damage, bolt.effect );
		BattleMechanics::GenerateExplosion( dd, origin, bolt.chitID, context->engine, this, context->worldMap );
	}
}
Пример #4
0
Chit* LumosChitBag::NewDenizen( const grinliz::Vector2I& pos, int team )
{
	const ChitContext* context = Context();
	IString itemName;

	switch (Team::Group(team)) {
		case TEAM_HOUSE:	itemName = (random.Bit()) ? ISC::humanFemale : ISC::humanMale;	break;
		case TEAM_GOB:		itemName = ISC::gobman;											break;
		case TEAM_KAMAKIRI:	itemName = ISC::kamakiri;										break;
		default: GLASSERT(0); break;
	}

	Chit* chit = NewChit();
	const GameItem& root = ItemDefDB::Instance()->Get(itemName.safe_str());

	chit->Add( new RenderComponent(root.ResourceName()));
	chit->Add( new PathMoveComponent());

	const char* altName = 0;
	if (Team::Group(team) == TEAM_HOUSE) {
		altName = "human";
	}
	AddItem(root.Name(), chit, context->engine, team, 0, 0, altName);

	ReserveBank::Instance()->WithdrawDenizen(chit->GetWallet());
	chit->GetItem()->GetTraitsMutable()->Roll( random.Rand() );
	chit->GetItem()->GetPersonalityMutable()->Roll( random.Rand(), &chit->GetItem()->Traits() );
	chit->GetItem()->FullHeal();

	IString nameGen = chit->GetItem()->keyValues.GetIString( "nameGen" );
	if ( !nameGen.empty() ) {
		LumosChitBag* chitBag = chit->Context()->chitBag;
		if ( chitBag ) {
			chit->GetItem()->SetProperName(chitBag->NameGen(nameGen.c_str(), chit->ID()));
		}
	}

	AIComponent* ai = new AIComponent();
	chit->Add( ai );

	chit->Add( new HealthComponent());
	chit->SetPosition( (float)pos.x+0.5f, 0, (float)pos.y+0.5f );

	chit->GetItem()->SetSignificant(GetNewsHistory(), ToWorld2F(pos), NewsEvent::DENIZEN_CREATED, NewsEvent::DENIZEN_KILLED, 0);

	if (XenoAudio::Instance()) {
		Vector3F pos3 = ToWorld3F(pos);
		XenoAudio::Instance()->PlayVariation(ISC::rezWAV, random.Rand(), &pos3);
	}

	return chit;
}
Пример #5
0
void CoreScript::AssignToSquads()
{
	// First, how many do we actually have?
	// Filter out everyone that has gone away.
	for (int i = 0; i < MAX_SQUADS; ++i) {
		//GL_ARRAY_FILTER(squads[i], (this->IsCitizen(ele)));
		squads[i].Filter(this, [](CoreScript* cs, int id) {
			return cs->IsCitizen(id);
		});
		if (squads[i].Empty()) {
			// Flush out dead squads so they don't have 
			// control flags laying around.
			waypoints[i].Clear();
		}
	}
	int nSquaddies = 0;
	for (int i = 0; i < MAX_SQUADS; ++i) {
		nSquaddies += squads[i].Size();
	}

	CChitArray recruits;
	int nCitizens = Citizens(&recruits);
	int nExpected = nCitizens - CITIZEN_BASE;
	if (nSquaddies >= nExpected) return;

	struct FilterData {
		CoreScript* cs;
		Chit* avatar;;
	};
	FilterData fd = { this, Context()->chitBag->GetAvatar() };

	// Filter to: not in squad AND not player controlled
	recruits.Filter(fd, [](const FilterData& ffd, Chit* chit) {
		return (ffd.cs->SquadID(chit->ID()) < 0 && chit != ffd.avatar);
	});

	// Sort the best recruits to the end.
	// FIXME: better if there was a (working) power approximation
	recruits.Sort([](Chit* a, Chit* b) {
		const GameItem* itemA = a->GetItem();
		const GameItem* itemB = b->GetItem();
		int scoreA = itemA->Traits().Level() * (itemA->GetPersonality().Fighting() == Personality::LIKES ? 2 : 1);
		int scoreB = itemB->Traits().Level() * (itemB->GetPersonality().Fighting() == Personality::LIKES ? 2 : 1);
		
		// Reverse order. Best at end.
		return scoreA > scoreB;
	});

	for (int n = nExpected - nSquaddies; n > 0; --n) {
		for (int i = 0; i < MAX_SQUADS; ++i) {
			if (   (squads[i].Size() < SQUAD_SIZE)
				&& SquadAtRest(i))
			{
				Chit* chit = recruits.Pop();
				squads[i].Push(chit->ID());
				++nSquaddies;
				break;
			}
		}
	}
}